Add validation and support for identifiers in PersonJsonDenormalizer, enhance altNames handling, and update tests for improved coverage. Adjust PersonIdentifierManager to handle identifier definitions by ID.

This commit is contained in:
2025-09-16 12:06:39 +02:00
parent bc8f3537ed
commit 5687f16817
4 changed files with 270 additions and 17 deletions

View File

@@ -14,9 +14,12 @@ namespace Chill\PersonBundle\Serializer\Normalizer;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Civility;
use Chill\MainBundle\Entity\Gender;
use Chill\PersonBundle\Entity\Identifier\PersonIdentifier;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\PersonAltName;
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierManagerInterface;
use libphonenumber\PhoneNumber;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
@@ -27,11 +30,13 @@ use Symfony\Component\Serializer\Normalizer\ObjectToPopulateTrait;
*
* To find an existing instance by his id, see the @see{PersonJsonReadDenormalizer}.
*/
class PersonJsonDenormalizer implements DenormalizerInterface, DenormalizerAwareInterface
final class PersonJsonDenormalizer implements DenormalizerInterface, DenormalizerAwareInterface
{
use DenormalizerAwareTrait;
use ObjectToPopulateTrait;
public function __construct(private readonly PersonIdentifierManagerInterface $personIdentifierManager) {}
public function denormalize($data, string $type, ?string $format = null, array $context = []): Person
{
$person = $this->extractObjectToPopulate($type, $context);
@@ -78,19 +83,48 @@ class PersonJsonDenormalizer implements DenormalizerInterface, DenormalizerAware
}
if (\array_key_exists('altNames', $data)) {
foreach ($data['altNames'] as $altName) {
$oldAltName = $person
->getAltNames()
->filter(static fn (PersonAltName $n): bool => $n->getKey() === $altName['key'])->first();
if (false === $oldAltName) {
$newAltName = new PersonAltName();
$newAltName->setKey($altName['key']);
$newAltName->setLabel($altName['label']);
$person->addAltName($newAltName);
} else {
$oldAltName->setLabel($altName['label']);
foreach ($data['altNames'] as $altNameData) {
if (!array_key_exists('key', $altNameData)
|| !array_key_exists('value', $altNameData)
|| '' === trim($altNameData['key'])
) {
throw new UnexpectedValueException('format for alt name is not correct');
}
$altNameKey = $altNameData['key'];
$altNameValue = $altNameData['value'];
$altName = $person->getAltNames()->findFirst(fn (PersonAltName $personAltName) => $personAltName->getKey() === $altNameKey);
if (null === $altName) {
$altName = new PersonAltName();
$person->addAltName($altName);
}
$altName->setKey($altNameKey)->setLabel($altNameValue);
}
}
if (\array_key_exists('identifiers', $data)) {
foreach ($data['identifiers'] as $identifierData) {
if (!array_key_exists('definition_id', $identifierData)
|| !array_key_exists('value', $identifierData)
|| !is_int($identifierData['definition_id'])
|| !is_array($identifierData['value'])
) {
throw new UnexpectedValueException('format for identifiers is not correct');
}
$definitionId = $identifierData['definition_id'];
$value = $identifierData['value'];
$worker = $this->personIdentifierManager->buildWorkerByPersonIdentifierDefinition($definitionId);
$personIdentifier = $person->getIdentifiers()->findFirst(fn (PersonIdentifier $personIdentifier) => $personIdentifier->getId() === $definitionId);
if (null === $personIdentifier) {
$personIdentifier = new PersonIdentifier($worker->getDefinition());
$person->addIdentifier($personIdentifier);
}
$personIdentifier->setValue($value);
$personIdentifier->setCanonical($worker->canonicalizeValue($value));
}
}