Introduce PersonJsonReadDenormalizer and PersonJsonDenormalizer to separate responsibilities for handling person denormalization. Add corresponding test classes for improved coverage. Refactor PersonJsonNormalizer to remove denormalization logic.

This commit is contained in:
2025-09-16 11:14:22 +02:00
parent 6e9ed7f79f
commit e4d256ceb3
5 changed files with 272 additions and 139 deletions

View File

@@ -0,0 +1,113 @@
<?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\Serializer\Normalizer;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Civility;
use Chill\MainBundle\Entity\Gender;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\PersonAltName;
use libphonenumber\PhoneNumber;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\ObjectToPopulateTrait;
/**
* Denormalize a Person entity from a JSON-like array structure, creating or updating an existing instance.
*
* To find an existing instance by his id, see the @see{PersonJsonReadDenormalizer}.
*/
class PersonJsonDenormalizer implements DenormalizerInterface, DenormalizerAwareInterface
{
use DenormalizerAwareTrait;
use ObjectToPopulateTrait;
public function denormalize($data, string $type, ?string $format = null, array $context = []): Person
{
$person = $this->extractObjectToPopulate($type, $context);
if (null === $person) {
$person = new Person();
}
// Setters applied directly per known field for readability
if (\array_key_exists('firstName', $data)) {
$person->setFirstName($data['firstName']);
}
if (\array_key_exists('lastName', $data)) {
$person->setLastName($data['lastName']);
}
if (\array_key_exists('phonenumber', $data)) {
$person->setPhonenumber($this->denormalizer->denormalize($data['phonenumber'], PhoneNumber::class, $format, $context));
}
if (\array_key_exists('mobilenumber', $data)) {
$person->setMobilenumber($this->denormalizer->denormalize($data['mobilenumber'], PhoneNumber::class, $format, $context));
}
if (\array_key_exists('gender', $data)) {
$gender = $this->denormalizer->denormalize($data['gender'], Gender::class, $format, []);
$person->setGender($gender);
}
if (\array_key_exists('birthdate', $data)) {
$object = $this->denormalizer->denormalize($data['birthdate'], \DateTime::class, $format, $context);
$person->setBirthdate($object);
}
if (\array_key_exists('deathdate', $data)) {
$object = $this->denormalizer->denormalize($data['deathdate'], \DateTimeImmutable::class, $format, $context);
$person->setDeathdate($object);
}
if (\array_key_exists('center', $data)) {
$object = $this->denormalizer->denormalize($data['center'], Center::class, $format, $context);
$person->setCenter($object);
}
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']);
}
}
}
if (\array_key_exists('email', $data)) {
$person->setEmail($data['email']);
}
if (\array_key_exists('civility', $data)) {
$civility = $this->denormalizer->denormalize($data['civility'], Civility::class, $format, []);
$person->setCivility($civility);
}
return $person;
}
public function supportsDenormalization($data, $type, $format = null): bool
{
return Person::class === $type && 'person' === ($data['type'] ?? null) && !isset($data['id']);
}
}