calculateSyncEnd($schema, $today); $deadlines = $this->deadlineCalculator->getDeadlinesForRange($schema, $today, $end); $shouldExist = []; foreach ($deadlines as $deadline) { $shouldExist[$deadline->format('Y-m-d')] = true; } $existingByDate = $this->loadExistingByDate($schema, $today); $this->removeObsoleteTasks($existingByDate, $shouldExist); $this->handleNullDateTasks($schema); $this->resetFutureOverrides($existingByDate); $this->createMissingTasks($schema, $deadlines, $existingByDate); $this->em->flush(); } private function calculateSyncEnd(TaskSchema $schema, \DateTimeImmutable $today): \DateTimeImmutable { $minEnd = $today->modify('+6 days'); $end = $schema->getEndDate() ? new \DateTimeImmutable($schema->getEndDate()->format('Y-m-d')) : $minEnd; return $end < $minEnd ? $minEnd : $end; } /** * @return array */ private function loadExistingByDate(TaskSchema $schema, \DateTimeImmutable $today): array { $futureTasks = $this->taskRepository->findBySchemaFromDate($schema, $today); $existingByDate = []; foreach ($futureTasks as $task) { $existingByDate[$task->getDate()->format('Y-m-d')] = $task; } return $existingByDate; } /** * @param array $existingByDate * @param array $shouldExist */ private function removeObsoleteTasks(array &$existingByDate, array $shouldExist): void { foreach ($existingByDate as $dateKey => $task) { if (!isset($shouldExist[$dateKey])) { $this->em->remove($task); unset($existingByDate[$dateKey]); } } } private function handleNullDateTasks(TaskSchema $schema): void { $nullDateTasks = $this->taskRepository->findBy(['schema' => $schema, 'date' => null]); if ($schema->getTaskType() === TaskSchemaType::Single && $schema->getDeadline() === null) { foreach ($nullDateTasks as $task) { $task->setName(null); $task->setCategory(null); $task->setCategoryOverridden(false); } } else { foreach ($nullDateTasks as $task) { $this->em->remove($task); } } } /** * @param array $existingByDate */ private function resetFutureOverrides(array $existingByDate): void { foreach ($existingByDate as $task) { $task->setName(null); $task->setCategory(null); $task->setCategoryOverridden(false); } } /** * @param \DateTimeInterface[] $deadlines * @param array $existingByDate */ private function createMissingTasks(TaskSchema $schema, array $deadlines, array $existingByDate): void { foreach ($deadlines as $deadline) { $dateKey = $deadline->format('Y-m-d'); if (!isset($existingByDate[$dateKey])) { $task = new Task(); $task->setSchema($schema); $task->setDate(new \DateTime($dateKey)); $this->em->persist($task); } } } }