|null $entity the entity or collection of entities to normalize * * @return array|int|string Returns the identifier(s) of the entity or entities. If an array of entities is provided, * an array of their identifiers is returned. If a single entity is provided, its identifier * is returned. If null, returns an empty value. */ private function normalizeDoctrineEntity(object|array|null $entity): array|int|string { if (is_array($entity)) { return array_values(array_filter(array_map(static fn (object $entity) => $entity->getId(), $entity), fn ($value) => null !== $value)); } if ($entity instanceof Collection) { return $this->normalizeDoctrineEntity($entity->toArray()); } return $entity?->getId(); } /** * Denormalizes a Doctrine entity by fetching it from the provided repository based on the given ID(s). * * @param list|int|string $id the identifier(s) of the entity to find * @param ObjectRepository $repository the Doctrine repository to query * * @return object|array the found entity or an array of entities if multiple IDs are provided * * @throws \UnexpectedValueException when the entity with the given ID does not exist */ private function denormalizeDoctrineEntity(array|int|string $id, ObjectRepository $repository): object|array { if (is_array($id)) { if ([] === $id) { return []; } return $repository->findBy(['id' => $id]); } if (null === $object = $repository->find($id)) { throw new \UnexpectedValueException(sprintf('Object with id "%s" does not exist.', $id)); } return $object; } /** * Normalizer the "user or me" values. * * @param 'me'|User|iterable<'me'|User> $user * * @return int|'me'|list<'me'|int> */ private function normalizeUserOrMe(string|User|iterable $user): int|string|array { if (is_iterable($user)) { $users = []; foreach ($user as $u) { $users[] = $this->normalizeUserOrMe($u); } return $users; } if ('me' === $user) { return $user; } return $user->getId(); } /** * @param 'me'|int|iterable<'me'|int> $userId * * @return 'me'|User|array|null */ private function denormalizeUserOrMe(string|int|iterable $userId, UserRepositoryInterface $userRepository): string|User|array|null { if (is_iterable($userId)) { $users = []; foreach ($userId as $id) { $users[] = $this->denormalizeUserOrMe($id, $userRepository); } return $users; } if ('me' === $userId) { return 'me'; } return $userRepository->find($userId); } /** * @param 'me'|User|iterable<'me'|User> $user * * @return User|list */ private function userOrMe(string|User|iterable $user, ExportGenerationContext $context): User|array { if (is_iterable($user)) { $users = []; foreach ($user as $u) { $users[] = $this->userOrMe($u, $context); } return array_values( array_filter($users, static fn (?User $user) => null !== $user) ); } if ('me' === $user) { return $context->byUser; } return $user; } /** * Normalizes a provided date into a specific string format. * * @param \DateTimeImmutable|\DateTime $date the date instance to normalize * * @return string a formatted string containing the type and formatted date */ private function normalizeDate(\DateTimeImmutable|\DateTime $date): string { return sprintf( '%s,%s', $date instanceof \DateTimeImmutable ? 'imm1' : 'mut1', $date->format('d-m-Y-H:i:s.u e'), ); } /** * Denormalizes a string back into a DateTime instance. * * The string is expected to contain a kind selector (e.g., 'imm1' or 'mut1') * to determine the type of DateTime object (immutable or mutable) followed by a date format. * * @param string $date the string to be denormalized, containing the kind selector and formatted date * * @return \DateTimeImmutable|\DateTime a DateTime instance created from the given string * * @throws \UnexpectedValueException if the kind selector or date format is invalid */ private function denormalizeDate(string $date): \DateTimeImmutable|\DateTime { $format = 'd-m-Y-H:i:s.u e'; $denormalized = match (substr($date, 0, 4)) { 'imm1' => \DateTimeImmutable::createFromFormat($format, substr($date, 5)), 'mut1' => \DateTime::createFromFormat($format, substr($date, 5)), default => throw new \UnexpectedValueException(sprintf('Unexpected format for the kind selector: %s', substr($date, 0, 4))), }; if (false === $denormalized) { throw new \UnexpectedValueException(sprintf('Unexpected date format: %s', substr($date, 5))); } return $denormalized; } }