diff --git a/app/Profile.php b/app/Profile.php index d8f6f0e..17f3577 100644 --- a/app/Profile.php +++ b/app/Profile.php @@ -174,64 +174,124 @@ public function hasOrcidManagedPublications() return $this->information()->where('data->orc_id_managed', '1')->exists(); } + /** + * Iterate over the publications retrieved from the ORCID API for a given profile and import the publication if it doesn't exist in the db already + */ public function updateORCID() { - $orc_id = $this->information()->get(array('data'))->toArray()[0]['data']['orc_id']; + $orc_id = $this->information()->get(array('data'))->toArray()[0]['data']['orc_id']; - if(is_null($orc_id)){ + if(is_null($orc_id)){ //can't update if we don't know your ID return false; - } + } - $orc_url = "https://pub.orcid.org/v2.0/" . $orc_id . "/activities"; + $orc_url = "https://pub.orcid.org/v2.0/" . $orc_id . "/activities"; - $client = new Client(); + $client = new Client(); - $res = $client->get($orc_url, [ - 'headers' => [ - 'Authorization' => 'Bearer ' . config('ORCID_TOKEN'), - 'Accept' => 'application/json' - ], - 'http_errors' => false, // don't throw exceptions for 4xx,5xx responses - ]); + $res = $client->get($orc_url, [ + 'headers' => [ + 'Authorization' => 'Bearer ' . config('ORCID_TOKEN'), + 'Accept' => 'application/json' + ], + 'http_errors' => false, // don't throw exceptions for 4xx,5xx responses + ]); - //an error of some sort - if($res->getStatusCode() != 200){ - return false; - } + //an error of some sort + if($res->getStatusCode() != 200){ + return false; + } + + $datum = json_decode($res->getBody()->getContents(), true); + + $sort_order = count($datum['works']['group'] ?? []) + 1; + + Cache::tags(['profile-{$this->id}-current_publications'])->flush(); + + $current_publications = Cache::remember( + "profile-{$this->id}-current_publications", + 15 * 60, + fn() => $this->publications()->get() + ); + + foreach($datum['works']['group'] as $record) { + $url = null; + $publications_found = null; + $existing_publication = false; + + foreach($record['external-ids']['external-id'] as $ref){ + if($ref['external-id-type'] == "eid"){ + $url = "https://www.scopus.com/record/display.uri?origin=resultslist&eid=" . $ref['external-id-value']; + } + else if($ref['external-id-type'] == "doi"){ + $url = "http://doi.org/" . $ref['external-id-value']; + $doi = $ref['external-id-value']; + } + } + + if ($current_publications->count() > 0) { + + $publications_found = $current_publications->filter(function ($elem) use ($ref) { return (isset($elem->data['doi'])) && ($elem->data['doi'] == $ref['external-id-value']); }); + + $existing_publication = $publications_found->count() > 0 ? true : false; - $datum = json_decode($res->getBody()->getContents(), true); + if (!$existing_publication) { - foreach($datum['works']['group'] as $record){ - $url = NULL; - foreach($record['external-ids']['external-id'] as $ref){ - if($ref['external-id-type'] == "eid"){ - $url = "https://www.scopus.com/record/display.uri?origin=resultslist&eid=" . $ref['external-id-value']; + $publications_found = Profile::searchPublicationByTitleAndYear($record['work-summary'][0]['title']['title']['value'], $record['work-summary'][0]['publication-date']['year']['value'], $current_publications); + + $existing_publication = empty($publications_found[1]) ? false : true; + } } - else if($ref['external-id-type'] == "doi"){ - $url = "http://doi.org/" . $ref['external-id-value']; + + if (!$existing_publication) { + $record = ProfileData::create([ + 'profile_id' => $this->id, + 'type' => 'publications', + 'sort_order' => $sort_order--, + 'data' => [ + 'url' => $url, + 'title' => $record['work-summary'][0]['title']['title']['value'], + 'year' => $record['work-summary'][0]['publication-date']['year']['value'] ?? null, + 'type' => ucwords(strtolower(str_replace('_', ' ', $record['work-summary'][0]['type']))), + 'status' => 'Published', + 'doi' => $doi, + ], + ]); } - } - $record = ProfileData::firstOrCreate([ - 'profile_id' => $this->id, - 'type' => 'publications', - 'data->title' => $record['work-summary'][0]['title']['title']['value'], - 'sort_order' => $record['work-summary'][0]['publication-date']['year']['value'] ?? null, - ],[ - 'data' => [ - 'url' => $url, - 'title' => $record['work-summary'][0]['title']['title']['value'], - 'year' => $record['work-summary'][0]['publication-date']['year']['value'] ?? null, - 'type' => ucwords(strtolower(str_replace('_', ' ', $record['work-summary'][0]['type']))), - 'status' => 'Published' - ], - ]); - } - Cache::tags(['profile_data'])->flush(); + } + + Cache::tags(['profile-{$this->id}-current_publications'])->flush(); + Cache::tags(['profile_data'])->flush(); + + //ran through process successfully + return true; + } + + /** + * Search for a publication by year and title within a given publications collection + * Return array with DOI and matching title + * @return Array + */ + public static function searchPublicationByTitleAndYear($title, $year, $publications) + { + $title = strip_tags(html_entity_decode($title)); + $year = $year; + $publication_found = $aa_doi = $aa_title = null; + + $publication_found = $publications->filter(function ($item) use ($title, $year) { + if (str_contains(strtolower($title), strtolower(strip_tags(html_entity_decode($item['data']['title'])))) and $year==$item['data']['year']) return true; + similar_text(strtolower($title), strtolower(strip_tags(html_entity_decode($item['data']['title']))), $percent); + if (($percent > 80) and ($year==$item['data']['year'])) return true; + }); + + if ($publication_found->count() == 1) { + $aa_doi = $publication_found->first()->doi; + $aa_title = $publication_found->first()->title; + } - //ran through process successfully - return true; + return [$aa_doi, $aa_title]; } public function updateDatum($section, $request) diff --git a/package-lock.json b/package-lock.json index 1f3ce5b..c5a41d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,7 @@ "requires": true, "packages": { "": { + "name": "profiles", "dependencies": { "puppeteer": "^16.1.0" },