<?php namespace App\Service; use League\Csv\Reader; use League\Csv\Writer; use Symfony\Component\HttpClient\HttpClient; use Symfony\Contracts\HttpClient\HttpClientInterface; class Openalex { private $client; private $id; public function __construct() { $this->client = HttpClient::create(); } public function getId(): ?int { return $this->id; } public function setId(int $id): self { $this->id = $id; return $this; } public function run(string $filename='file.csv'){ $writer = Writer::createFromPath($filename, 'w+'); $i = 0; $next = '*'; do { $next = $this->traitement($next,$writer); } while (!is_null($next)); } private function traitement($next,$writer) { $exclude = ['abstract_inverted_index','concepts','authorships','alternate_host_venues','referenced_works','related_works','is_paratext','biblio','is_authors_truncated']; $doSplit = ['open_access','host_venue']; $ret = $this->fetchOpenAlexAPI("https://api.openalex.org/works?filter=institutions.ror:https://ror.org/00afp2z80|https://ror.org/00bmzhb16|https://ror.org/044s61914,type:article,publication_year:2018|2019|2020&per-page=200&cursor=".$next); foreach ($ret['results'] as $key => $value) { $this->setId($key); $ret['results'][$key]['abstract'] = $this->parseAbstractInvertedIndex($ret['results'][$key]['abstract_inverted_index']); foreach ($value as $key2 => $value2) { if (in_array($key2,$exclude)) { unset($ret['results'][$key][$key2]); } else if (is_array($value2) && in_array($key2,$doSplit)) { unset($ret['results'][$key][$key2]); if(strcmp('host_venue', $key2) === 0 ){ if(is_null($value2['issn'])){ $value2['issn']=array('',''); } else if(count($value2['issn']) < 2 ){ $value2['issn'][1]=''; } else if(count($value2['issn']) > 2){ $value2['issn'] = array_slice($value2['issn'], 0, 2); } } $input = $this->array_flat($value2, $key2); $ret['results'][$key] = array_merge($ret['results'][$key], $input); } else if (is_array($value2) && !in_array($key2,$doSplit)) { $input = $this->array_flat($value2, $key2); $ret['results'][$key][$key2] = implode('||', array_map( function ($v, $k) { return sprintf("%s='%s'", $k, $v); }, $input, array_keys($input) )); } } } $writer->insertAll($ret['results']); return $ret['meta']['next_cursor']; } private function fetchOpenAlexAPI(string $url): array { $response = $this->client->request( 'GET', $url ); $statusCode = $response->getStatusCode(); $contentType = $response->getHeaders()['content-type'][0]; $content = $response->toArray(); return $content; } private function array_flat($array, $prefix = '') { $result = array(); foreach ($array as $key => $value) { $new_key = $prefix . (empty($prefix) ? '' : '.') . $key; if (is_array($value)) { $result = array_merge($result, $this->array_flat($value, $new_key)); } else { $result[$new_key] = $value; } } return $result; } private function parseAbstractInvertedIndex(?array $abstract) { $abstractArray = null; if(!is_null($abstract) && !empty($abstract)){ foreach ($abstract as $key => $value) { foreach ($value as $val) { $abstractArray[$val] = $key; } } if(ksort($abstractArray)){ return implode(' ',$abstractArray); } } return null; } }