133 lines
3.6 KiB
PHP
133 lines
3.6 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace App\Services\Wikidata;
|
||
|
|
||
|
use Illuminate\Support\Facades\Cache;
|
||
|
use Illuminate\Support\Facades\Http;
|
||
|
use Illuminate\Support\Str;
|
||
|
|
||
|
class WikidataClient
|
||
|
{
|
||
|
protected static string $cachePrefix = 'wikidata';
|
||
|
|
||
|
public function __construct(protected array $config)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Search for an entity ID for text submitted as $expression
|
||
|
*/
|
||
|
public function searchEntityId(string $expression)
|
||
|
{
|
||
|
$data = [
|
||
|
'action' => 'wbsearchentities',
|
||
|
'search' => $expression,
|
||
|
'language' => 'en',
|
||
|
'limit' => 10,
|
||
|
'format' => 'json',
|
||
|
];
|
||
|
|
||
|
$response = $this->getFromApi($data);
|
||
|
$items = [];
|
||
|
|
||
|
if (!empty($response['search'])) {
|
||
|
foreach ($response['search'] as $item) {
|
||
|
$items[$item['id']] = sprintf('[%s] %s (%s)', $item['id'], $item['label'], $item['description'] ?? null);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $items;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return complete set of data related to specified entity
|
||
|
*/
|
||
|
public function getEntityData(string $entityId)
|
||
|
{
|
||
|
$data = [
|
||
|
'action' => 'wbgetentities',
|
||
|
'ids' => $entityId,
|
||
|
'languages' => 'fr|en',
|
||
|
'format' => 'json',
|
||
|
];
|
||
|
|
||
|
return $this->getFromApi($data);
|
||
|
|
||
|
// if ($replaceIds) {
|
||
|
// $data = json_encode($result, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||
|
// $properties = $this->getDeclaredPropertiesInEntity($data);
|
||
|
// $entities = $this->getDeclaredEntitiesInEntity($data, $entityId);
|
||
|
// $result = $this->replaceLabelsIn($result, $properties, $entities, $entityId);
|
||
|
// }
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return an array containing Wikidata Entities Id as keys and corresponding
|
||
|
* labels as values
|
||
|
*/
|
||
|
public function getLabelsForEntities(array $entities)
|
||
|
{
|
||
|
$result = [];
|
||
|
$batchSize = 50;
|
||
|
$batches = array_chunk($entities, $batchSize);
|
||
|
|
||
|
foreach ($batches as $batch) {
|
||
|
$ids = implode('|', $batch);
|
||
|
$data = [
|
||
|
'action' => 'wbgetentities',
|
||
|
'ids' => $ids,
|
||
|
'props' => 'labels|descriptions',
|
||
|
'languages' => 'fr|en',
|
||
|
'format' => 'json',
|
||
|
];
|
||
|
|
||
|
$result += $this->getFromApi($data)['entities'];
|
||
|
}
|
||
|
|
||
|
$labels = [];
|
||
|
|
||
|
foreach ($result as $id => $entity) {
|
||
|
if (
|
||
|
!isset($entity['labels']['fr']['value'])
|
||
|
&& !isset($entity['labels']['en']['value'])
|
||
|
) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
$label = $entity['labels']['fr']['value']
|
||
|
?? $entity['labels']['en']['value'];
|
||
|
|
||
|
$description = $entity['descriptions']['fr']['value']
|
||
|
?? $entity['descriptions']['en']['value']
|
||
|
?? null;
|
||
|
|
||
|
if ($label) {
|
||
|
$labels[$id] = Str::ucfirst($label);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $labels;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Perform a GET request against wikidata API
|
||
|
*/
|
||
|
private function getFromApi(array $params)
|
||
|
{
|
||
|
$baseUrl = $this->config['baseApiUrl'];
|
||
|
$slug = Str::slug(http_build_query($params));
|
||
|
$cacheKey = sprintf('%s_%s', static::$cachePrefix, $slug);
|
||
|
|
||
|
if (Cache::has($cacheKey)) {
|
||
|
return Cache::get($cacheKey);
|
||
|
}
|
||
|
|
||
|
$response = Http::throw()->get($baseUrl, $params)->json();
|
||
|
|
||
|
Cache::put($cacheKey, $response, now()->addMonth());
|
||
|
|
||
|
return $response;
|
||
|
}
|
||
|
}
|