<?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;
}
}