Files
tougao/application/common/UnpaywallService.php
wyn 8785610e6d 参考文献作者堆叠
参考文献相关性检测
作者ai写作辅助检测工作
2026-07-15 10:49:05 +08:00

77 lines
1.9 KiB
PHP

<?php
namespace app\common;
use think\Env;
/**
* Unpaywall OA PDF 定位
* @see https://unpaywall.org/products/api
*/
class UnpaywallService
{
private $email;
private $timeout = 20;
public function __construct()
{
$this->email = trim((string)Env::get('unpaywall_email', Env::get('pubmed_email', '')));
}
/**
* @return string PDF 直链,找不到返回空
*/
public function findOaPdfUrl($doi)
{
$doi = trim((string)$doi);
if ($doi === '' || $this->email === '') {
return '';
}
$url = 'https://api.unpaywall.org/v2/' . rawurlencode($doi) . '?' . http_build_query([
'email' => $this->email,
]);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HTTPHEADER => ['User-Agent: TMRjournals-Unpaywall/1.0'],
]);
$raw = curl_exec($ch);
curl_close($ch);
if (!is_string($raw) || $raw === '') {
return '';
}
$json = json_decode($raw, true);
if (!is_array($json)) {
return '';
}
$best = $json['best_oa_location'] ?? [];
if (!is_array($best)) {
return '';
}
foreach (['url_for_pdf', 'url'] as $key) {
$candidate = trim((string)($best[$key] ?? ''));
if ($candidate !== '' && $this->looksLikePdfUrl($candidate)) {
return $candidate;
}
}
return '';
}
private function looksLikePdfUrl($url)
{
if (stripos($url, '.pdf') !== false) {
return true;
}
return (bool)preg_match('#/(pdf|download|content/pdf)#i', $url);
}
}