src/Controller/Api/EventsApiController.php line 12

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Api;
  3. use Carbon\Carbon;
  4. use Pimcore\Controller\FrontendController;
  5. use Pimcore\Model\DataObject;
  6. use Symfony\Component\HttpFoundation\Request;
  7. use Symfony\Component\Routing\Annotation\Route;
  8. class EventsApiController extends FrontendController
  9. {
  10.     private $inputLat;
  11.     private $inputLon;
  12.     private $inputRadius;
  13.     /**
  14.      * @Route("/api/get-events", name="events")
  15.      */
  16.     public function defaultAction(Request $request)
  17.     {
  18.         $events = new DataObject\Event\Listing();
  19.         $eventsFillup = new DataObject\Event\Listing();
  20.         // premium
  21.         $inputPremiumOnly $request->get('premium''');
  22.         $inputSearch $request->get('q''');
  23.         $limit intval($request->get('l'30));
  24.         if ($limit 10) { $limit 10; }
  25.         // date
  26.         $inputWeek intval($request->get("week"0));
  27.         $inputDuration intval($request->get('duration'0));
  28.         $inputYear intval($request->get("year"0));
  29.         $inputDate $request->get("date""");
  30.         // geolocation umkreis
  31.         $inputLat floatval($request->get('lat'0.0));
  32.         $inputLon floatval($request->get('lon'0.0));
  33.         $inputRadius intval($request->get('radius'10));
  34.         $this->inputLat $inputLat;
  35.         $this->inputLon $inputLon;
  36.         $this->inputRadius $inputRadius;
  37.         $ids $request->get('id'null);
  38.         if ($ids) {
  39.             $ids explode(','$ids);
  40.         }
  41.         $orderKey = ['startDate'];
  42.         $events->setOrderKey($orderKey);
  43.         $events->setOrder('asc');
  44.         // tags
  45.         $tags $request->get("tags"null);
  46.         $now Carbon::now();
  47.         // $now->setYear(2022);
  48. //        if ($inputWeek >= 0 && $inputWeek < 53) {
  49. //            $year = $inputYear > 0 ? $inputYear : date('Y');
  50. //            $now = Carbon::now();
  51. //            $now->setISODate($year, $inputWeek);
  52. //        }
  53.         if ($inputDate) {
  54.             $now Carbon::parse($inputDate);
  55.         }
  56.         $year $now->yearIso;
  57.         $week $now->week;
  58. //        $startOfWeek = Carbon::parse($now)->startOfWeek();
  59.         $startOfWeek Carbon::parse($now)->startOfDay();
  60.         $endOfWeek Carbon::parse($now)->endOfWeek();
  61.         if ($inputDuration) {
  62.             $endOfWeek $endOfWeek->addWeeks($inputDuration);
  63.         }
  64.         $events->setOrderKey("dateStart");
  65.         $events->setOrder("asc");
  66.         $eventsFillup->setOrderKey("dateStart");
  67.         $eventsFillup->setOrder("asc");
  68.         $condition = [];
  69.         $conditionParams = [];
  70.         $conditionFillup = [];
  71.         $conditionFillupParams = [];
  72.         $doFillup true;
  73.         if ($tags) {
  74.             $condition[] = "topic LIKE :topic";
  75.             $conditionFillup[] = "topic LIKE :topic";
  76.             $conditionParams["topic"] = "%$tags%";
  77.             $conditionFillupParams["topic"] = "%$tags%";
  78.         }
  79.         if ($inputSearch) {
  80.             $condition[] = "(Title LIKE :search OR Text LIKE :search)";
  81.             $conditionParams["search"] = "%$inputSearch%";
  82.             $conditionFillup[] = "(Title LIKE :search OR Text LIKE :search)";
  83.             $conditionFillupParams["search"] = "%$inputSearch%";
  84.         }
  85.         if ($ids) {
  86.             $condition[] = "oo_id IN (:ids)";
  87.             $conditionParams["ids"] = $ids;
  88.         }
  89.         $condition[] = '((userEvent = 1 and released = 1) or (userEvent is null or userEvent = 0))';
  90. //        if ($startOfWeek && $endOfWeek) {
  91. //            $condition[] = "(dateStart >= :start AND dateStart <= :end OR (dateStart <= :start AND dateEnd > 0 AND dateEnd >= :endStart))";
  92. //            $conditionParams["start"] = $startOfWeek->getTimestamp();
  93. //            $conditionParams["endStart"] = $startOfWeek->getTimestamp();
  94. //            $conditionParams["end"] = $endOfWeek->getTimestamp();
  95. //            $conditionParams["endEnd"] = $endOfWeek->getTimestamp();
  96. //            $conditionFillup[] = "dateStart > :start";
  97. //            $conditionFillupParams["start"] = $endOfWeek->getTimestamp();
  98. //        }
  99.         $events->setCondition(join(' AND '$condition), $conditionParams);
  100.         $data $this->formatEvents($events);
  101.         $topics DataObject\ClassDefinition::getById(DataObject\Event::classId())->getFieldDefinition("Topic")->getOptions();
  102.         $topicsMap = [];
  103.         foreach ($topics as $topic) {
  104.             $topicsMap[$topic["value"]] = $topic["key"];
  105.         }
  106.         $returnData = [];
  107.         $count 0;
  108.         foreach ($data as $event) {
  109. //          $showEvent = (dateStart >= :start AND dateStart <= :end OR (dateStart <= :start AND dateEnd > 0 AND dateEnd >= :endStart))
  110.             $start Carbon::parse($event['dateStart']);
  111.             $end $event['dateEnd'] ? Carbon::parse($event['dateEnd']) : null;
  112.             $endOfDay Carbon::parse($event['dateStart'])->endOfDay();
  113.             foreach ($event['otherDates'] as $otherDate) {
  114.                 $start Carbon::parse($otherDate['dateStart']);
  115.                 $end $otherDate['dateEnd'] ? Carbon::parse($otherDate['dateEnd']) : null;
  116.                 $showEvent $start >= $startOfWeek || ($end && $end >= $now) || (!$end && $now $endOfDay);
  117.                 if ($showEvent) {
  118.                     $event['dateStart'] = $otherDate['dateStart'];
  119.                     $event['dateEnd'] = $otherDate['dateEnd'];
  120.                     $returnData[] = $event;
  121.                 }
  122.             }
  123.         }
  124.         usort($returnData, function ($a$b): int {
  125.             return [$a['premium'], $a['dateStart']] <=> [$b['premium'], $b['dateStart']];
  126.         });
  127.         if (count($returnData) > $limit) {
  128.             $returnData array_slice($returnData0$limit 1);
  129.         }
  130. //        if (count($data) < $limit && $doFillup) {
  131. //            $eventsFillup->setLimit($limit - count($data));
  132. //            $eventsFillup->setCondition(join(' AND ', $conditionFillup), $conditionFillupParams);
  133. //            $fillup = $this->formatEvents($eventsFillup);
  134. //            $data = array_merge($data, $fillup);
  135. ////            foreach ($fillup as $event) {
  136. ////                // todo: if $event is already in $data...
  137. ////                $data[] = $fillup;
  138. ////            }
  139. //        }
  140. //
  141. //        var_dump($data);
  142. //        die();
  143.         $response $this->json([
  144. //            "conditionParams" => $condition,
  145.             "success" => true,
  146.             "topics" => $topicsMap,
  147.             "week" => [
  148.                 "number" => $week,
  149.                 "date" => $now->toDateTime(),
  150.                 "start" => $startOfWeek,
  151.                 "end" => $endOfWeek,
  152.             ],
  153.             "data" => $returnData
  154.         ]);
  155.         $response->setExpires(new \DateTime('+3 minutes'));
  156.         return $response;
  157.     }
  158.     /**
  159.      * @Route("/api/get-event/{id}", name="event_by_id")
  160.      */
  161.     public function eventAction(int $idRequest $request)
  162.     {
  163.         $event DataObject\Event::getById($id);
  164.         if (!$event) {
  165.             throw $this->createNotFoundException('The event does not exist');
  166.         }
  167.         $response $this->json([
  168.             "success" => true,
  169.             "data" => $this->formatEvent($event)
  170.         ]);
  171.         $response->setExpires(new \DateTime('+3 minutes'));
  172.         return $response;
  173.     }
  174.     public function formatImageGallery($imageGallery) {
  175.         $data = [];
  176.         foreach ($imageGallery->getItems() as $item) {
  177.             $image $item->getImage();
  178.             $data[] = [
  179.                 "path" => $image->getThumbnail("standardThumbnail")->getPath(),
  180.             ];
  181.         }
  182.         return $data;
  183.     }
  184.     private function formatEvent($event) {
  185.         $link $this->generateUrl('event_detail', ['path' => $event->getKey()]);
  186.         $previewVideo null;
  187.         if ($event->getPreview()) {
  188.             $tmp $event->getPreview()->getData();
  189.             $previewVideo $tmp->getPath() . $tmp->getFilename();
  190.         }
  191.         // you can do this in SQL, but i guess the LISTING model does not allow this...
  192.         // SELECT latitude, longitude, SQRT(
  193.         //    POW(69.1 * (latitude - [startlat]), 2) +
  194.         //    POW(69.1 * ([startlng] - longitude) * COS(latitude / 57.3), 2)) AS distance
  195.         // FROM TableName HAVING distance < 25 ORDER BY distance;
  196.         $geo $event->getGeolocation() ? [$event->getGeolocation()->getLatitude(), $event->getGeolocation()->getLongitude()] : [];
  197.         $distance 0;
  198.         if (count($geo) > && $this->inputLat && $this->inputLon) {
  199.             $distance sqrt(
  200.                 pow(69.1 * ($geo[0] - $this->inputLat), 2) +
  201.                 pow(69.1 * ($this->inputLon $geo[1]) * cos($geo[0] / 57.3), 2)
  202.             );
  203.         }
  204.         $otherDates = [];
  205.         $otherDates[] = [
  206.             "dateStart" => $event->getDateStart(),
  207.             "dateEnd" => $event->getDateEnd()
  208.         ];
  209.         /** @var DataObject\Fieldcollection\Data\EventDates $otherDate */
  210.         if ($event->getOtherDates()) {
  211.             foreach ($event->getOtherDates() as $otherDate) {
  212.                 $otherDates[] = [
  213.                     "dateStart" => $otherDate->getDateStart(),
  214.                     "dateEnd" => $otherDate->getDateEnd()
  215.                 ];
  216.             }
  217.         }
  218.         return [
  219.             "id" => $event->getId(),
  220.             // content
  221.             "topic" => $event->getTopic(),
  222.             "title" => $event->getTitle(),
  223.             "text" => ''// $event->getText(),
  224.             "entry" => $event->getEntry(),
  225.             "link" => $event->getLink(),
  226.             // location
  227.             "dateStart" => $event->getDateStart(),
  228.             "dateEnd" => $event->getDateEnd(),
  229.             "city" => $event->getCity(),
  230.             "street" => $event->getStreet(),
  231.             "location_type" => $event->getLocation_type(),
  232.             "geolocation" => $geo,
  233.             "distance" => $distance,
  234.             // additional times
  235.             "otherDates" => $otherDates,
  236.             // media
  237.             "image" => $event->getImage()?->getThumbnail('image1x1')->getPath(),
  238.             "imageTitle" => $event->getImage()?->getMetadata('title''de') ?? '',
  239.             "imageCopyright" => $event->getImage()?->getMetadata('copyright''de') ?? '',
  240.             "imageGallery" => ($event->getImageGallery() && count($event->getImageGallery()->getItems())) ? $this->formatImageGallery($event->getImageGallery()) : null,
  241.             "video_preview" => $previewVideo,
  242.             "video" => $event->getVideo(),
  243.             // rest
  244.             "premium" => $event->getPremium() ? 2,
  245.             "userEvent" => $event->getUserEvent() ? 0,
  246.             "published" => $event->getPublished(),
  247.             "createdAt" => date("c"$event->getCreationDate()),
  248.             "updatedAt" => date("c"$event->getModificationDate()),
  249.             "url" => $link
  250.         ];
  251.     }
  252.     public function formatEvents($events) {
  253.         $data = [];
  254.         /**
  255.          * @var int $key
  256.          * @var DataObject\Event $event
  257.          */
  258.         foreach ($events as $key => $event) {
  259.             $data[] = $this->formatEvent($event);
  260.         }
  261.         return $data;
  262.     }
  263.     /**
  264.      * Calculates the great-circle distance between two points, with
  265.      * the Vincenty formula.
  266.      * @param float $latitudeFrom Latitude of start point in [deg decimal]
  267.      * @param float $longitudeFrom Longitude of start point in [deg decimal]
  268.      * @param float $latitudeTo Latitude of target point in [deg decimal]
  269.      * @param float $longitudeTo Longitude of target point in [deg decimal]
  270.      * @param float $earthRadius Mean earth radius in [m]
  271.      * @return float Distance between points in [m] (same as earthRadius)
  272.      */
  273.     public static function vincentyGreatCircleDistance(
  274.         $latitudeFrom$longitudeFrom$latitudeTo$longitudeTo$earthRadius 6371000)
  275.     {
  276.         // convert from degrees to radians
  277.         $latFrom deg2rad($latitudeFrom);
  278.         $lonFrom deg2rad($longitudeFrom);
  279.         $latTo deg2rad($latitudeTo);
  280.         $lonTo deg2rad($longitudeTo);
  281.         $lonDelta $lonTo $lonFrom;
  282.         $a pow(cos($latTo) * sin($lonDelta), 2) +
  283.             pow(cos($latFrom) * sin($latTo) - sin($latFrom) * cos($latTo) * cos($lonDelta), 2);
  284.         $b sin($latFrom) * sin($latTo) + cos($latFrom) * cos($latTo) * cos($lonDelta);
  285.         $angle atan2(sqrt($a), $b);
  286.         return $angle $earthRadius;
  287.     }
  288. }