<?php
namespace App\Controller\Api;
use App\Controller\EventsDirectusController;
use App\Entity\EventsTag;
use App\Entity\Pages\EventsPage;
use Doctrine\Common\Collections\ArrayCollection;
use GuzzleHttp\Exception\RequestException;
use Jamel\CropperBundle\Service\Cropper;
use Kunstmaan\NodeBundle\Entity\NodeTranslation;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\Translation\TranslatorInterface;
use Welp\IcalBundle\Factory\Factory;
use Welp\IcalBundle\Response\CalendarResponse;
use GuzzleHttp\Client;
class EventsApiController extends AbstractController
{
/** @var Cropper $cropper */
private $cropper;
private $directusApiUrl;
private $directusUrl;
private $directusToken;
private $eventsDirectusController;
public function __construct(Cropper $cropper, TranslatorInterface $translator, EventsDirectusController $eventsDirectusController)
{
$this->cropper = $cropper;
$this->directusUrl = $translator->trans($_ENV['DIRECTUS_URL']);
$this->directusApiUrl = $translator->trans($_ENV['DIRECTUS_API_URL']);
$this->directusToken = $translator->trans($_ENV['DIRECTUS_API_TOKEN']);
$this->eventsDirectusController = $eventsDirectusController;
}
/**
* @Route("/api/events/ics", name="gcs_api_events_ics", methods={"GET"})
*/
public function getIcsAction(Request $request)
{
$eventId = $request->get('event_id');
if (!$eventId) {
return new Response('No id provided');
}
/** @var EventsPage $events */
$event = $this->getDoctrine()->getRepository(EventsPage::class)->getOneArticle(
$request->getLocale(),
null,
null,
null,
null,
null,
null,
null,
$eventId
);
if ($event) {
$calendar = $this->createCalendar($event);
return new CalendarResponse($calendar, 200);
}
return new Response('Wrong id');
}
/**
* @Route("/api/events", name="gcs_api_events_get", methods={"GET"})
*/
public function getEvents(Request $request)
{
$date = $this->getIfSet($request->get('date'));
$sports = $this->getIfSet($request->get('sports'));
$tags = $this->getIfSet($request->get('place'));
$gp = $this->getIfSet(filter_var($request->get('gp'), FILTER_VALIDATE_BOOLEAN));
$featured = $this->getIfSet(filter_var($request->get('featured'), FILTER_VALIDATE_BOOLEAN));
$sort = $this->getIfSet($request->get('sort'));
if (!$date) {
return new Response('No date provided');
}
/** @var EventsPage $events */
$events = $this->getDoctrine()->getRepository(EventsPage::class)->getFilteredArticles(
$request->getLocale(),
null,
null,
$sports,
$tags,
$gp,
$featured,
$date,
null,
$sort
);
;
return new JsonResponse(['events' => $this->iterateEvents($events, $date, $request)]);
}
/**
* @Route("/api/directusevents/ics", name="gcs_api_directus_events_ics", methods={"GET"})
*/
public function getDirectusIcsAction(Request $request)
{
$eventId = $request->get('event_id');
if (!$eventId) {
return new Response('No id provided');
}
$apiUrl = $this->directusApiUrl . '/gdynia-arena?events=' . $eventId;
$token = $this->directusToken;
$client = new Client();
$response = $client->post($apiUrl, [
'headers' => [
'ga-auth-token' => $token
],
]);
$responseData = $response->getBody()->getContents();
$apiData = json_decode($responseData, true);
$item = $apiData['data'][0];
if ($item) {
$calendar = $this->createDirectusCalendar($item);
return new CalendarResponse($calendar, 200);
}
return new Response('Wrong id');
}
/**
* @Route("/api/directusevents/{uri}", name="gcs_api_directus_events_get", methods={"GET"}, requirements={"uri"="[^/]+"})
*/
public function getDirectusEvents(Request $request, $uri)
{
$decodedUri = urldecode($uri);
$pathSegments = explode('/', $decodedUri);
$lastSegment = end($pathSegments) . '/';
$url = $this->directusUrl;
$date = $this->getIfSet($request->get('date'));
$req_disciplines = $this->getIfSet($request->get('sports'))[0];
$req_objects = $this->getIfSet($request->get('place'))[0];
$gp = $this->getIfSet(filter_var($request->get('gp'), FILTER_VALIDATE_BOOLEAN));
$featured = $this->getIfSet(filter_var($request->get('featured'), FILTER_VALIDATE_BOOLEAN));
$sort = $this->getIfSet($request->get('sort'));
if ($date) {
$formatDate = \DateTime::createFromFormat('d-m-Y', $date);
$date = $formatDate->format('Y-m-d');
}
$apiUrl = $this->directusApiUrl . '/gdynia-arena?start_date=' . $date;
if ($req_disciplines) {
$apiUrl = $apiUrl . '&disciplines=' . $req_disciplines;
}
if ($req_objects) {
$apiUrl = $apiUrl . '&objects=' . $req_objects;
}
if ($gp) {
$apiUrl = $apiUrl . '&gdynia_motion=true';
}
if ($featured) {
$apiUrl = $apiUrl . '&highlight=true';
}
if ($sort == 'alphabetical') {
$apiUrl = $apiUrl . '&sort=title';
}
$token = $this->directusToken;
$client = new Client();
try {
$response = $client->post($apiUrl, [
'headers' => [
'ga-auth-token' => $token,
]
]);
$responseData = $response->getBody()->getContents();
$apiData = json_decode($responseData, true);
$transformedData = [];
$countApiData = count($apiData['data']);
foreach ($apiData['data'] as $item) {
$sports = [];
if (isset($item['attributes']['disciplines']["data"]) && is_array($item['attributes']['disciplines']["data"])) {
foreach ($item['attributes']['disciplines']["data"] as $discipline) {
if (isset($discipline['attributes']['name'])) {
$sports[] = ['name' => $discipline['attributes']['name']];
}
}
}
$places = [];
if (isset($item['attributes']['objects']['data']) && is_array($item['attributes']['objects']['data'])) {
foreach ($item['attributes']['objects']['data'] as $object) {
if (isset($object['attributes']['name'])) {
$places[] = ['name' => $object['attributes']['name'], 'address' => $object['attributes']['address']];
}
}
}
$start_date = null;
$end_date = null;
if (isset($item['attributes']['dates']) && is_array($item['attributes']['dates'])) {
$count = count($item['attributes']['dates']);
if ($count > 0) {
$start_timestamp = strtotime($item['attributes']['dates'][0]['start_date']);
$end_timestamp = strtotime($item['attributes']['dates'][$count - 1]['end_date']);
$start_date = date('d.m.Y', $start_timestamp);
$end_date = date('d.m.Y', $end_timestamp);
}
}
$imageKey = ['background' => 'background', 'poster' => 'poster'];
if ($item['attributes']['publishedAt']) {
$imageKey = $this->eventsDirectusController->setImageKey($item['attributes']['publishedAt']);
}
$transformedItem = [
'id' => $item['id'],
'name' => $item['attributes']['title'],
'list_img_url' => $url . ($countApiData > 1 ?
$item['attributes'][$imageKey['poster']]['data']['attributes']['formats']['gcs-list']['url'] :
$item['attributes'][$imageKey['poster']]['data']['attributes']['url']),
'path' => $lastSegment . $item['attributes']['slug'],
'sports' => $sports,
'places' => $places,
'startDate' => $start_date,
'endDate' => $end_date,
'list_img_alt' => $item['attributes']['title'],
'sort' => $sort
];
$transformedData[] = $transformedItem;
}
if ($sort == 'date') {
$startDates = array_column($transformedData, "startDate");
array_multisort($startDates, SORT_ASC, $transformedData);
}
} catch (RequestException $e) {
$transformedData = [];
}
return new JsonResponse(['events' => $transformedData]);
}
private function createDirectusCalendar($item)
{
$atts = $item['attributes'];
$start_date = date($atts['dates'][0]['start_date']);
$start_date = new \DateTime($start_date);
if (isset($atts['dates']) && is_array($atts['dates'])) {
$count = count($atts['dates']);
if ($count > 0) {
$today = new \DateTime('today');
foreach ($atts['dates'] as $date) {
$row_date = new \DateTime($date["start_date"]);
if ($row_date >= $today) {
$start_date = $row_date;
break;
}
}
}
}
/** @var Factory $icalFactory */
$icalFactory = new Factory();
$calendar = $icalFactory->createCalendar();
$calendarEvent = $icalFactory->createCalendarEvent();
$calendarEvent->setStart($start_date)->setSummary($atts['title'])->setUid($item['id']);
$organizer = $icalFactory->createOrganizer();
$organizer->setName('Gdyńskie centrum sportu')->setLanguage('pl');
$locations = $atts['objects']['data'];
$locationsArray = [];
/**
* @var int $key
* @var EventsTag $location
*/
foreach ($locations as $key => $location) {
$location = $icalFactory->createLocation()->setLanguage('pl')->setName(
$location['attributes']['name'].', '.$location['attributes']['address']
);
$locationsArray[] = $location;
}
$calendarEvent->setLocations($locationsArray);
$calendarEvent->setOrganizer($organizer);
$calendar->addEvent($calendarEvent);
return $calendar;
}
private function createCalendar(EventsPage $event)
{
/** @var Factory $icalFactory */
$icalFactory = new Factory();
$calendar = $icalFactory->createCalendar();
$calendarEvent = $icalFactory->createCalendarEvent();
$calendarEvent->setStart($event->getDate())->setSummary($event->getTitle())->setUid($event->getId());
$organizer = $icalFactory->createOrganizer();
$organizer->setName('Gdyńskie centrum sportu')->setLanguage('pl');
$locations = $event->getTags();
$locationsArray = [];
/**
* @var int $key
* @var EventsTag $location
*/
foreach ($locations as $key => $location) {
$location = $icalFactory->createLocation()->setLanguage('pl')->setName(
$location->getName().', '.$location->getAddress()
);
$locationsArray[] = $location;
}
$calendarEvent->setLocations($locationsArray);
$calendarEvent->setOrganizer($organizer);
$calendar->addEvent($calendarEvent);
return $calendar;
}
private function iterateEvents($pages,$date, $request)
{
$array = [];
/** @var EventsPage $eventsPage */
foreach ($pages as $eventsPage) {
if ($eventsPage->getDateFrequency()->y == 0 && $eventsPage->getDateFrequency(
)->m == 0 && $eventsPage->getDateFrequency()->d == 0) {
$array[] = $this->eventArray($eventsPage, $request);
continue;
}
/** @var \DateTime $dateObject */
$dateObject = \DateTime::createFromFormat('d-m-Y G:i:s', $date." 00:00:00");
/** @var \DateTime $eventDate */
for (
$i = $eventsPage->getStartDate();
$i <= $eventsPage->getEndDate();
$i->add($eventsPage->getDateFrequency())
) {
if ($dateObject->format('d-m-Y') === $i->format('d-m-Y')) {
$array[] = $this->eventArray($eventsPage, $request);
}
}
}
return $array;
}
private function eventArray(EventsPage $page, Request $request)
{
$listImage = null;
$places = null;
$sports = null;
$tagObject = $page->getTags();
$sportObject = $page->getSports();
$listAlt = null;
$listImageObject = $page->getListImage();
if (!$listImageObject->isEmpty()) {
$listImage = $listImageObject->first()->getMedia()->getUrl();
$cropping = $listImageObject->first()->getCropping();
$listImage = $this->cropper->getCroppedImageSrc($listImage, $cropping, ['w' => 500]);
$listAlt = $listImageObject->first()->getMediaAlt();
}
if (!$tagObject->isEmpty()) {
foreach ($tagObject as $item) {
$places[] = [
'name' => $item->getName(),
'address' => $item->getAddress(),
];
}
}
if (!$sportObject->isEmpty()) {
foreach ($sportObject as $item) {
$sports[] = [
'name' => $item->getName(),
];
}
}
$nodeTranslationRepo = $this->getDoctrine()->getRepository(NodeTranslation::class);
/** @var NodeTranslation $nodeTranslation */
$nodeTranslation = $nodeTranslationRepo->getNodeTranslationFor($page);
return [
'id' => $page->getId(),
'name' => $nodeTranslation->getTitle(),
'list_img_url' => $listImage,
'path' => $request->getSchemeAndHttpHost().'/'.$request->getLocale().'/'.$nodeTranslation->getUrl(),
'places' => $places,
'sports' => $sports,
'startDate' => $page->getStartDate()->format('d.m.Y'),
'endDate' => $page->getEndDate()->format('d.m.Y'),
'list_img_alt' => $listAlt,
];
}
public function getIfSet($value, $default = null)
{
return $value ?? $default;
}
private function getAllDates(EventsPage $eventsPage)
{
}
}