src/Controller/IcsController.php line 118

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Booking;
  4. use App\Entity\Property;
  5. use App\Entity\User;
  6. use App\Entity\User\UserRole;
  7. use App\Repository\BookingRepository;
  8. use App\Repository\PropertyRepository;
  9. use DateTime;
  10. use DateTimeZone;
  11. use Doctrine\Common\Collections\Collection;
  12. use Doctrine\Common\Collections\Criteria;
  13. use ICal\ICal;
  14. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  15. use Symfony\Component\HttpFoundation\JsonResponse;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\Routing\Annotation\Route;
  18. use Symfony\Component\HttpFoundation\Response;
  19. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  20. use Symfony\Contracts\HttpClient\HttpClientInterface;
  21. class IcsController extends AbstractController {
  22.     public function __construct(
  23.         private PropertyRepository $propertyRepository,
  24.         private BookingRepository $bookingRepository
  25.     ) {}
  26.     /**
  27.      * @Route("/properties/{id}/ics/parsed", name="parseCalendar",
  28.      *  requirements={"id"="[\w\-\+\.]+"}
  29.      * )
  30.      */
  31.     public function parseCalendar(string $idHttpClientInterface $httpClientInterface): Response {
  32.         throw new \Exception("Jayyrr");
  33.         
  34.         return new JsonResponse([
  35.             'Fail'
  36.         ], 404);
  37.     }
  38.     private static function ww(string $w): string {
  39.         return wordwrap($w65"\n "false);
  40.     }
  41.     protected static function vevent(Booking $bstring $descstring $summary) {
  42.         $start $b->getCheckin();
  43.         $end $b->getCheckout();
  44.         $md5 md5($b->getCalIdentifier());
  45.         // $desc = '$prop->getUncleanBookings("now")->count()} unclean units';
  46.         $summary = static::ww($summary);
  47.         $desc = static::ww($desc);
  48.         return <<<VEVENT
  49. BEGIN:VEVENT
  50. DTSTAMP;TZID=Europe/Oslo:{$start->format('Ymd')}T{$start->format('His')}
  51. DTSTART;VALUE=DATE:{$start->format('Ymd')}
  52. DTEND;VALUE=DATE:{$end->format('Ymd')}
  53. UID:{$md5}@askepott.giaever.online
  54. DESCRIPTION:{$desc}
  55. SUMMARY:{$summary}
  56. END:VEVENT
  57. VEVENT;
  58.     }
  59.     protected static function vbegin(Property $property, array $rest): string {
  60.         $rest join($rest);
  61.         return <<<VBEGIN
  62. BEGIN:VCALENDAR
  63. PRODID;X-RICAL-TZSOURCE=TZINFO:-//BNB.hosting//Simple Calendar 0.1//EN
  64. CALSCALE:GREGORIAN
  65. VERSION:2.0
  66. X-WR-CALNAME:{$property->getSection()}{$rest}
  67. END:VCALENDAR
  68. VBEGIN;
  69.     }
  70.     /**
  71.      * @Route({
  72.      *  "/properties/{id}/ics/{action}", 
  73.      *  "/p/{id}/ics/{action}",
  74.      *  "/ics/{id}/{action}",
  75.      *  "/p/{id}/i/{action}"
  76.      * }, name="simpleCalendar",
  77.      *  requirements={"id"="[\w\-\+\.]+"}
  78.      * )
  79.      */
  80.     public function icsCalendar(string $idstring $actionRequest $request) {
  81.         $property $this->propertyRepository->find($id) ?: $this->propertyRepository->findOneBy([
  82.             'section' => strtoupper($id)
  83.         ]) ?: null;
  84.         if ($property == null)
  85.             throw new NotFoundHttpException('Pollo');
  86.         $set = fn (string $keymixed $default null): bool => $request->get($key$default) !== false;
  87.         $out = match($action) {
  88.             'unclean' => static::getUnclean($property),
  89.             default => static::getReservations($property$set('only-bookings'
  90.                 $set('bookings-only'
  91.                     !$set('include-blocking'true)
  92.                 )
  93.             ))
  94.         };
  95.         if ($out->count() == 0)
  96.             $out->add(
  97.                 static::vevent((new Booking($property))->setCheckin(
  98.                     new \DateTimeImmutable("-365 days")
  99.                 )->setCheckout(
  100.                     new \DateTimeImmutable('-1 days')
  101.                 ), "Clean" "Clean")
  102.             );
  103.         return new Response(str_replace("\n""\r\n", static::vbegin($property$out->map(
  104.             fn($a) => "\n" $a
  105.             )->toArray())
  106.         ), 200, [
  107.             'Content-type' => 'text/calendar; charset=utf-8',
  108.             'Content-Disposition' => sprintf('inline; filename=%s-%d-simple.ics'$property->getSection(), time())
  109.         ]);
  110.     }
  111.     private  static function getUnclean(Property $property): Collection {
  112.         return $property->getUncleanBookings()->map(
  113.             fn(Booking $b): string => static::vevent($b,
  114.                 sprintf('Unclean from %s'
  115.                     $b->getCheckout()->format('d-m-Y H:i')
  116.                 ), sprintf('Ready at %s'
  117.                     $b->getProperty()->getTodaysCheckinTime($b->getCheckout())->format('d-m-Y H:i')
  118.                 )
  119.             )
  120.         );
  121.     }
  122.     private static function getReservations(Property $propertybool $bookingsOnly true): Collection|array {
  123.         return $property->getBookings(
  124.             Criteria::expr()->gte('checkout', new \DateTimeImmutable()),
  125.             Criteria::expr()->isNull('cancelledAt'),
  126.             ...[Booking::cleanCriteria(false), ...($bookingsOnly ? [Criteria::expr()->neq('blocking'1)] : [])]
  127.         )->map(
  128.             fn(Booking $b): string => match ($b->isBlocking()) {
  129.                 true => static::vevent($bsprintf('%s => %s'
  130.                     $b->getCheckin()->format('d-m-Y H:i'),
  131.                     $b->getCheckout()->format('d-m-Y H:i')
  132.                 ), sprintf('Blocked: %s'$b->getCalendarSource())),
  133.                 default => static::vevent($bsprintf('Check-in %s, Check-out: %s',
  134.                     $b->getCheckin()->format('d-m-Y H:i'),
  135.                     $b->getCheckout()->format('d-m-Y H:i')
  136.                 ), $b->getGuests() ? sprintf('%d guests'$b->getGuests() ?: 0) : 'Guests not set')
  137.             }
  138.         );
  139.     }
  140. }