performChecks($data); // route to "leave movement" (all concerned leave household) // or "move to another household" (all concerned go to another // household) if (null === $data['destination']) { return $this->denormalizeLeave($data, $type, $format, $context); } return $this->denormalizeMove($data, $type, $format, $context); } public function supportsDenormalization($data, $type, $format = null) { return MembersEditor::class === $type; } protected function denormalizeLeave($data, string $type, string $format, array $context = []) { $editor = $this->factory->createEditor(null); foreach ($data['concerned'] as $key => $concerned) { $person = $this->denormalizer->denormalize( $concerned['person'] ?? null, Person::class, $format, $context ); $startDate = $this->denormalizer->denormalize( $concerned['start_date'] ?? null, \DateTimeImmutable::class, $format, $context ); if ( null === $person && null === $startDate ) { throw new Exception\InvalidArgumentException('position with '."key {$key} could not be denormalized: missing ".'person or start_date.'); } $editor->leaveMovement($startDate, $person); } return $editor; } protected function denormalizeMove($data, string $type, string $format, array $context = []) { $householdContext = $context; $householdContext['groups'][] = 'create'; $household = $this->denormalizer->denormalize( $data['destination'], Household::class, $format, $householdContext ); if (null === $household) { throw new Exception\InvalidArgumentException('household could not be denormalized. Impossible to process'); } $editor = $this->factory->createEditor($household); foreach ($data['concerned'] as $key => $concerned) { $person = $this->denormalizer->denormalize( $concerned['person'] ?? null, Person::class, $format, $context ); if (\array_key_exists('position', $concerned)) { $position = $this->denormalizer->denormalize( $concerned['position'] ?? null, Position::class, $format, $context ); } else { $position = null; } $startDate = $this->denormalizer->denormalize( $concerned['start_date'] ?? null, \DateTimeImmutable::class, $format, $context ); $holder = (bool) $concerned['holder'] ?? false; $comment = (string) $concerned['comment'] ?? false; if ( null === $person && null === $position && null === $startDate ) { throw new Exception\InvalidArgumentException('position with '."key {$key} could not be denormalized: missing ".'person, position or start_date.'); } $editor->addMovement( $startDate, $person, $position, $holder, $comment ); } if (null !== $data['composition']) { $compositionType = $this->denormalizer->denormalize($data['composition']['household_composition_type'], HouseholdCompositionType::class, $format, $context); $numberOfChildren = $data['composition']['number_of_children']; $startDate = $this->denormalizer->denormalize($data['composition']['start_date'], \DateTimeImmutable::class, $format, $context); if (null === $compositionType) { throw new \UnexpectedValueException('composition type cannot be null'); } $householdComposition = (new HouseholdComposition()) ->setHouseholdCompositionType($compositionType) ->setNumberOfChildren($numberOfChildren) ->setStartDate($startDate); $household->addComposition($householdComposition); } return $editor; } private function performChecks($data): void { if ( null === $data['concerned'] ?? null && false === \is_array('concerned') ) { throw new Exception\UnexpectedValueException("The schema does not have any key 'concerned'"); } if (false === \array_key_exists('destination', $data)) { throw new Exception\UnexpectedValueException("The schema does not have any key 'destination'"); } } }