feat: add AwardImporter service with tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
89
src/Service/AwardImporter.php
Normal file
89
src/Service/AwardImporter.php
Normal 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user