* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ namespace Chill\PersonBundle\Serializer\Normalizer; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher; use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Person; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface; use Chill\PersonBundle\Repository\PersonRepository; use Symfony\Component\Serializer\Exception\RuntimeException; use Symfony\Component\Serializer\Exception\UnexpectedValueException; use Chill\MainBundle\Templating\Entity\ChillEntityRenderExtension; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\Normalizer\ObjectToPopulateTrait; /** * Serialize a Person entity * */ class PersonJsonNormalizer implements NormalizerInterface, NormalizerAwareInterface, DenormalizerInterface, DenormalizerAwareInterface { private ChillEntityRenderExtension $render; private PersonRepository $repository; private CenterResolverManagerInterface $centerResolverManager; use NormalizerAwareTrait; use ObjectToPopulateTrait; use DenormalizerAwareTrait; public function __construct( ChillEntityRenderExtension $render, PersonRepository $repository, CenterResolverManagerInterface $centerResolverManager ) { $this->render = $render; $this->repository = $repository; $this->centerResolverManager = $centerResolverManager; } public function normalize($person, string $format = null, array $context = []) { /** @var Household $household */ $household = $person->getCurrentHousehold(); /** @var Person $person */ return [ 'type' => 'person', 'id' => $person->getId(), 'text' => $this->render->renderString($person), 'firstName' => $person->getFirstName(), 'lastName' => $person->getLastName(), 'birthdate' => $this->normalizer->normalize($person->getBirthdate(), $format, $context), 'deathdate' => $this->normalizer->normalize($person->getDeathdate(), $format, $context), 'centers' => $this->normalizer->normalize($this->centerResolverManager->resolveCenters($person), $format, $context), 'phonenumber' => $person->getPhonenumber(), 'mobilenumber' => $person->getMobilenumber(), 'altNames' => $this->normalizeAltNames($person->getAltNames()), 'gender' => $person->getGender(), 'current_household_address' => $this->normalizer->normalize($person->getCurrentHouseholdAddress(), $format, $context), 'current_household_id' => $household ? $this->normalizer->normalize($household->getId(), $format, $context) : null, ]; } protected function normalizeAltNames($altNames): array { $r = []; foreach ($altNames as $n) { $r[] = [ 'key' => $n->getKey(), 'label' => $n->getLabel() ]; } return $r; } public function supportsNormalization($data, string $format = null): bool { return $data instanceof Person && $format === 'json'; } public function denormalize($data, string $type, string $format = null, array $context = []) { $person = $this->extractObjectToPopulate($type, $context); if (\array_key_exists('id', $data)) { $person = $this->repository->find($data['id']); if (null === $person) { throw new UnexpectedValueException("The person with id \"{$data['id']}\" does ". "not exists"); } // currently, not allowed to update a person through api // if instantiated with id return $person; } if (null === $person) { $person = new Person(); } foreach (['firstName', 'lastName', 'phonenumber', 'mobilenumber', 'gender', 'birthdate', 'deathdate', 'center'] as $item) { if (!\array_key_exists($item, $data)) { continue; } switch ($item) { case 'firstName': $person->setFirstName($data[$item]); break; case 'lastName': $person->setLastName($data[$item]); break; case 'phonenumber': $person->setPhonenumber($data[$item]); break; case 'mobilenumber': $person->setMobilenumber($data[$item]); break; case 'gender': $person->setGender($data[$item]); break; case 'birthdate': $object = $this->denormalizer->denormalize($data[$item], \DateTime::class, $format, $context); if ($object instanceof \DateTime) { $person->setBirthdate($object); } break; case 'deathdate': $object = $this->denormalizer->denormalize($data[$item], \DateTime::class, $format, $context); if ($object instanceof \DateTime) { $person->setDeathdate($object); } break; case 'center': $object = $this->denormalizer->denormalize($data[$item], Center::class, $format, $context); $person->setCenter($object); break; default: throw new \LogicException("item not defined: $item"); } } return $person; } public function supportsDenormalization($data, string $type, string $format = null) { return $type === Person::class && ($data['type'] ?? NULL) === 'person'; } }