diff --git a/src/Controller/Admin/CalendarController.php b/src/Controller/Admin/CalendarController.php index 449e097..eea139e 100644 --- a/src/Controller/Admin/CalendarController.php +++ b/src/Controller/Admin/CalendarController.php @@ -6,7 +6,6 @@ use App\Entity\CalendarInstance; use App\Entity\CalendarSubscription; use App\Entity\Principal; -use App\Entity\SchedulingObject; use App\Entity\User; use App\Form\CalendarInstanceType; use Doctrine\Persistence\ManagerRegistry; @@ -240,6 +239,12 @@ public function calendarShareAdd(ManagerRegistry $doctrine, Request $request, in #[Route('/{userId}/delete/{id}', name: 'delete', requirements: ['id' => "\d+"])] public function calendarDelete(ManagerRegistry $doctrine, int $userId, string $id, TranslatorInterface $trans): Response { + $user = $doctrine->getRepository(User::class)->findOneById($userId); + if (!$user) { + throw $this->createNotFoundException('User not found'); + } + $principalUri = Principal::PREFIX.$user->getUsername(); + $instance = $doctrine->getRepository(CalendarInstance::class)->findOneById($id); if (!$instance) { throw $this->createNotFoundException('Calendar not found'); @@ -252,11 +257,11 @@ public function calendarDelete(ManagerRegistry $doctrine, int $userId, string $i $entityManager->remove($subscription); } - $schedulingObjects = $doctrine->getRepository(SchedulingObject::class)->findByPrincipalUri($instance->getPrincipalUri()); - foreach ($schedulingObjects ?? [] as $object) { + // Scheduling objects attached to the calendar objects of the calendar + $schedulingObjectsOfCalendarObjects = $doctrine->getRepository(CalendarInstance::class)->findAllSchedulingObjectsForCalendar($instance->getId(), $principalUri); + foreach ($schedulingObjectsOfCalendarObjects ?? [] as $object) { $entityManager->remove($object); } - foreach ($instance->getCalendar()->getObjects() ?? [] as $object) { $entityManager->remove($object); } diff --git a/src/Repository/CalendarInstanceRepository.php b/src/Repository/CalendarInstanceRepository.php index 27c2c6c..dd85434 100644 --- a/src/Repository/CalendarInstanceRepository.php +++ b/src/Repository/CalendarInstanceRepository.php @@ -2,8 +2,11 @@ namespace App\Repository; +use App\Entity\Calendar; use App\Entity\CalendarInstance; +use App\Entity\CalendarObject; use App\Entity\Principal; +use App\Entity\SchedulingObject; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -37,11 +40,11 @@ public function findSharedInstancesOfInstance(int $calendarId, bool $withCalenda return $query->addSelect('p.displayName', 'p.email') ->getQuery() ->getArrayResult(); - } else { - // Returns CalendarInstances as objects - return $query->getQuery() - ->getResult(); } + + // Returns CalendarInstances as objects + return $query->getQuery() + ->getResult(); } /** @@ -74,6 +77,23 @@ public function hasDifferentOwner(int $calendarId, string $principalUri): bool ->getSingleScalarResult() > 0; } + + public function findAllSchedulingObjectsForCalendar(int $calendarInstanceId, string $principalUri): array + { + $objectRepository = $this->getEntityManager()->getRepository(SchedulingObject::class); + return $objectRepository->createQueryBuilder('s') + ->leftJoin(CalendarObject::class, 'c', \Doctrine\ORM\Query\Expr\Join::WITH, 'c.uri = s.uri') + ->leftJoin(CalendarInstance::class, 'ci', \Doctrine\ORM\Query\Expr\Join::WITH, 'ci.calendar = c.calendar') + ->where('ci.id = :id') + // uri is not unique across calendars — two different calendars can have objects with the same uri. + // The join should also filter by principaluri as a consequence + ->andWhere('s.principalUri = :principalUri') + ->setParameter('id', $calendarInstanceId) + ->setParameter('principalUri', $principalUri) + ->getQuery() + ->getResult(); + } + /** * Get counts of calendar objects by component type for a calendar instance. * @@ -83,7 +103,7 @@ public function hasDifferentOwner(int $calendarId, string $principalUri): bool */ public function getObjectCountsByComponentType(int $calendarId): array { - $objectRepository = $this->getEntityManager()->getRepository(\App\Entity\CalendarObject::class); + $objectRepository = $this->getEntityManager()->getRepository(CalendarObject::class); // Instead of three separate queries, get all counts in a single query $results = $objectRepository->createQueryBuilder('o') @@ -95,9 +115,9 @@ public function getObjectCountsByComponentType(int $calendarId): array ->getResult(); $componentTypeMap = [ - \App\Entity\Calendar::COMPONENT_EVENTS => 'events', - \App\Entity\Calendar::COMPONENT_NOTES => 'notes', - \App\Entity\Calendar::COMPONENT_TODOS => 'tasks', + Calendar::COMPONENT_EVENTS => 'events', + Calendar::COMPONENT_NOTES => 'notes', + Calendar::COMPONENT_TODOS => 'tasks', ]; $counts = [