denormalizer->denormalize($data, $type, $format, array_merge( $context, ['skip' => self::class] )); $this->handleDocumentCollection($data, $evaluation, $format, $context); return $evaluation; } public function supportsDenormalization($data, $type, $format = null, array $context = []): bool { return AccompanyingPeriodWorkEvaluation::class === $type && self::class !== ($context['skip'] ?? null) && is_array($data) && array_key_exists('type', $data) && 'accompanying_period_work_evaluation' === $data['type']; } private function handleDocumentCollection(array $data, AccompanyingPeriodWorkEvaluation $evaluation, string $format, array $context) { $dataById = []; $dataWithoutId = []; foreach ($data['documents'] as $e) { if (array_key_exists('id', $e)) { $dataById[$e['id']] = $e; } else { $dataWithoutId[] = $e; } } //partition the separate kept documents and removed one [$kept, $removed] = $evaluation->getDocuments() ->partition( static fn (int $key, AccompanyingPeriodWorkEvaluationDocument $a) => array_key_exists($a->getId(), $dataById) ); // remove the document from evaluation foreach ($removed as $r) { $evaluation->removeDocument($r); } // handle the documents kept foreach ($kept as $k) { $this->denormalizer->denormalize( $dataById[$k->getId()], AccompanyingPeriodWorkEvaluationDocument::class, $format, array_merge( $context, [ 'groups' => ['write'], AbstractNormalizer::OBJECT_TO_POPULATE => $k, ] ) ); } // create new document foreach ($dataWithoutId as $newData) { $document = $this->denormalizer->denormalize( $newData, AccompanyingPeriodWorkEvaluationDocument::class, $format, array_merge( $context, ['groups' => ['accompanying_period_work_evaluation:create']] ) ); $evaluation->addDocument($document); } } }