1
0
cms11/app/Console/Commands/Wikidata/UpdateProperties.php

93 lines
2.9 KiB
PHP

<?php
namespace App\Console\Commands\Wikidata;
use App\Models\WikidataProperty;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
class UpdateProperties extends Command
{
protected $signature = 'wikidata:update-properties';
protected $description = 'Import Wikidata properties into the database.';
public function handle()
{
$data = $this->fetchData();
$this->importData($data);
}
/**
* Fetch data from Wikidata or cache.
*/
protected function fetchData(): array
{
$endpoint = 'https://query.wikidata.org/sparql';
$query = "
SELECT ?property ?propertyType ?propertyLabel ?propertyDescription ?propertyAltLabel WHERE {
?property wikibase:propertyType ?propertyType .
SERVICE wikibase:label { bd:serviceParam wikibase:language \"fr\". }
}
ORDER BY ASC(xsd:integer(STRAFTER(STR(?property), 'P')))";
$response = Http::throw()->timeout(60)->withHeaders(['Accept' => 'application/sparql-results+json'])
->get($endpoint, ['query' => $query]);
return $response->json();
}
/**
* Import data into the database.
*/
protected function importData(array $data): void
{
$total = count($data['results']['bindings']);
$this->info("Starting import of $total Wikidata properties.");
$bar = $this->output->createProgressBar($total);
$bar->start();
DB::transaction(function () use ($data, &$bar) {
$batchSize = 200;
foreach (array_chunk($data['results']['bindings'], $batchSize) as $batch) {
$this->insertBatch($batch, $bar);
}
});
$bar->finish();
$this->newLine(2);
$this->info('Properties imported successfully.');
}
/**
* Insert a batch of properties into the database.
*
* @param \Symfony\Component\Console\Helper\ProgressBar $bar
*/
protected function insertBatch(array $batch, $bar): void
{
$upsertData = [];
foreach ($batch as $result) {
$propertyId = str_replace('http://www.wikidata.org/entity/', '', $result['property']['value']);
$upsertData[] = [
'property_id' => $propertyId,
'property_type' => $result['propertyType']['value'] ?? null,
'label' => $result['propertyLabel']['value'] ?? null,
'description' => $result['propertyDescription']['value'] ?? null,
'alt_label' => $result['propertyAltLabel']['value'] ?? null,
];
$bar->advance();
}
WikidataProperty::upsert($upsertData, 'property_id', ['property_type', 'label', 'description', 'alt_label']);
}
}