feat: add AwardImporter service with tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
thibaud-leclere
2026-04-01 14:27:15 +02:00
parent d4d2272396
commit 8aa33ccefc
2 changed files with 228 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
<?php
declare(strict_types=1);
namespace App\Service;
use App\Entity\Actor;
use App\Entity\Award;
use App\Entity\AwardType;
use App\Gateway\WikidataGateway;
use App\Repository\AwardTypeRepository;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
readonly class AwardImporter
{
public function __construct(
private WikidataGateway $wikidataGateway,
private AwardTypeRepository $awardTypeRepository,
private EntityManagerInterface $em,
private ?LoggerInterface $logger = null,
) {}
public function importForActor(Actor $actor): void
{
if ($actor->isAwardsImported()) {
return;
}
try {
$wikidataAwards = $this->wikidataGateway->getAwards($actor);
} catch (\Throwable $e) {
$this->logger?->warning('Failed to fetch awards from Wikidata', [
'actor' => $actor->getName(),
'error' => $e->getMessage(),
]);
return;
}
$knownTypes = $this->awardTypeRepository->findAll();
foreach ($wikidataAwards as $wikidataAward) {
$awardType = $this->resolveAwardType($wikidataAward['name'], $knownTypes);
$award = new Award();
$award->setName($wikidataAward['name']);
$award->setYear($wikidataAward['year']);
$award->setActor($actor);
$award->setAwardType($awardType);
$this->em->persist($award);
}
$actor->setAwardsImported(true);
}
/**
* @param list<AwardType> $knownTypes
*/
private function resolveAwardType(string $awardName, array &$knownTypes): AwardType
{
foreach ($knownTypes as $type) {
if (str_contains($awardName, $type->getPattern())) {
return $type;
}
}
$newType = new AwardType();
$prefix = $this->extractPrefix($awardName);
$newType->setName($prefix);
$newType->setPattern($prefix);
$this->em->persist($newType);
$knownTypes[] = $newType;
return $newType;
}
private function extractPrefix(string $awardName): string
{
// Extract text before " for " or " pour " (common patterns in award names)
if (preg_match('/^(.+?)\s+(?:for|pour)\s+/i', $awardName, $matches)) {
return trim($matches[1]);
}
return $awardName;
}
}