<?php
declare(strict_types=1);
namespace Domain\EventSubscriber;
use CalendarBundle\CalendarEvents;
use CalendarBundle\Entity\Event;
use CalendarBundle\Event\CalendarEvent;
use Domain\Repository\LogEntryRepositoryInterface;
use Infrastructure\Persistence\Doctrine\Entity\LogEntry;
use Infrastructure\Persistence\Doctrine\Entity\User;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
final class LogbookEventSubscriber implements EventSubscriberInterface
{
private const COLOR_BLUE = '#007bff';
private LogEntryRepositoryInterface $logEntryRepository;
private UrlGeneratorInterface $urlGenerator;
private TokenStorageInterface $tokenStorage;
private RequestStack $requestStack;
private LoggerInterface $logger;
public function __construct(
LogEntryRepositoryInterface $logEntryRepository,
UrlGeneratorInterface $urlGenerator,
TokenStorageInterface $tokenStorage,
RequestStack $requestStack,
LoggerInterface $logger
) {
$this->logEntryRepository = $logEntryRepository;
$this->urlGenerator = $urlGenerator;
$this->tokenStorage = $tokenStorage;
$this->requestStack = $requestStack;
$this->logger = $logger;
}
public static function getSubscribedEvents(): array
{
return [
CalendarEvents::SET_DATA => 'onCalendarSetData',
];
}
public function onCalendarSetData(CalendarEvent $calendar)
{
$start = $calendar->getStart();
$end = $calendar->getEnd();
$filters = $calendar->getFilters();
// You may want to make a custom query from your database to fill the calendar
/** @var User $currentUser */
$currentUser = $this->tokenStorage->getToken()->getUser();
$logEntries = $this->fetchLogEntries($currentUser, $start, $end, $filters['companyId'] ?? null);
array_map(function (LogEntry $logEntry) use ($calendar) {
$colorOfLogEntry = $this->colorizeLogEntry($logEntry);
$calendar->addEvent(new Event(
sprintf('%s: %s', $logEntry->getUser()->getFullName(), $logEntry->getText()),
$logEntry->getCreatedAt(),
$logEntry->getCreatedAt(),
[
'backgroundColor' => $colorOfLogEntry,
'borderColor' => $colorOfLogEntry,
'textColor' => 'white',
'url' => $this->urlGenerator->generate('fetch_logentry_for_company', [
'companyId' => $logEntry->getCompany()->getId(),
'logEntryId' => $logEntry->getId(),
]),
]
));
}, $logEntries);
}
private function colorizeLogEntry(LogEntry $logEntry): string
{
if (!$logEntry->isCommentedAndLocked() && $logEntry->getUser()->isClient()) {
return 'orange';
}
if ($logEntry->isCommentedAndLocked()) {
return 'lightgrey';
}
return self::COLOR_BLUE;
}
public function fetchLogEntries(User $currentUser, \DateTimeInterface $start, \DateTimeInterface $end, ?int $companyId = null): array
{
if ($currentUser->isClient() || $currentUser->isCleaner()) {
return $this->logEntryRepository->byCompanyId($currentUser->getCompany()->getId());
}
if (\is_int($companyId) && $currentUser->isManager()) {
return $this->logEntryRepository->allInGivenMonthForCompany($start, $end, $companyId);
}
if (null === $companyId && $currentUser->isManager()) {
return $this->logEntryRepository->allInCurrentMonth();
}
return [];
}
}