diff --git a/src/Controller/DomainCalendarController.php b/src/Controller/DomainCalendarController.php deleted file mode 100644 index 9475898..0000000 --- a/src/Controller/DomainCalendarController.php +++ /dev/null @@ -1,62 +0,0 @@ -domainRepository->findOneBy(["ldhName" => $ldhName]); - $attendees = []; - - /** @var DomainEntity $entity */ - foreach ($domain->getDomainEntities()->toArray() as $entity) { - $vCard = Reader::readJson($entity->getEntity()->getJCard()); - $email = (string)$vCard->EMAIL; - if (!filter_var($email, FILTER_VALIDATE_EMAIL)) continue; - - $attendees[] = (new Attendee(new EmailAddress($email)))->setDisplayName((string)$vCard->FN); - } - - /** @var DomainEvent $event */ - foreach ($domain->getEvents()->toArray() as $event) { - $calendar->addEvent((new Event()) - ->setSummary($domain->getLdhName() . ' (' . $event->getAction()->value . ')') - ->addCategory(new Category($event->getAction()->value)) - ->setAttendees($attendees) - ->setOccurrence(new SingleDay(new Date($event->getDate()))) - ); - } - return new Response((new CalendarFactory())->createCalendar($calendar), Response::HTTP_OK, [ - "Content-Type" => 'text/calendar; charset=utf-8' - ]); - } -} \ No newline at end of file diff --git a/src/Controller/WatchListController.php b/src/Controller/WatchListController.php index f10d0e9..81bef0b 100644 --- a/src/Controller/WatchListController.php +++ b/src/Controller/WatchListController.php @@ -2,13 +2,30 @@ namespace App\Controller; +use App\Entity\DomainEntity; +use App\Entity\DomainEvent; use App\Entity\User; use App\Entity\WatchList; +use App\Repository\WatchListRepository; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\EntityManagerInterface; +use Eluceo\iCal\Domain\Entity\Attendee; +use Eluceo\iCal\Domain\Entity\Calendar; +use Eluceo\iCal\Domain\Entity\Event; +use Eluceo\iCal\Domain\ValueObject\Category; +use Eluceo\iCal\Domain\ValueObject\Date; +use Eluceo\iCal\Domain\ValueObject\EmailAddress; +use Eluceo\iCal\Domain\ValueObject\SingleDay; +use Eluceo\iCal\Presentation\Factory\CalendarFactory; use Exception; +use Sabre\VObject\EofException; +use Sabre\VObject\InvalidDataException; +use Sabre\VObject\ParseException; +use Sabre\VObject\Reader; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Serializer\SerializerInterface; @@ -16,27 +33,13 @@ class WatchListController extends AbstractController { public function __construct( - private readonly SerializerInterface $serializer, private readonly EntityManagerInterface $em + private readonly SerializerInterface $serializer, + private readonly EntityManagerInterface $em, + private readonly WatchListRepository $watchListRepository ) { } - #[Route( - path: '/api/watchlists', - name: 'watchlist_get_all_mine', - defaults: [ - '_api_resource_class' => WatchList::class, - '_api_operation_name' => 'get_all_mine', - ], - methods: ['GET'] - )] - public function getWatchLists(): Collection - { - /** @var User $user */ - $user = $this->getUser(); - return $user->getWatchLists(); - } - /** * @throws Exception */ @@ -60,4 +63,70 @@ class WatchListController extends AbstractController return $watchList; } + /** + * @throws ParseException + * @throws EofException + * @throws InvalidDataException + */ + #[Route( + path: '/api/watchlists/{token}/calendar', + name: 'watchlist_calendar', + defaults: [ + '_api_resource_class' => WatchList::class, + '_api_operation_name' => 'calendar', + ] + )] + public function getWatchlistCalendar(string $token): Response + { + $watchList = $this->watchListRepository->findOneBy(["token" => $token]); + /** @var User $user */ + $user = $this->getUser(); + if (!$user->getWatchLists()->contains($watchList)) throw new UnauthorizedHttpException(''); + + $calendar = new Calendar(); + + foreach ($watchList->getDomains()->getIterator() as $domain) { + $attendees = []; + + /** @var DomainEntity $entity */ + foreach ($domain->getDomainEntities()->toArray() as $entity) { + $vCard = Reader::readJson($entity->getEntity()->getJCard()); + $email = (string)$vCard->EMAIL; + if (!filter_var($email, FILTER_VALIDATE_EMAIL)) continue; + + $attendees[] = (new Attendee(new EmailAddress($email)))->setDisplayName((string)$vCard->FN); + } + + /** @var DomainEvent $event */ + foreach ($domain->getEvents()->toArray() as $event) { + $calendar->addEvent((new Event()) + ->setSummary($domain->getLdhName() . ' (' . $event->getAction() . ')') + ->addCategory(new Category($event->getAction())) + ->setAttendees($attendees) + ->setOccurrence(new SingleDay(new Date($event->getDate()))) + ); + } + } + + return new Response((new CalendarFactory())->createCalendar($calendar), Response::HTTP_OK, [ + "Content-Type" => 'text/calendar; charset=utf-8' + ]); + } + + #[Route( + path: '/api/watchlists', + name: 'watchlist_get_all_mine', + defaults: [ + '_api_resource_class' => WatchList::class, + '_api_operation_name' => 'get_all_mine', + ], + methods: ['GET'] + )] + public function getWatchLists(): Collection + { + /** @var User $user */ + $user = $this->getUser(); + return $user->getWatchLists(); + } + } \ No newline at end of file diff --git a/src/Entity/WatchList.php b/src/Entity/WatchList.php index 9528340..75a2690 100644 --- a/src/Entity/WatchList.php +++ b/src/Entity/WatchList.php @@ -8,6 +8,7 @@ use ApiPlatform\Metadata\Get; use ApiPlatform\Metadata\GetCollection; use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Post; +use App\Controller\WatchListController; use App\Repository\WatchListRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -28,6 +29,29 @@ use Symfony\Component\Uid\Uuid; new Get( normalizationContext: ['groups' => 'watchlist:item'] ), + new Get( + routeName: 'watchlist_calendar', + controller: WatchListController::class, + openapiContext: [ + 'responses' => [ + '200' => [ + 'description' => 'Watchlist iCalendar', + 'content' => [ + 'text/calendar' => [ + 'schema' => [ + 'type' => 'string', + 'format' => 'text' + ] + ] + ] + ] + ] + ], + read: false, + deserialize: false, + serialize: false, + name: 'calendar' + ), new Post( routeName: 'watchlist_create', normalizationContext: ['groups' => 'watchlist:list'], denormalizationContext: ['groups' => 'watchlist:create'],