Ajoute la gestion de l'upsert des utilisateurs avec un nouveau handler et un message d'upsert, met à jour les dépendances et ajoute une méthode pour trouver un utilisateur par son identifiant externe.

This commit is contained in:
Boris Waaub
2026-02-23 10:18:52 +01:00
parent 590f4121d0
commit 312dbf6cda
5 changed files with 112 additions and 3 deletions

View File

@@ -98,7 +98,7 @@
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.3",
"fakerphp/faker": "^1.13",
"friendsofphp/php-cs-fixer": "3.93.0",
"friendsofphp/php-cs-fixer": "^3.94",
"jangregor/phpstan-prophecy": "^1.0",
"nelmio/alice": "^3.8",
"nikic/php-parser": "^4.15",
@@ -113,13 +113,13 @@
"symfony/debug-bundle": "^5.4",
"symfony/dotenv": "^5.4",
"symfony/flex": "^2.4",
"symfony/loco-translation-provider": "^6.0",
"symfony/maker-bundle": "^1.20",
"symfony/phpunit-bridge": "^7.1",
"symfony/runtime": "^5.4",
"symfony/stopwatch": "^5.4",
"symfony/var-dumper": "^5.4",
"symfony/web-profiler-bundle": "^5.4",
"symfony/loco-translation-provider": "^6.0"
"symfony/web-profiler-bundle": "^5.4"
},
"conflict": {
"symfony/symfony": "*"

View File

@@ -11,6 +11,7 @@
"@hotwired/stimulus": "^3.0.0",
"@luminateone/eslint-baseline": "^1.0.9",
"@symfony/stimulus-bridge": "^3.2.0",
"@symfony/ux-translator": "file:vendor/symfony/ux-translator/assets",
"@symfony/webpack-encore": "^4.1.0",
"@tsconfig/node20": "^20.1.4",
"@types/dompurify": "^3.0.5",

View File

@@ -0,0 +1,83 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\Bundle\ChillPersonBundle\Entity\Person\Upsert\Handler;
use Chill\PersonBundle\Repository\PersonRepository;
use Chill\PersonBundle\Repository\Identifier\PersonIdentifierDefinitionRepository;
use Chill\PersonBundle\Repository\Identifier\PersonIdentifierRepository;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\Identifier\PersonIdentifier;
use Chill\PersonBundle\Entity\Person\Upsert\UpsertMessage;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Doctrine\ORM\EntityManagerInterface;
#[AsMessageHandler]
class PersonUpsertHandler
{
public function __construct(
// TODO: Utiliser findByExternalId à la place de findByDefinitionAndCanonical ?
private readonly PersonRepository $personRepository,
private readonly PersonIdentifierDefinitionRepository $personIdentifierDefinitionRepository,
private readonly PersonIdentifierRepository $personIdentifierRepository,
private readonly EntityManagerInterface $entityManager,
) {}
public function __invoke(UpsertMessage $message): void
{
// 1. Récupérer la définition
$definition = $this->personIdentifierDefinitionRepository->find($message->personIdentifierDefinitionId);
if (!$definition) {
throw new \RuntimeException('PersonIdentifierDefinition non trouvée pour l\'id '.$message->personIdentifierDefinitionId);
}
// 2. Chercher les identifiants
$identifiers = $this->personIdentifierRepository->findByDefinitionAndCanonical($definition, $message->externalId);
if (count($identifiers) > 1) {
throw new \RuntimeException('Plus d\'un identifiant trouvé pour la définition et la valeur donnée.');
}
if (0 === count($identifiers)) {
// 3. Créer une nouvelle entité Person
$person = new Person();
if (null !== $message->firstName) {
$person->setFirstName($message->firstName);
}
if (null !== $message->lastName) {
$person->setLastName($message->lastName);
}
$this->entityManager->persist($person);
// Créer l'identifiant et l'associer
$identifier = new PersonIdentifier($definition);
$identifier->setPerson($person);
$identifier->setValue(['content' => $message->externalId]);
$this->entityManager->persist($identifier);
} else {
// 4. Mettre à jour le Person existant
/** @var PersonIdentifier $identifier */
$identifier = $identifiers[0];
$person = $identifier->getPerson();
if (null === $person) {
throw new \RuntimeException('L\'identifiant trouvé n\'est lié à aucun Person.');
}
if (null !== $message->firstName) {
$person->setFirstName($message->firstName);
}
if (null !== $message->lastName) {
$person->setLastName($message->lastName);
}
}
$this->entityManager->flush();
}
}

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Entity\Person\Upsert;
class UpsertMessage
{
public string $externalId;
public int $personIdentifierDefinitionId;
public ?string $firstName = null;
public ?string $lastName = null;
}

View File

@@ -73,6 +73,11 @@ class PersonRepository implements ObjectRepository
return $this->repository->findBy(['id' => $ids]);
}
public function findByExternalId(string $externalId): ?Person
{
return $this->repository->findOneBy(['externalId' => $externalId]);
}
/**
* @throws \Exception
*