<?php
namespace CorpusParole\Services;
use CorpusParole\Services\ViafResolverInterface;
use Cache;
use Config;
use EasyRdf\Graph;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Cache\Repository as CacheRepository;
class ViafResolver implements ViafResolverInterface {
private $client = null;
public function __construct(Client $httpClient) {
$this->client = $httpClient;
}
/**
* make the viaf query.
*/
public function queryName($id) {
$url = config('corpusparole.viaf_base_url').$id;
try {
$response = $this->client->get($url."/", ['headers'=>['Accept' => 'application/rdf+xml'],]);
}
catch(ClientException $e) {
if($e->getResponse()->getStatusCode() === 404) {
return null;
} else {
throw new ViafResolverException(
$e->getMessage(),
$e->getResponse()->getStatusCode(),
$e
);
}
}
catch(RequestException $e) {
throw new ViafResolverException(
$e->getMessage(),
$e->hasResponse()?$e->getResponse()->getStatusCode():500,
$e
);
}
$graph = new Graph($url, $response->getBody());
$names = [];
foreach ($graph->allLiterals("<$url>", "schema:name") as $nameLit) {
$lang = $nameLit->getLang();
if(!$lang && !isset($names[''])) {
$names[''] = $nameLit->getvalue();
}
elseif (strpos($lang, 'fr') === 0 && !isset($names['fr'])) {
$names['fr'] = $nameLit->getvalue();
}
elseif (strpos($lang, 'en') === 0 && !isset($names['en'])) {
$names['en'] = $nameLit->getvalue();
}
}
return (isset($names['fr'])) ? $names['fr'] : ((isset($names['en'])) ? $names['en'] : ((isset($names['']))? $names[''] : null));
}
/**
* Check viaf id format
*/
private function checkViafIdFormat($viafid) {
return ctype_digit($viafid);
}
/**
* Get name from Viaf id
* @param string $id The id to resolve. Can be an url starting with http://viaf.org/viaf/
* @return a string with the name
*/
public function getName($id) {
$viafid = $id;
if(strpos($id, config('corpusparole.viaf_base_url')) === 0) {
$viafid = substr($id, strlen(config('corpusparole.viaf_base_url')));
}
$viafid = rtrim($viafid, '/');
if(!$this->checkViafIdFormat($viafid)) {
throw new ViafResolverException("ViafId not in correct format", 400);
}
$that = $this;
return Cache::remember("viaf:$viafid", config('corpusparole.viaf_cache_expiration'), function() use ($that, $viafid) {
return $that->queryName($viafid);
});
}
/**
* Get a list of names from an array of viaf ids.
* @param array $ids The array of ids to resolve.
* Each id can be an url starting with http://viaf.org/viaf/
*/
public function getNames(array $ids) {
if(count($ids) > config('corpusparole.viaf_max_ids')) {
throw new ViafResolverException("Too manys ids provided");
}
return array_combine($ids, array_map([$this,'getName'], $ids));
}
}