cache = JCache :: getInstance(); $this -> http = new JHttp(); } private function _parseMultipleJsonDOIs($message){ $publications=array(); if(isset($message -> items)){ foreach ($message -> items as $item) { $publication= $this ->_parseJsonDOI($item); if($publication!==null){ $publications[]=$publication; } } } return $publications; } private function _parseJsonDOI($message) { $publication = new JObject(); $publication -> id = isset($message -> DOI)?$message -> DOI:NULL; $publication -> source = self :: DOI; $publication -> url = isset($message -> URL)?$message -> URL:NULL; $publication -> accessMode = NULL; $publication -> datasources = array(); $publication -> title = (isset($message -> title) && isset($message -> title[0]))?$message -> title[0]:NULL; $publication -> authors = array(); if(isset($message -> author)){ foreach ($message -> author as $author_item) { $author = new JObject(); $author -> id = NULL; $author -> lastName = isset($author_item-> family) ? trim($author_item -> family):NULL; $author -> firstName = isset($author_item -> given) ? trim($author_item -> given):NULL; $author -> fullName = NULL; if (($author -> id != NULL) || ($author -> lastName != NULL) || ($author-> firstName != NULL) || ($author -> fullName != NULL)) $publication -> authors[] = $author; } } $publication -> publisher =isset($message -> publisher)?$message -> publisher:NULL; $publication -> year = (isset($message -> issued )&&isset($message -> issued -> date_parts[0]))? ((isset($message -> issued -> date_parts[0][0]))?$message -> issued -> date_parts[0][0]:NULL):NULL; $publication -> language = NULL; $publication -> projects = array(); $publication -> embargoEndDate = NULL; $publication -> description = NULL; if (($publication -> id != NULL)&&( ($publication -> url != NULL) || ($publication -> title != NULL) || ($publication -> authors != NULL) || ($publication -> year != NULL))) { return $publication; } return NULL; } // Search for a dataset DOI using caching if enabled. // $doi the dataset DOI to search for // return a result (object) containing datasets and total private function _searchDataCiteWithDoi($doi) { try { $request = self :: DATACITE_URL . urlencode(trim($doi)); JLog :: add('Requesting ' . $request, JLog :: INFO, self :: LOG); $time = microtime(TRUE); $response = $this -> http -> get($request); JLog :: add('Received response in ' . (microtime(TRUE) - $time) . ' s', JLog :: INFO, self :: LOG); if ($response== NULL) throw new Exception('no HTTP response'); /*if ($response -> code == self :: HTTP_NOT_FOUND) { // no dataset found; just return empty result $result = new JObject(); $result -> datasets = array(); $result -> totalDatasets = 0; JLog :: add('Retrieved 0 DataCite records in ' . (microtime(TRUE) - $time) . ' s', JLog :: INFO, self :: LOG); return $result; }*/ if ($response -> code != self :: HTTP_OK) throw new Exception('HTTP response code ' . $response -> code); $document = new DOMDocument(); $document -> recover = TRUE; if ($document -> loadXML(trim($response -> body)) == FALSE) throw new Exception('invalid XML response'); $xpath = new DOMXPath($document); if ((($descriptionNodes = $xpath -> query('/rdf:RDF/rdf:Description')) == FALSE) || (($descriptionNode = $descriptionNodes -> item(0)) == NULL)) throw new Exception('error parsing DataCite record'); if (($idNodes = $xpath -> query('./j.0:identifier', $descriptionNode)) == FALSE) throw new Exception('error parsing DataCite record'); if (($titleNodes = $xpath -> query('./j.0:title', $descriptionNode)) == FALSE) throw new Exception('error parsing DataCite record'); if (($authorNodes = $xpath -> query('./j.0:creator', $descriptionNode)) == FALSE) throw new Exception('error parsing DataCite record'); if (($yearNodes = $xpath -> query('./j.0:date', $descriptionNode)) == FALSE) throw new Exception('error parsing DataCite record'); if (($publisherNodes = $xpath -> query('./j.0:publisher', $descriptionNode)) == FALSE) throw new Exception('error parsing DataCite record'); $dataset = new JObject(); $dataset -> id = (($idNode = $idNodes -> item(0)) == NULL) ? NULL : trim($idNode -> nodeValue); $dataset -> source = self :: DATACITE; $dataset -> url = self :: DOI_URL . urlencode(trim($doi)); $dataset -> accessMode = NULL; $dataset -> datasources = array(); $dataset -> title = (($titleNode = $titleNodes -> item(0)) == NULL) ? NULL : trim($titleNode -> nodeValue); $dataset -> authors = array(); $dataset -> publisher = (($publisherNode = $publisherNodes -> item(0)) == NULL) ? NULL : trim($publisherNode -> nodeValue); $dataset -> year = (($yearNode = $yearNodes -> item(0)) == NULL) ? NULL : intval(trim($yearNode -> nodeValue)); $dataset -> language = NULL; $dataset -> projects = array(); $dataset -> embargoEndDate = NULL; $dataset -> description = NULL; foreach ($authorNodes as $authorNode) { $author = new JObject(); $author -> id = NULL; $author -> lastName = NULL; $author -> firstName = NULL; $author -> fullName = trim($authorNode -> nodeValue); if ($author -> fullName != NULL) $dataset -> authors[] = $author; } /*$result = new JObject(); $result -> datasets = array(); $result -> totalDatasets = 0; if (($dataset -> id != NULL) || ($dataset -> url != NULL) || ($dataset -> title != NULL) || ($dataset -> authors != NULL) || ($dataset -> year != NULL)) { $result -> datasets[] = $dataset; $result -> totalDatasets = 1; }*/ JLog :: add('Retrieved DataCite record in ' . (microtime(TRUE) - $time) . ' s', JLog :: INFO, self :: LOG); return $dataset; } catch (Exception $e) { JLog :: add('Error performing DataCite search (doi: ' . $doi . '): ' . $e -> getMessage(), JLog :: ERROR, self :: LOG); return NULL; } } private function _searchDataCite($doi, $page, $size) { $result = new JObject(); $result->datasets = array(); $result->totalPublications = 0; $result->totalDatasets = 0; try { $dois = explode(" ", preg_replace('/\s+/', ' ',$doi)); $unique_dois =array_slice( array_unique($dois),0,10); $pattern1 = '#\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])\S)+)\b#'; $pattern2 = '#\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])[[:graph:]])+)\b#'; if (preg_match($pattern1, $unique_dois[0]) || preg_match($pattern2, $unique_dois[0])) { if(count($dois)>10){ $result = new JObject(); $result->datasets = array(); $result->totalPublications = 0; $result->totalDatasets = '-'; $result->maxDoisExceeded = true; return $result; } JLog :: add('It;s a dataset DOI!!!!!!!!! ' . $dois[0], JLog :: INFO, self :: LOG); JLog :: add('Searching for DOIs in Datacite', JLog :: INFO, self :: LOG); foreach ($unique_dois as $doi_) { JLog :: add('DOI::: ' . $doi_, JLog :: INFO, self :: LOG); $dataset = $this->_searchDataCiteWithDoi($doi_); if ($dataset != null) { $result->datasets[] = $dataset; } } }else{ JLog :: add('It;sNOOOOOOOT a dataset DOI!!!!!!!!! ' . $dois[0], JLog :: INFO, self :: LOG); } $result->totalDatasets = count($result->datasets); if($result->totalDatasets!==0){ return $result; } $request = self :: DATACITE_URL_KEYWORD. urlencode(trim($doi)).self :: DATACITE_URL_KEYWORD_REST."&rows=".$size."&start=".($page-1)*$size; JLog :: add('Requesting ' . $request, JLog :: INFO, self :: LOG); $time = microtime(TRUE); $response = $this -> http -> get($request); JLog :: add('Received response in ' . (microtime(TRUE) - $time) . ' s', JLog :: INFO, self :: LOG); if ($response== NULL) throw new Exception('no HTTP response'); if ($response -> code == self :: HTTP_NOT_FOUND) { // no dataset found; just return empty result $result = new JObject(); //$result -> datasets = array(); $result -> totalDatasets = 0; $result -> totalPublications = 0; JLog :: add('Retrieved 0 DataCite records in ' . (microtime(TRUE) - $time) . ' s', JLog :: INFO, self :: LOG); return $result; } if ($response -> code != self :: HTTP_OK) throw new Exception('HTTP response code ' . $response -> code); $document = new DOMDocument(); $document -> recover = TRUE; if ($document -> loadXML(trim($response -> body)) == FALSE) throw new Exception('invalid XML response'); $xpath = new DOMXPath($document); if ((($numFoundNodes = $xpath -> query('/response/result[@name = "response"]/@numFound')) == FALSE) || (($numFoundNode = $numFoundNodes -> item(0)) == NULL)) throw new Exception('error parsing DataCite record'); $numFound=((($numFoundNode)) == NULL) ? NULL : trim($numFoundNode -> nodeValue); if ((($resultNodes = $xpath -> query('/response/result/doc')) == FALSE) || (($resultNode = $resultNodes -> item(0)) == NULL)) throw new Exception('error parsing DataCite record'); foreach ($resultNodes as $resultNode) { if (($idNodes = $xpath -> query('./str[@name = "doi"]/text()', $resultNode)) == FALSE) throw new Exception('error parsing DataCite record'); if (($titleNodes = $xpath -> query('./arr[@name="title"]/str/text()', $resultNode)) == FALSE) throw new Exception('error parsing DataCite record'); if (($authorNodes = $xpath -> query('./arr[@name = "creator"]/str/text()', $resultNode)) == FALSE) throw new Exception('error parsing DataCite record'); if (($publisherNodes = $xpath -> query('./str[@name = "publisher"]/text()', $resultNode)) == FALSE) throw new Exception('error parsing DataCite record'); if (($yearNodes = $xpath -> query('./date[@name = "created"]/text()', $resultNode)) == FALSE) throw new Exception('error parsing DataCite record'); $dataset = new JObject(); $dataset -> id = (($idNode = $idNodes -> item(0)) == NULL) ? NULL : trim($idNode -> nodeValue); $dataset -> source = self :: DATACITE; $dataset -> url = self :: DOI_URL . urlencode(trim($dataset -> id)); $dataset -> accessMode = NULL; $dataset -> datasources = array(); $dataset -> title = (($titleNode = $titleNodes -> item(0)) == NULL) ? NULL : trim($titleNode -> nodeValue); $dataset -> authors = array(); $dataset -> publisher = (($publisherNode = $publisherNodes -> item(0)) == NULL) ? NULL : trim($publisherNode -> nodeValue); $dataset -> year = (($yearNode = $yearNodes -> item(0)) == NULL) ? NULL : substr(trim($yearNode -> nodeValue),0,4); $dataset -> language = NULL; $dataset -> projects = array(); $dataset -> embargoEndDate = NULL; $dataset -> description = NULL; foreach ($authorNodes as $authorNode) { $authorName= $authorNode -> nodeValue; $author = new JObject(); $author -> id = NULL; $author -> lastName = NULL; $author -> firstName = NULL; $author -> fullName = trim($authorName ); if ($author -> fullName != NULL) $dataset -> authors[] = $author; } if (($dataset -> id != NULL) || ($dataset -> url != NULL) || ($dataset -> title != NULL) || ($dataset -> authors != NULL) || ($dataset -> year != NULL)) { $result -> datasets[] = $dataset; } } // $result -> totalDatasets =$numFound ; /* if(isset($size)&&isset($page)){ $result -> datasets = array_slice($result -> datasets, ($page - 1) * $size, $size); }*/ JLog :: add('Retrieved DataCite '.count($result -> datasets).' records in ' . (microtime(TRUE) - $time) . ' s', JLog :: INFO, self :: LOG); $result -> totalPublications = 0; return $result; } catch (Exception $e) { JLog :: add('Error performing DataCite search (doi: ' . $doi . '): ' . $e -> getMessage(), JLog :: ERROR, self :: LOG); $result = new JObject(); //$result -> datasets = array(); $result -> totalPublications = 0; $result -> totalDatasets = 0; return $result; } } // Parse a journal out of a DOI record. // $doi the DOI of the record // $xpath the DOMXPath to parse // $journalNode the journal node to start from // return a result (object) containing publications and total private function parseJournal($doi, $xpath, $journalNode) { if (($resourceNodes = $xpath -> query('./journal_article/doi_data/resource', $journalNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($titleNodes = $xpath -> query('./journal_article/titles/title', $journalNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($contributorNodes = $xpath -> query('./journal_article/contributors', $journalNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($yearNodes = $xpath -> query('./journal_article/publication_date/year', $journalNode)) == FALSE) throw new Exception('error parsing DOI record'); $publication = new JObject(); $publication -> id = $doi; $publication -> source = self :: DOI; $publication -> url = (($resourceNode = $resourceNodes -> item(0)) == NULL) ? NULL : trim($resourceNode -> nodeValue); $publication -> accessMode = NULL; $publication -> datasources = array(); $publication -> title = (($titleNode = $titleNodes -> item(0)) == NULL) ? NULL : trim($titleNode -> nodeValue); $publication -> authors = $this -> parseContributors($xpath, $contributorNodes); $publication -> publisher = NULL; $publication -> year = (($yearNode = $yearNodes -> item(0)) == NULL) ? NULL : intval(trim($yearNode -> nodeValue)); $publication -> language = NULL; $publication -> projects = array(); $publication -> embargoEndDate = NULL; $publication -> description = NULL; $result = new JObject(); $result -> publications = array(); $result -> totalPublications = 0; if (($publication -> id != NULL) || ($publication -> url != NULL) || ($publication -> title != NULL) || ($publication -> authors != NULL) || ($publication -> year != NULL)) { $result -> publications[] = $publication; $result -> totalPublications = 1; } return $result; } // Parse a book out of a DOI record. // $doi the DOI of the record // $xpath the DOMXPath to parse // $bookNode the book node to start from // return a result (object) containing publications and total private function parseBook($doi, $xpath, $bookNode) { if (($bookMetadataNodes = $xpath -> query('./book_metadata', $bookNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($bookSeriesMetadataNodes = $xpath -> query('./book_series_metadata', $bookNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($bookSetMetadataNodes = $xpath -> query('./book_set_metadata', $bookNode)) == FALSE) throw new Exception('error parsing DOI record'); if ((($metadataNode = $bookMetadataNodes -> item(0)) == NULL) && (($metadataNode = $bookSeriesMetadataNodes -> item(0)) == NULL) && (($metadataNode = $bookSetMetadataNodes -> item(0)) == NULL)) throw new Exception('error parsing DOI record'); if (($resourceNodes = $xpath -> query('./doi_data/resource', $metadataNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($titleNodes = $xpath -> query('./titles/title', $metadataNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($contributorNodes = $xpath -> query('./contributors', $metadataNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($yearNodes = $xpath -> query('./publication_date/year', $metadataNode)) == FALSE) throw new Exception('error parsing DOI record'); $publication = new JObject(); $publication -> id = $doi; $publication -> source = self :: DOI; $publication -> url = (($resourceNode = $resourceNodes -> item(0)) == NULL) ? NULL : trim($resourceNode -> nodeValue); $publication -> accessMode = NULL; $publication -> datasources = array(); $publication -> title = (($titleNode = $titleNodes -> item(0)) == NULL) ? NULL : trim($titleNode -> nodeValue); $publication -> authors = $this -> parseContributors($xpath, $contributorNodes); $publication -> publisher = NULL; $publication -> year = (($yearNode = $yearNodes -> item(0)) == NULL) ? NULL : intval(trim($yearNode -> nodeValue)); $publication -> language = NULL; $publication -> projects = array(); $publication -> embargoEndDate = NULL; $publication -> description = NULL; $result = new JObject(); $result -> publications = array(); $result -> totalPublications = 0; if (($publication -> id != NULL) || ($publication -> url != NULL) || ($publication -> title != NULL) || ($publication -> authors != NULL) || ($publication -> year != NULL)) { $result -> publications[] = $publication; $result -> totalPublications = 1; } return $result; } // Parse a Conference out of a DOI record. // $doi the DOI of the record // $xpath the DOMXPath to parse // $conferenceNode the book node to start from // return a result (object) containing publications and total private function parseConference($doi, $xpath, $conferenceNode) { if (($eventMetadata = $xpath -> query('./event_metadata', $conferenceNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($proceedingsMetadata = $xpath -> query('./proceedings_metadata', $conferenceNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($conferencePaperNodes = $xpath -> query('./conference_paper', $conferenceNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($resourceNodes = $xpath -> query('./conference_paper/doi_data/resource', $conferenceNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($titleNodes = $xpath -> query('./conference_paper/titles/title', $conferenceNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($contributorNodes = $xpath -> query('./conference_paper/contributors', $conferenceNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($yearNodes = $xpath -> query('./conference_paper/publication_date/year', $conferenceNode)) == FALSE) throw new Exception('error parsing DOI record'); $publication = new JObject(); $publication -> id = $doi; $publication -> source = self :: DOI; $publication -> url = (($resourceNode = $resourceNodes -> item(0)) == NULL) ? NULL : trim($resourceNode -> nodeValue); $publication -> accessMode = NULL; $publication -> datasources = array(); $publication -> title = (($titleNode = $titleNodes -> item(0)) == NULL) ? NULL : trim($titleNode -> nodeValue); $publication -> authors = $this -> parseContributors($xpath, $contributorNodes); $publication -> publisher = NULL; $publication -> year = (($yearNode = $yearNodes -> item(0)) == NULL) ? NULL : intval(trim($yearNode -> nodeValue)); $publication -> language = NULL; $publication -> projects = array(); $publication -> embargoEndDate = NULL; $publication -> description = NULL; $result = new JObject(); $result -> publications = array(); $result -> totalPublications = 0; if (($publication -> id != NULL) || ($publication -> url != NULL) || ($publication -> title != NULL) || ($publication -> authors != NULL) || ($publication -> year != NULL)) { $result -> publications[] = $publication; $result -> totalPublications = 1; } return $result; } // Parse contributor metadata out of a DOI record. // $doi the DOI of the record // $xpath the DOMXPath to parse // $contributorNodes the contributor nodes to start from // return authors (array) private function parseContributors($xpath, $contributorNodes) { $authors = array(); foreach ($contributorNodes as $contributorNode) { if (($personNameNodes = $xpath -> query('./person_name', $contributorNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($organizationNodes = $xpath -> query('./organization', $contributorNode)) == FALSE) throw new Exception('error parsing DOI record'); foreach ($personNameNodes as $personNameNode) { if (($surnameNodes = $xpath -> query('./surname', $personNameNode)) == FALSE) throw new Exception('error parsing DOI record'); if (($givenNameNodes = $xpath -> query('./given_name', $personNameNode)) == FALSE) throw new Exception('error parsing DOI record'); $author = new JObject(); $author -> id = NULL; $author -> lastName = (($surnameNode = $surnameNodes -> item(0)) == NULL) ? NULL : trim($surnameNode -> nodeValue); $author -> firstName = (($givenNameNode = $givenNameNodes -> item(0)) == NULL) ? NULL : trim($givenNameNode -> nodeValue); $author -> fullName = NULL; if (($author -> id != NULL) || ($author -> lastName != NULL) || ($author -> firstName != NULL) || ($author -> fullName != NULL)) $authors[] = $author; } foreach ($organizationNodes as $organizationNode) { $author = new JObject(); $author -> id = NULL; $author -> lastName = NULL; $author -> firstName = NULL; $author -> fullName = trim($organizationNode -> nodeValue); if (($author -> id != NULL) || ($author -> lastName != NULL) || ($author -> firstName != NULL) || ($author -> fullName != NULL)) $authors[] = $author; } } return $authors; } private function _searchORCID($orcid, $page, $size) { try { $time = microtime(TRUE); $authorRequest = self :: ORCID_URL_PREFIX . trim($orcid) . self :: ORCID_URL_AUTHOR_SUFFIX; JLog :: add('Requesting ' . $authorRequest, JLog :: INFO, self :: LOG); $authorResponse = $this -> http -> get($authorRequest); JLog :: add('Received response in ' . (microtime(TRUE) - $time) . ' s'); $author = new JObject(); $result = new JObject(); if ($authorResponse != NULL&&$authorResponse -> code===self :: HTTP_OK){ /*if ($authorResponse -> code != self :: HTTP_OK) throw new Exception('HTTP response code ' . $authorResponse -> code);*/ $authorDocument = new DOMDocument(); $authorDocument -> recover = TRUE; if ($authorDocument -> loadXML(trim($authorResponse -> body)) == FALSE) throw new Exception('invalid XML response'); $authorXpath = new DOMXPath($authorDocument); if ($authorXpath -> registerNamespace('orcid', $authorDocument -> lookupNamespaceUri(NULL)) == FALSE) throw new Exception('error parsing ORCID bio record'); if (($familyNameNodes = $authorXpath -> query('/orcid:orcid-message/orcid:orcid-profile/orcid:orcid-bio/orcid:personal-details/orcid:family-name')) == FALSE) throw new Exception('error parsing ORCID bio record'); if (($givenNamesNodes = $authorXpath -> query('/orcid:orcid-message/orcid:orcid-profile/orcid:orcid-bio/orcid:personal-details/orcid:given-names')) == FALSE) throw new Exception('error parsing ORCID bio record'); $author -> id = $orcid; $author -> lastName = (($familyNameNode = $familyNameNodes -> item(0)) == NULL) ? NULL : trim($familyNameNode -> nodeValue); $author -> firstName = (($givenNamesNode = $givenNamesNodes ->item(0)) == NULL) ? NULL : trim($givenNamesNode -> nodeValue); $author -> fullName = NULL; }else{ $time = microtime(TRUE); $orcid=str_replace(" ","+",$orcid); //$authorRequest = 'http://pub.orcid.org/search/orcid-bio?q='. trim($orcid); $authorRequest = 'http://pub.orcid.org/search/orcid-bio?defType=edismax&q='. trim($orcid)."&qf=given-name^1.0+family-name^2.0+other-names^1.0+credit-name^1.0&start=0&rows=10"; JLog :: add('Requesting ' . $authorRequest, JLog :: INFO, self :: LOG); $authorResponse = $this -> http -> get($authorRequest); JLog :: add('Received response in ' . (microtime(TRUE) - $time) . ' s'); if ($authorResponse -> code != self :: HTTP_OK) throw new Exception('HTTP response code ' . $authorResponse -> code); $authorDocument = new DOMDocument(); $authorDocument -> recover = TRUE; if ($authorDocument -> loadXML(trim($authorResponse -> body)) == FALSE) throw new Exception('invalid XML response'); $authorXpath = new DOMXPath($authorDocument); if ($authorXpath -> registerNamespace('orcid', $authorDocument -> lookupNamespaceUri(NULL)) == FALSE) throw new Exception('error parsing ORCID bio record'); if (($resultNodes = $authorXpath -> query('/orcid:orcid-message/orcid:orcid-search-results/orcid:orcid-search-result')) == FALSE) throw new Exception('error parsing ORCID bio record'); $authors = array(); foreach ($resultNodes as $resultNode) { if (($familyNameNodes = $authorXpath -> query('./orcid:orcid-profile/orcid:orcid-bio/orcid:personal-details/orcid:family-name',$resultNode)) == FALSE) throw new Exception('error parsing ORCID bio record'); if (($givenNamesNodes = $authorXpath -> query('./orcid:orcid-profile/orcid:orcid-bio/orcid:personal-details/orcid:given-names',$resultNode)) == FALSE) throw new Exception('error parsing ORCID bio record'); if (($idNodes = $authorXpath -> query('./orcid:orcid-profile/orcid:orcid-identifier/orcid:path',$resultNode)) == FALSE) throw new Exception('error parsing ORCID bio record'); if (($relevanceNodes = $authorXpath -> query('./orcid:relevancy-score',$resultNode)) == FALSE) throw new Exception('error parsing ORCID bio record'); $tempAuthor = new JObject(); $tempAuthor -> id = (($idNode = $idNodes -> item(0)) == NULL) ? NULL : trim($idNode -> nodeValue); $tempAuthor -> lastName = (($familyNameNode = $familyNameNodes -> item(0)) == NULL) ? NULL : trim($familyNameNode -> nodeValue); $tempAuthor -> firstName = (($givenNamesNode = $givenNamesNodes ->item(0)) == NULL) ? NULL : trim($givenNamesNode -> nodeValue); $tempAuthor -> fullName = NULL; $relevance = (($relevanceNode = $relevanceNodes ->item(0)) == NULL) ? NULL : trim($relevanceNode -> nodeValue); $authors[] = $tempAuthor; } $author= $authors[0]; $authors = array_slice($authors, 0, 10); $result ->alternativeAuthors =NULL; if($page===1){ $result ->alternativeAuthors =$authors; } } $publicationsRequest = self :: ORCID_URL_PREFIX . trim(((isset($author -> id)&&$author -> id!=null)?$author -> id:$orcid)) . self :: ORCID_URL_PUBLICATIONS_SUFFIX; JLog :: add('Requesting ' . $publicationsRequest, JLog :: INFO, self :: LOG); if (($publicationsResponse = $this -> http -> get($publicationsRequest)) == NULL) throw new Exception('no HTTP response'); if ($publicationsResponse -> code != self :: HTTP_OK) throw new Exception('HTTP response code ' . $publicationsResponse -> code); $publicationsDocument = new DOMDocument(); $publicationsDocument -> recover = TRUE; if ($publicationsDocument -> loadXML(trim($publicationsResponse -> body)) == FALSE) throw new Exception('invalid XML response'); $publicationsXpath = new DOMXPath($publicationsDocument); if ($publicationsXpath -> registerNamespace('orcid', $publicationsDocument -> lookupNamespaceUri(NULL)) == FALSE) throw new Exception('error parsing ORCID works record'); if (($orcidWorkNodes = $publicationsXpath -> query('/orcid:orcid-message/orcid:orcid-profile/orcid:orcid-activities/orcid:orcid-works/orcid:orcid-work')) == FALSE) throw new Exception('error ORCID works record'); $result -> publications = array(); $dois = array(); $i=0; foreach ($orcidWorkNodes as $orcidWorkNode) { $i++; if($i>=($page-1)*$size +1 && $i<=$page*$size ){ if (($putCodeNodes = $publicationsXpath -> query('./@put-code', $orcidWorkNode)) == FALSE) throw new Exception('error ORCID works record'); if (($urlNodes = $publicationsXpath -> query('./orcid:url', $orcidWorkNode)) == FALSE) throw new Exception('error ORCID works record'); if (($titleNodes = $publicationsXpath -> query('./orcid:work-title/orcid:title', $orcidWorkNode)) == FALSE) throw new Exception('error ORCID works record'); if (($yearNodes = $publicationsXpath -> query('./orcid:publication-date/orcid:year', $orcidWorkNode)) == FALSE) throw new Exception('error ORCID works record'); if (($shortDescriptionNodes = $publicationsXpath -> query('./orcid:short-description', $orcidWorkNode)) == FALSE) throw new Exception('error ORCID works record'); if (($doiNodes = $publicationsXpath -> query('./orcid:work-external-identifiers/orcid:work-external-identifier[orcid:work-external-identifier-type = "doi"]/orcid:work-external-identifier-id', $orcidWorkNode)) == FALSE) throw new Exception('error ORCID works record'); $publication = new JObject(); $publication -> id = (($putCodeNode = $putCodeNodes -> item(0)) == NULL) ? NULL : ($author -> id . '-' . trim($putCodeNode -> nodeValue)); $publication -> source = self :: ORCID; $publication -> url = (($urlNode = $urlNodes -> item(0)) == NULL) ? NULL : trim($urlNode -> nodeValue); $publication -> accessMode = NULL; $publication -> datasources = array(); $publication -> title = (($titleNode = $titleNodes -> item(0)) == NULL) ? NULL : trim($titleNode -> nodeValue); $publication -> authors = array(); $publication -> publisher = NULL; $publication -> year = (($yearNode = $yearNodes -> item(0)) == NULL) ? NULL : intval(trim($yearNode -> nodeValue)); $publication -> language = NULL; $publication -> projects = array(); $publication -> embargoEndDate = NULL; $publication -> description = (($shortDescriptionNode = $shortDescriptionNodes -> item(0)) == NULL) ? NULL : trim($shortDescriptionNode -> nodeValue); if (($author -> lastName != NULL) || ($author -> firstName != NULL)) $publication -> authors[] = $author; if ((($doiNode = $doiNodes -> item(0)) != NULL) && (($doiResult = $this -> searchSingleDOI(trim($doiNode -> nodeValue))) != NULL)) { // resolve via DOI if ($publication -> url == NULL) // set URL if missing $publication -> url = $doiResult -> url; if ($publication -> title == NULL) // set title if missing $publication -> title = $doiResult -> title; foreach ($doiResult -> authors as $doiAuthor) { // merge authors if ((count($publication -> authors) == 0) || ($doiAuthor -> id != $publication -> authors[0] -> id) || ($doiAuthor -> lastName != $publication -> authors[0] -> lastName) || ($doiAuthor -> firstName != $publication -> authors[0] -> firstName) || ($doiAuthor -> fullName != $publication -> authors[0] -> fullName)) $publication -> authors[] = $doiAuthor; } if ($publication -> year == NULL) // set year if missing $publication -> year = $doiResult -> year; } if (($publication -> id != NULL) || ($publication -> title != NULL) || ($publication -> authors != NULL) || ($publication -> year != NULL) || ($publication -> description != NULL)){ if ((($doiNode = $doiNodes -> item(0)) != NULL)) { // resolve via DOI $doi=trim($doiNode -> nodeValue); if((strpos($doi,"DOI: ") !== false)){ $doi=explode("DOI: ", $doi)[1]; } $dois[$publication -> id]=$doi; } $result -> publications[$publication -> id] = $publication; } } } // request to crossref via DOI $resultsFromDois=$this->_searchMultipleDOIs($dois); foreach ($result -> publications as $publication){ $doi=$dois[$publication -> id]; if($doi!=null&&$resultsFromDois[$doi]!=null){ $doiResult=$resultsFromDois[$doi]; if ($publication -> url == NULL) // set URL if missing $publication -> url = $doiResult -> url; if ($publication -> title == NULL) // set title if missing $publication -> title = $doiResult -> title; foreach ($doiResult -> authors as $doiAuthor) { // merge authors if ((count($publication -> authors) == 0) || ($doiAuthor -> id != $publication -> authors[0] -> id) || ($doiAuthor -> lastName != $publication -> authors[0] -> lastName) || ($doiAuthor -> firstName != $publication -> authors[0] -> firstName) || ($doiAuthor -> fullName != $publication -> authors[0] -> fullName)) $publication -> authors[] = $doiAuthor; } if ($publication -> year == NULL) // set year if missing $publication -> year = $doiResult -> year; } } $result -> totalPublications = $i; $result -> totalDatasets = 0; $result -> author = $author; JLog :: add('ORCID search retrieved ' . count($result -> publications) . ' publications in ' . (microtime(TRUE) - $time) . ' s (ORCID: ' . $orcid . ', page: ' . $page . ', size: ' . $size . ')', JLog :: INFO, self :: LOG); return $result; } catch (Exception $e) { JLog :: add('Error performing ORCID search (ORCID: ' . $orcid . ', page: ' . $page . ', size: ' . $size . '): ' . $e -> getMessage(), JLog :: ERROR, self :: LOG); $result = new JObject(); $result -> totalPublications = 0; $result -> totalDatasets = 0; $result -> author = $author; return $result; } } private function _searchDOI($doi, $page, $size) { try { $result = new JObject(); $result -> publications = array(); $result -> totalPublications = 0; $result -> totalDatasets = 0; $dois = explode(" ", preg_replace('/\s+/', ' ',$doi)); $unique_dois =array_slice( array_unique($dois),0,10); $pattern1 ='#\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])\S)+)\b#'; $pattern2 ='#\b(10[.][0-9]{4,}(?:[.][0-9]+)*/(?:(?!["&\'<>])[[:graph:]])+)\b#'; if (preg_match($pattern1,$unique_dois[0])||preg_match($pattern2,$unique_dois[0])){ if(count($dois)>10){ $result = new JObject(); $result->publications = array(); $result->totalPublications = '-'; $result->totalDatasets = 0; $result->maxDoisExceeded = true; return $result; } JLog :: add('Searching for DOIs ' , JLog :: INFO, self :: LOG); /*foreach($unique_dois as $doi_){ JLog :: add('DOI::: '.$doi_ , JLog :: INFO, self :: LOG); $publication = $this->_searchSingleDOI($doi_); if ($publication != null) { $result->publications[] = $publication; } }*/ $result->publications= $this->_searchMultipleDOIs($unique_dois); } $result -> totalPublications = count( $result -> publications); if($result -> totalPublications ===0){ //.'&rows='.$size.'&offset='.$page $request = "http://api.crossref.org/works?query=" . urlencode( trim($doi))."&rows=".$size."&offset=".($page-1)*$size; JLog :: add('Requesting ' . $request, JLog :: INFO, self :: LOG); $time = microtime(TRUE); $response = $this -> http -> get($request); JLog :: add('Received response in ' . (microtime(TRUE) - $time) . ' s', JLog :: INFO, self :: LOG); if ($response == NULL) throw new Exception('no HTTP response'); if ($response -> code != self :: HTTP_OK) throw new Exception('HTTP response code ' . $response -> code); $res = array(); $response= $response -> body; $response=str_replace("date-parts", "date_parts",$response); $response=str_replace("total-results", "total_results",$response); //$res = json_decode(str_replace("-", "_", $response -> body)); $res = json_decode($response); if(isset($res -> status)&&$res -> status === "ok" && isset($res -> message)){ foreach($res ->message -> items as $item){ $publication = $this -> _parseJsonDOI($item); if($publication!=null){ $result -> publications[] = $publication; } } $result -> totalPublications = $res -> message ->total_results; /*if(isset($size)&&isset($page)){ $result -> publications = array_slice($result -> publications, ($page - 1) * $size, $size); }*/ } } return $result; } catch (Exception $e) { JLog :: add('Error performing DOI search (doi: ' . $doi . '): ' . $e -> getMessage(), JLog :: ERROR, self :: LOG); $result = new JObject(); $result -> publications = array(); $result -> totalPublications = 0; $result -> totalDatasets = 0; JLog :: add('error parsing DOI record', JLog :: INFO, self :: LOG); return $result; } } public function searchSingleDOI($doi) { if ($this -> cache -> getCaching()) { $cacheId = self :: SEARCH_DOI_CACHE_ID . '.' . $doi; $results = $this -> cache -> get($cacheId, self :: CACHE_GROUP); if ($results === FALSE) { $results = $this -> _searchSingleDOI($doi); if ($results !== NULL) $this -> cache -> store($results, $cacheId, self :: CACHE_GROUP); } } else $results = $this -> _searchSingleDOI($doi); return $results; } private function _searchSingleDOI($doi) { try { $request = self :: CROSSREF_API_DOI . urlencode( trim($doi)); JLog :: add('Requesting ' . $request, JLog :: INFO, self :: LOG); $time = microtime(TRUE); $response = $this -> http -> get($request); JLog :: add('Received response in ' . (microtime(TRUE) - $time) . ' s', JLog :: INFO, self :: LOG); if ($response == NULL) throw new Exception('no HTTP response'); if ($response -> code != self :: HTTP_OK) throw new Exception('HTTP response code ' . $response -> code); $res = array(); $response= $response -> body; $response=str_replace("date-parts", "date_parts",$response); $response=str_replace("total-results", "total_results",$response); //$res = json_decode(str_replace("-", "_", $response -> body)); $res = json_decode($response); if(isset($res -> status) && $res -> status === "ok" && isset($res -> message)){ $publication = $this -> _parseJsonDOI($res -> message); return $publication; } } catch (Exception $e) { JLog :: add('Error performing DOI search (doi: ' . $doi . '): ' . $e -> getMessage(), JLog :: ERROR, self :: LOG); $result = new JObject(); $result -> publications = array(); $result -> totalPublications = 0; $result -> totalDatasets = 0; JLog :: add('error parsing DOI record', JLog :: INFO, self :: LOG); return null; } } private function _searchMultipleDOIs($dois){ try { $request ="http://api.crossref.org/works"."?filter="; foreach($dois as $doi){ $request.="doi:".urlencode( trim($doi)).","; } JLog :: add('Requesting ' . $request, JLog :: INFO, self :: LOG); $time = microtime(TRUE); $response = $this -> http -> get($request); JLog :: add('Received response in ' . (microtime(TRUE) - $time) . ' s', JLog :: INFO, self :: LOG); if ($response == NULL) throw new Exception('no HTTP response'); if ($response -> code != self :: HTTP_OK) throw new Exception('HTTP response code ' . $response -> code); $res = array(); $res = json_decode(str_replace("-", "_", $response -> body)); if(isset($res -> status) && $res -> status === "ok" && isset($res -> message)){ $publications = $this ->_parseMultipleJsonDOIs($res -> message); return $publications; } } catch (Exception $e) { JLog :: add('Error performing DOI search (doi: ' . $doi . '): ' . $e -> getMessage(), JLog :: ERROR, self :: LOG); $result = new JObject(); $result -> publications = array(); $result -> totalPublications = 0; $result -> totalDatasets = 0; JLog :: add('error parsing DOI record', JLog :: INFO, self :: LOG); return null; } } // Search for a publication DOI using caching if enabled. // $doi the publication DOI to search for // return an array of results public function searchDOI($doi, $page, $size) { if ($this -> cache -> getCaching()) { $cacheId = self :: SEARCH_DOI_CACHE_ID . '.' . $doi; $results = $this -> cache -> get($cacheId, self :: CACHE_GROUP); if ($results === FALSE) { $results = $this -> _searchDOI($doi, $page, $size); if ($results !== NULL) $this -> cache -> store($results, $cacheId, self :: CACHE_GROUP); } } else $results = $this -> _searchDOI($doi, $page, $size); return $results; } // Search for a dataset DOI using caching if enabled. // $doi the dataset DOI to search for // return a result (object) containing publications and total public function searchDataCite($doi, $page, $size) { if ($this -> cache -> getCaching()) { $cacheId = self :: SEARCH_DATASET_CACHE_ID . '.' . $doi; $results = $this -> cache -> get($cacheId, self :: CACHE_GROUP); if ($results === FALSE) { $results = $this -> _searchDataCite($doi, $page, $size); if ($results !== NULL) $this -> cache -> store($results, $cacheId, self :: CACHE_GROUP); } } else $results = $this -> _searchDataCite($doi, $page, $size); return $results; } // Search for publications in ORCID using caching if enabled. // $doi the ORCID id to search for // $page the result page to retrieve // $size the result page size to use // return a result (object) containing datasets and total public function searchORCID($orcid, $page, $size) { if ($this -> cache -> getCaching()) { $cacheId = self :: SEARCH_ORCID_CACHE_ID . '.' . $orcid . '.' . $page . '.' . $size; $results = $this -> cache -> get($cacheId, self :: CACHE_GROUP); if ($results === FALSE) { $results = $this -> _searchORCID($orcid, $page, $size); if ($results !== NULL) $this -> cache -> store($results, $cacheId, self :: CACHE_GROUP); } } else $results = $this -> _searchORCID($orcid, $page, $size); return $results; } } ?>