<?php
namespace App\EventSubscriber;
use App\Controller\BaseController;
use App\Repository\EventRepository;
use App\Repository\TaskRepository;
use CalendarBundle\CalendarEvents;
use CalendarBundle\Entity\Event;
use CalendarBundle\Event\CalendarEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
class CalendarSubscriber implements EventSubscriberInterface
{
private $eventRepository;
private $router;
private $security;
private $user;
public function __construct(
EventRepository $eventRepository,
TaskRepository $taskRepository,
UrlGeneratorInterface $router,
Security $security,
BaseController $user
) {
$this->eventRepository = $eventRepository;
$this->taskRepository = $taskRepository;
$this->router = $router;
$this->security = $security;
$this->user = $user;
}
public static function getSubscribedEvents()
{
return [
CalendarEvents::SET_DATA => 'onCalendarSetData',
];
}
public function onCalendarSetData(CalendarEvent $calendar)
{
$start = $calendar->getStart();
$end = $calendar->getEnd();
$filters = $calendar->getFilters();
switch($filters['calendar-id']) {
case 'event-calendar':
$this->fillEventsCalendar($calendar, $start, $end, $filters);
break;
case 'task-calendar':
$this->fillTasksCalendar($calendar, $start, $end, $filters);
break;
}
}
public function fillEventsCalendar(CalendarEvent $calendar, \DateTimeInterface $start, \DateTimeInterface $end, array $filters) {
// Modify the query to fit to your entity and needs
// Change booking.beginAt by your start date property
if ($this->security->isGranted('ROLE_SUPERUSER') || $this->security->isGranted('ROLE_ADMINISTRATOR') || $this->security->isGranted('ROLE_CSO') || $this->security->isGranted('ROLE_PMM')) {
$events = $this->eventRepository
->createQueryBuilder('event')
->where('event.beginAt BETWEEN :start and :end OR event.endAt BETWEEN :start and :end')
->setParameter('start', $start->format('Y-m-d H:i:s'))
->setParameter('end', $end->format('Y-m-d H:i:s'))
->getQuery()
->getResult()
;
} else {
$events = $this->eventRepository
->createQueryBuilder('event')
->where('event.beginAt BETWEEN :start and :end OR event.endAt BETWEEN :start and :end')
->setParameter('start', $start->format('Y-m-d H:i:s'))
->setParameter('end', $end->format('Y-m-d H:i:s'))
->andwhere('event.user = :userid')
->setParameter('userid', $this->user->getId())
->getQuery()
->getResult()
;
}
foreach ($events as $event) {
// this create the events with your data (here booking data) to fill calendar
$bookingEvent = new Event(
$event->getDescription()." - ".$event->getNotes(),
$event->getBeginAt(),
$event->getEndAt()
// If the end date is null or not defined, a all day event is created.
);
switch ($event->getType()) {
case 'call':
$color = "#0d6efd";
break;
case 'interview':
$color = "#0dcaf0";
break;
case 'sale':
$color = "#28a745";
break;
default:
$color = "#0d6efd";
break;
}
/*
* Add custom options to events
*
* For more information see: https://fullcalendar.io/docs/event-object
* and: https://github.com/fullcalendar/fullcalendar/blob/master/src/core/options.ts
*/
$bookingEvent->setOptions([
'backgroundColor' => $color,
'borderColor' => $color,
'id'=>$event->getId(),
'startEditable' => true,
'useDetailPopup' => true,
'overlap'=>$event->getDescription(),
]);
$bookingEvent->addOption(
'url',
$this->router->generate('app_event_edit', [
'id' => $event->getId(),
])
);
// finally, add the event to the CalendarEvent to fill the calendar
$calendar->addEvent($bookingEvent);
}
}
public function fillTasksCalendar(CalendarEvent $calendar, \DateTimeInterface $start, \DateTimeInterface $end, array $filters) {
// Modify the query to fit to your entity and needs
// Change booking.beginAt by your start date property
if ($this->security->isGranted('ROLE_SUPERUSER') || $this->security->isGranted('ROLE_CSO') || $this->security->isGranted('ROLE_PMM') || $this->security->isGranted('ROLE_ADMINISTRATOR')) {
$tasks = $this->taskRepository
->createQueryBuilder('task')
->where('task.end BETWEEN :start and :endD')
->andWhere("task.status != 'STATUS_SUSPENDED'")
->setParameter('start', $start->format('Y-m-d H:i:s'))
->setParameter('endD', $end->format('Y-m-d H:i:s'))
->getQuery()
->getResult()
;
} else {
$tasks = $this->taskRepository
->createQueryBuilder('task')
->addSelect('user')
->innerJoin('task.strategists', 'user')
->where('user.id = :userid')
->setParameter('userid', $this->user->getId())
->andWhere('task.end BETWEEN :start and :endD')
->andWhere("task.status != 'STATUS_SUSPENDED'")
->setParameter('start', $start->format('Y-m-d H:i:s'))
->setParameter('endD', $end->format('Y-m-d H:i:s'))
->getQuery()
->getResult()
;
}
foreach ($tasks as $task) {
// this create the events with your data (here booking data) to fill calendar
$strategistsInfo = '';
foreach ($task->getStrategists() as $user) {
$strategistsInfo = $strategistsInfo." ".$user->getName().' '.$user->getSurname().'; ';
}
$bookingEvent = new Event(
$task->getName()." - ".$task->getDescription()." - ".$strategistsInfo,
$task->getStart(),
$task->getEnd()
// If the end date is null or not defined, a all day event is created.
);
switch ($task->getStatus()) {
case 'STATUS_ACTIVE':
$color = "#0d6efd";
break;
case 'STATUS_SUSPENDED':
$color = "#ffc107";
break;
case 'STATUS_DONE':
$color = "#198754";
break;
case 'STATUS_FAILED':
$color = "#dc3545";
break;
case 'STATUS_WAITING':
$color = "#ffc107";
break;
case 'STATUS_UNDEFINED':
$color = "#6c757d";
break;
default:
$color = "#0d6efd";
break;
}
/*
* Add custom options to events
*
* For more information see: https://fullcalendar.io/docs/event-object
* and: https://github.com/fullcalendar/fullcalendar/blob/master/src/core/options.ts
*/
$bookingEvent->setOptions([
'backgroundColor' => $color,
'borderColor' => $color,
'id'=>$task->getId(),
//'startEditable' => true,
'useDetailPopup' => true,
'overlap'=>$task->getDescription(),
]);
/*$bookingEvent->addOption(
'url',
$this->router->generate('app_event_edit', [
'id' => $task->getId(),
])
);*/
// finally, add the event to the CalendarEvent to fill the calendar
$calendar->addEvent($bookingEvent);
}
}
}