searchFirst($query); } public function searchByBibliographic($title, $author, $year = '') { $title = trim((string)$title); if ($title === '') { return null; } $parts = ['TITLE:"' . str_replace('"', '', $title) . '"']; $author = trim((string)$author); if ($author !== '') { $firstAuthor = preg_split('/[,;]/', $author); $firstAuthor = trim((string)($firstAuthor[0] ?? '')); if ($firstAuthor !== '') { $parts[] = 'AUTH:"' . str_replace('"', '', $firstAuthor) . '"'; } } $year = trim((string)$year); if ($year !== '' && preg_match('/^(19|20)\d{2}$/', $year)) { $parts[] = 'PUB_YEAR:' . $year; } return $this->searchFirst(implode(' AND ', $parts)); } public function fetchFullTextByPmcid($pmcid) { $pmcid = strtoupper(trim((string)$pmcid)); if ($pmcid === '') { return ''; } if (strpos($pmcid, 'PMC') !== 0) { $pmcid = 'PMC' . preg_replace('/\D/', '', $pmcid); } $url = $this->base . '/' . rawurlencode($pmcid) . '/fullTextXML'; $xml = $this->httpGet($url); if ($xml === '') { return ''; } return $this->xmlToPlainText($xml); } private function searchFirst($query) { $url = $this->base . '/search?' . http_build_query([ 'query' => $query, 'format' => 'json', 'pageSize' => 1, ]); $raw = $this->httpGet($url); if ($raw === '') { return null; } $json = json_decode($raw, true); $list = $json['resultList']['result'] ?? []; if (empty($list[0]) || !is_array($list[0])) { return null; } $row = $list[0]; return [ 'title' => trim((string)($row['title'] ?? '')), 'abstract' => trim((string)($row['abstractText'] ?? '')), 'doi' => trim((string)($row['doi'] ?? '')), 'pmid' => trim((string)($row['pmid'] ?? '')), 'pmcid' => trim((string)($row['pmcid'] ?? '')), 'journal' => trim((string)($row['journalTitle'] ?? '')), 'year' => trim((string)($row['pubYear'] ?? '')), 'source' => 'europe_pmc', ]; } private function xmlToPlainText($xml) { $xml = trim((string)$xml); if ($xml === '') { return ''; } libxml_use_internal_errors(true); $doc = new \DOMDocument(); if (!$doc->loadXML($xml)) { return trim(strip_tags($xml)); } return trim(preg_replace('/\s+/u', ' ', $doc->textContent)); } private function httpGet($url) { $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-EuropePMC/1.0'], ]); $res = curl_exec($ch); curl_close($ch); return is_string($res) ? $res : ''; } }