workRepository = $workRepository; $this->em = $em; } public function denormalize($data, string $type, ?string $format = null, array $context = []) { $work = $this->denormalizer->denormalize($data, $type, $format, array_merge( $context, ['skip' => self::class] )); if (in_array('accompanying_period_work:edit', $context['groups'] ?? [])) { $this->handleEvaluationCollection($data, $work, $format, $context); } return $work; } public function supportsDenormalization($data, string $type, ?string $format = null, array $context = []): bool { return AccompanyingPeriodWork::class === $type && self::class !== ($context['skip'] ?? null) && is_array($data) && array_key_exists('type', $data) && 'accompanying_period_work' === $data['type']; } private function handleEvaluationCollection(array $data, AccompanyingPeriodWork $work, string $format, array $context) { $dataById = []; $dataWithoutId = []; foreach ($data['accompanyingPeriodWorkEvaluations'] as $e) { if (array_key_exists('id', $e)) { $dataById[$e['id']] = $e; } else { $dataWithoutId[] = $e; } } // partition the separate kept evaluations and removed one [$kept, $removed] = $work->getAccompanyingPeriodWorkEvaluations() ->partition( static fn (int $key, AccompanyingPeriodWorkEvaluation $a) => array_key_exists($a->getId(), $dataById) ); // remove the evaluations from work foreach ($removed as $r) { $work->removeAccompanyingPeriodWorkEvaluation($r); } // handle the evaluation kept foreach ($kept as $k) { $this->denormalizer->denormalize( $dataById[$k->getId()], AccompanyingPeriodWorkEvaluation::class, $format, array_merge( $context, [ 'groups' => ['write'], AbstractNormalizer::OBJECT_TO_POPULATE => $k, ] ) ); } // create new evaluation foreach ($dataWithoutId as $newData) { $evaluation = $this->denormalizer->denormalize( $newData, AccompanyingPeriodWorkEvaluation::class, $format, array_merge( $context, ['groups' => ['accompanying_period_work_evaluation:create']] ) ); $work->addAccompanyingPeriodWorkEvaluation($evaluation); } } }