mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-20 14:43:49 +00:00
Merge branch 'calendar/finalization' into calendar_changes
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\CalendarBundle\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class AdminController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* Calendar admin.
|
||||
*
|
||||
* @Route("/{_locale}/admin/calendar", name="chill_calendar_admin_index")
|
||||
*/
|
||||
public function indexAdminAction()
|
||||
{
|
||||
return $this->render('ChillCalendarBundle:Admin:index.html.twig');
|
||||
}
|
||||
}
|
@@ -13,17 +13,21 @@ namespace Chill\CalendarBundle\Controller;
|
||||
|
||||
use Chill\CalendarBundle\Entity\Calendar;
|
||||
use Chill\CalendarBundle\Form\CalendarType;
|
||||
use Chill\CalendarBundle\RemoteCalendar\Connector\RemoteCalendarConnectorInterface;
|
||||
use Chill\CalendarBundle\Repository\CalendarACLAwareRepositoryInterface;
|
||||
use Chill\CalendarBundle\Repository\CalendarRepository;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||
use Chill\MainBundle\Repository\UserRepository;
|
||||
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
|
||||
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use DateTimeImmutable;
|
||||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\Form\Form;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
@@ -35,32 +39,40 @@ use Symfony\Component\Serializer\SerializerInterface;
|
||||
|
||||
class CalendarController extends AbstractController
|
||||
{
|
||||
protected AuthorizationHelper $authorizationHelper;
|
||||
|
||||
protected EventDispatcherInterface $eventDispatcher;
|
||||
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
protected PaginatorFactory $paginator;
|
||||
|
||||
protected SerializerInterface $serializer;
|
||||
private CalendarACLAwareRepositoryInterface $calendarACLAwareRepository;
|
||||
|
||||
private CalendarRepository $calendarRepository;
|
||||
|
||||
private FilterOrderHelperFactoryInterface $filterOrderHelperFactory;
|
||||
|
||||
private LoggerInterface $logger;
|
||||
|
||||
private PaginatorFactory $paginator;
|
||||
|
||||
private RemoteCalendarConnectorInterface $remoteCalendarConnector;
|
||||
|
||||
private SerializerInterface $serializer;
|
||||
|
||||
private UserRepository $userRepository;
|
||||
|
||||
public function __construct(
|
||||
EventDispatcherInterface $eventDispatcher,
|
||||
AuthorizationHelper $authorizationHelper,
|
||||
CalendarRepository $calendarRepository,
|
||||
CalendarACLAwareRepositoryInterface $calendarACLAwareRepository,
|
||||
FilterOrderHelperFactoryInterface $filterOrderHelperFactory,
|
||||
LoggerInterface $logger,
|
||||
SerializerInterface $serializer,
|
||||
PaginatorFactory $paginator,
|
||||
CalendarRepository $calendarRepository
|
||||
RemoteCalendarConnectorInterface $remoteCalendarConnector,
|
||||
SerializerInterface $serializer,
|
||||
UserRepository $userRepository
|
||||
) {
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
$this->authorizationHelper = $authorizationHelper;
|
||||
$this->logger = $logger;
|
||||
$this->serializer = $serializer;
|
||||
$this->paginator = $paginator;
|
||||
$this->calendarRepository = $calendarRepository;
|
||||
$this->calendarACLAwareRepository = $calendarACLAwareRepository;
|
||||
$this->filterOrderHelperFactory = $filterOrderHelperFactory;
|
||||
$this->logger = $logger;
|
||||
$this->paginator = $paginator;
|
||||
$this->remoteCalendarConnector = $remoteCalendarConnector;
|
||||
$this->serializer = $serializer;
|
||||
$this->userRepository = $userRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,8 +139,12 @@ class CalendarController extends AbstractController
|
||||
*
|
||||
* @Route("/{_locale}/calendar/calendar/{id}/edit", name="chill_calendar_calendar_edit")
|
||||
*/
|
||||
public function editAction(int $id, Request $request): Response
|
||||
public function editAction(Calendar $entity, Request $request): Response
|
||||
{
|
||||
if (!$this->remoteCalendarConnector->isReady()) {
|
||||
return $this->remoteCalendarConnector->getMakeReadyResponse($request->getUri());
|
||||
}
|
||||
|
||||
$view = null;
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
|
||||
@@ -137,35 +153,28 @@ class CalendarController extends AbstractController
|
||||
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
|
||||
$view = '@ChillCalendar/Calendar/editByAccompanyingCourse.html.twig';
|
||||
} elseif ($user instanceof User) {
|
||||
throw new Exception('to analyze');
|
||||
$view = '@ChillCalendar/Calendar/editByUser.html.twig';
|
||||
}
|
||||
|
||||
$entity = $em->getRepository(\Chill\CalendarBundle\Entity\Calendar::class)->find($id);
|
||||
|
||||
if (!$entity) {
|
||||
throw $this->createNotFoundException('Unable to find Calendar entity.');
|
||||
}
|
||||
|
||||
$form = $this->createForm(CalendarType::class, $entity, [
|
||||
'accompanyingPeriod' => $accompanyingPeriod,
|
||||
])->handleRequest($request);
|
||||
$form = $this->createForm(CalendarType::class, $entity);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$em->persist($entity);
|
||||
$em->flush();
|
||||
|
||||
$this->addFlash('success', $this->get('translator')->trans('Success : calendar item updated!'));
|
||||
|
||||
$params = $this->buildParamsToUrl($user, $accompanyingPeriod);
|
||||
|
||||
return $this->redirectToRoute('chill_calendar_calendar_list', $params);
|
||||
return $this->redirectToRoute('chill_calendar_calendar_list_by_period', $params);
|
||||
}
|
||||
|
||||
if ($form->isSubmitted() && !$form->isValid()) {
|
||||
$this->addFlash('error', $this->get('translator')->trans('This form contains errors'));
|
||||
}
|
||||
|
||||
$deleteForm = $this->createDeleteForm($id, $user, $accompanyingPeriod);
|
||||
$deleteForm = $this->createDeleteForm($entity->getId(), $user, $accompanyingPeriod);
|
||||
|
||||
if (null === $view) {
|
||||
throw $this->createNotFoundException('Template not found');
|
||||
@@ -178,7 +187,7 @@ class CalendarController extends AbstractController
|
||||
'form' => $form->createView(),
|
||||
'delete_form' => $deleteForm->createView(),
|
||||
'accompanyingCourse' => $accompanyingPeriod,
|
||||
'user' => $user,
|
||||
// 'user' => $user,
|
||||
'entity_json' => $entity_array,
|
||||
]);
|
||||
}
|
||||
@@ -207,48 +216,31 @@ class CalendarController extends AbstractController
|
||||
/**
|
||||
* Lists all Calendar entities.
|
||||
*
|
||||
* @Route("/{_locale}/calendar/calendar/", name="chill_calendar_calendar_list")
|
||||
* @Route("/{_locale}/calendar/calendar/by-period/{id}", name="chill_calendar_calendar_list_by_period")
|
||||
*/
|
||||
public function listAction(Request $request): Response
|
||||
public function listActionByCourse(AccompanyingPeriod $accompanyingPeriod): Response
|
||||
{
|
||||
$view = null;
|
||||
$filterOrder = $this->buildListFilterOrder();
|
||||
['from' => $from, 'to' => $to] = $filterOrder->getDateRangeData('startDate');
|
||||
|
||||
[$user, $accompanyingPeriod] = $this->getEntity($request);
|
||||
$total = $this->calendarACLAwareRepository
|
||||
->countByAccompanyingPeriod($accompanyingPeriod, $from, $to);
|
||||
$paginator = $this->paginator->create($total);
|
||||
$calendarItems = $this->calendarACLAwareRepository->findByAccompanyingPeriod(
|
||||
$accompanyingPeriod,
|
||||
$from,
|
||||
$to,
|
||||
['startDate' => 'DESC'],
|
||||
$paginator->getCurrentPageFirstItemNumber(),
|
||||
$paginator->getItemsPerPage()
|
||||
);
|
||||
|
||||
/*
|
||||
dead code ?
|
||||
if ($user instanceof User) {
|
||||
$calendarItems = $this->calendarRepository->findByUser($user);
|
||||
|
||||
$view = '@ChillCalendar/Calendar/listByUser.html.twig';
|
||||
|
||||
return $this->render($view, [
|
||||
'calendarItems' => $calendarItems,
|
||||
'user' => $user,
|
||||
]);
|
||||
}
|
||||
*/
|
||||
|
||||
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
|
||||
$total = $this->calendarRepository->countByAccompanyingPeriod($accompanyingPeriod);
|
||||
$paginator = $this->paginator->create($total);
|
||||
$calendarItems = $this->calendarRepository->findBy(
|
||||
['accompanyingPeriod' => $accompanyingPeriod],
|
||||
['startDate' => 'DESC'],
|
||||
$paginator->getItemsPerPage(),
|
||||
$paginator->getCurrentPageFirstItemNumber()
|
||||
);
|
||||
|
||||
$view = '@ChillCalendar/Calendar/listByAccompanyingCourse.html.twig';
|
||||
|
||||
return $this->render($view, [
|
||||
'calendarItems' => $calendarItems,
|
||||
'accompanyingCourse' => $accompanyingPeriod,
|
||||
'paginator' => $paginator,
|
||||
]);
|
||||
}
|
||||
|
||||
throw new Exception('Unable to list actions.');
|
||||
return $this->render('@ChillCalendar/Calendar/listByAccompanyingCourse.html.twig', [
|
||||
'calendarItems' => $calendarItems,
|
||||
'accompanyingCourse' => $accompanyingPeriod,
|
||||
'paginator' => $paginator,
|
||||
'filterOrder' => $filterOrder,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -258,6 +250,10 @@ class CalendarController extends AbstractController
|
||||
*/
|
||||
public function newAction(Request $request): Response
|
||||
{
|
||||
if (!$this->remoteCalendarConnector->isReady()) {
|
||||
return $this->remoteCalendarConnector->getMakeReadyResponse($request->getUri());
|
||||
}
|
||||
|
||||
$view = null;
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
|
||||
@@ -271,8 +267,10 @@ class CalendarController extends AbstractController
|
||||
// }
|
||||
|
||||
$entity = new Calendar();
|
||||
$entity->setUser($this->getUser());
|
||||
$entity->setStatus($entity::STATUS_VALID);
|
||||
|
||||
if ($request->query->has('mainUser')) {
|
||||
$entity->setMainUser($this->userRepository->find($request->query->getInt('mainUser')));
|
||||
}
|
||||
|
||||
// if ($user instanceof User) {
|
||||
// $entity->setPerson($user);
|
||||
@@ -282,9 +280,8 @@ class CalendarController extends AbstractController
|
||||
$entity->setAccompanyingPeriod($accompanyingPeriod);
|
||||
}
|
||||
|
||||
$form = $this->createForm(CalendarType::class, $entity, [
|
||||
'accompanyingPeriod' => $accompanyingPeriod,
|
||||
])->handleRequest($request);
|
||||
$form = $this->createForm(CalendarType::class, $entity);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$em->persist($entity);
|
||||
@@ -294,7 +291,7 @@ class CalendarController extends AbstractController
|
||||
|
||||
$params = $this->buildParamsToUrl($user, $accompanyingPeriod);
|
||||
|
||||
return $this->redirectToRoute('chill_calendar_calendar_list', $params);
|
||||
return $this->redirectToRoute('chill_calendar_calendar_list_by_period', $params);
|
||||
}
|
||||
|
||||
if ($form->isSubmitted() && !$form->isValid()) {
|
||||
@@ -387,6 +384,14 @@ class CalendarController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
private function buildListFilterOrder(): FilterOrderHelper
|
||||
{
|
||||
$filterOrder = $this->filterOrderHelperFactory->create(self::class);
|
||||
$filterOrder->addDateRange('startDate', 'chill_calendar.start date filter', new DateTimeImmutable('3 days ago'), null);
|
||||
|
||||
return $filterOrder->build();
|
||||
}
|
||||
|
||||
private function buildParamsToUrl(?User $user, ?AccompanyingPeriod $accompanyingPeriod): array
|
||||
{
|
||||
$params = [];
|
||||
@@ -396,7 +401,7 @@ class CalendarController extends AbstractController
|
||||
}
|
||||
|
||||
if (null !== $accompanyingPeriod) {
|
||||
$params['accompanying_period_id'] = $accompanyingPeriod->getId();
|
||||
$params['id'] = $accompanyingPeriod->getId();
|
||||
}
|
||||
|
||||
return $params;
|
||||
|
@@ -11,58 +11,72 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\CalendarBundle\Controller;
|
||||
|
||||
use Chill\CalendarBundle\Repository\CalendarRangeRepository;
|
||||
use Chill\MainBundle\CRUD\Controller\ApiController;
|
||||
use DateTime;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Serializer\Model\Collection;
|
||||
use DateTimeImmutable;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
|
||||
use function count;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class CalendarRangeAPIController extends ApiController
|
||||
{
|
||||
/**
|
||||
* @Route("/api/1.0/calendar/calendar-range-available.{_format}", name="chill_api_single_calendar_range_available")
|
||||
*/
|
||||
public function availableRanges(Request $request, string $_format): JsonResponse
|
||||
private CalendarRangeRepository $calendarRangeRepository;
|
||||
|
||||
public function __construct(CalendarRangeRepository $calendarRangeRepository)
|
||||
{
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$this->calendarRangeRepository = $calendarRangeRepository;
|
||||
}
|
||||
|
||||
$sql = 'SELECT c FROM ChillCalendarBundle:CalendarRange c
|
||||
WHERE NOT EXISTS (SELECT cal.id FROM ChillCalendarBundle:Calendar cal WHERE cal.calendarRange = c.id)';
|
||||
/**
|
||||
* @Route("/api/1.0/calendar/calendar-range-available/{id}.{_format}",
|
||||
* name="chill_api_single_calendar_range_available",
|
||||
* requirements={"_format": "json"}
|
||||
* )
|
||||
*/
|
||||
public function availableRanges(User $user, Request $request, string $_format): JsonResponse
|
||||
{
|
||||
//return new JsonResponse(['ok' => true], 200, [], false);
|
||||
$this->denyAccessUnlessGranted('ROLE_USER');
|
||||
|
||||
if ($request->query->has('user')) {
|
||||
$user = $request->query->get('user');
|
||||
$sql = $sql . ' AND c.user = :user';
|
||||
$query = $em->createQuery($sql)
|
||||
->setParameter('user', $user);
|
||||
|
||||
if ($request->query->has('start') && $request->query->has('end')) {
|
||||
$startDate = $request->query->get('start');
|
||||
$endDate = $request->query->get('end');
|
||||
|
||||
$sql = $sql . ' AND c.startDate > :startDate AND c.endDate < :endDate';
|
||||
$query = $em ->createQuery($sql)
|
||||
->setParameter('startDate', $startDate)
|
||||
->setParameter('endDate', $endDate)
|
||||
->setParameter('user', $user);
|
||||
}
|
||||
|
||||
if($request->query->has('start') && !$request->query->has('end')) {
|
||||
$copyDate = $request->query->get('start');
|
||||
|
||||
$sql = $sql . ' AND DATE_DIFF(c.startDate, :copyDate) = 0';
|
||||
$query = $em ->createQuery($sql)
|
||||
->setParameter('copyDate', $copyDate)
|
||||
->setParameter('user', $user);
|
||||
}
|
||||
} else {
|
||||
$query = $em->createQuery($sql);
|
||||
if (!$request->query->has('dateFrom')) {
|
||||
throw new BadRequestHttpException('You must provide a dateFrom parameter');
|
||||
}
|
||||
$results = $query->getResult();
|
||||
|
||||
return $this->json(['count' => count($results), 'results' => $results], Response::HTTP_OK, [], ['groups' => ['read']]);
|
||||
//TODO use also the paginator, eg return $this->serializeCollection('get', $request, $_format, $paginator, $results);
|
||||
if (false === $dateFrom = DateTimeImmutable::createFromFormat(
|
||||
DateTimeImmutable::ATOM,
|
||||
$request->query->get('dateFrom')
|
||||
)) {
|
||||
throw new BadRequestHttpException('dateFrom not parsable');
|
||||
}
|
||||
|
||||
if (!$request->query->has('dateTo')) {
|
||||
throw new BadRequestHttpException('You must provide a dateTo parameter');
|
||||
}
|
||||
|
||||
if (false === $dateTo = DateTimeImmutable::createFromFormat(
|
||||
DateTimeImmutable::ATOM,
|
||||
$request->query->get('dateTo')
|
||||
)) {
|
||||
throw new BadRequestHttpException('dateTo not parsable');
|
||||
}
|
||||
|
||||
$total = $this->calendarRangeRepository->countByAvailableRangesForUser($user, $dateFrom, $dateTo);
|
||||
$paginator = $this->getPaginatorFactory()->create($total);
|
||||
$ranges = $this->calendarRangeRepository->findByAvailableRangesForUser(
|
||||
$user,
|
||||
$dateFrom,
|
||||
$dateTo,
|
||||
$paginator->getItemsPerPage(),
|
||||
$paginator->getCurrentPageFirstItemNumber()
|
||||
);
|
||||
|
||||
$collection = new Collection($ranges, $paginator);
|
||||
|
||||
return $this->json($collection, Response::HTTP_OK, [], ['groups' => ['read']]);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\CalendarBundle\Controller;
|
||||
|
||||
use Chill\MainBundle\CRUD\Controller\CRUDController;
|
||||
use Chill\MainBundle\Pagination\PaginatorInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class CancelReasonController extends CRUDController
|
||||
{
|
||||
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)
|
||||
{
|
||||
$query->addOrderBy('e.id', 'ASC');
|
||||
|
||||
return parent::orderQuery($action, $query, $request, $paginator);
|
||||
}
|
||||
}
|
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\CalendarBundle\Controller;
|
||||
|
||||
use Chill\CalendarBundle\Entity\Calendar;
|
||||
use Chill\CalendarBundle\Entity\Invite;
|
||||
use Chill\CalendarBundle\Messenger\Message\InviteUpdateMessage;
|
||||
use Chill\CalendarBundle\Security\Voter\InviteVoter;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
use Symfony\Component\Messenger\MessageBusInterface;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use function in_array;
|
||||
|
||||
class InviteApiController
|
||||
{
|
||||
private EntityManagerInterface $entityManager;
|
||||
|
||||
private MessageBusInterface $messageBus;
|
||||
|
||||
private Security $security;
|
||||
|
||||
public function __construct(EntityManagerInterface $entityManager, MessageBusInterface $messageBus, Security $security)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
$this->messageBus = $messageBus;
|
||||
$this->security = $security;
|
||||
}
|
||||
|
||||
/**
|
||||
* Give an answer to a calendar invite.
|
||||
*
|
||||
* @Route("/api/1.0/calendar/calendar/{id}/answer/{answer}.json", methods={"post"})
|
||||
*/
|
||||
public function answer(Calendar $calendar, string $answer): Response
|
||||
{
|
||||
$user = $this->security->getUser();
|
||||
|
||||
if (!$user instanceof User) {
|
||||
throw new AccessDeniedHttpException('not a regular user');
|
||||
}
|
||||
|
||||
if (null === $invite = $calendar->getInviteForUser($user)) {
|
||||
throw new AccessDeniedHttpException('not invited to this calendar');
|
||||
}
|
||||
|
||||
if (!$this->security->isGranted(InviteVoter::ANSWER, $invite)) {
|
||||
throw new AccessDeniedHttpException('not allowed to answer on this invitation');
|
||||
}
|
||||
|
||||
if (!in_array($answer, Invite::STATUSES, true)) {
|
||||
throw new BadRequestHttpException('answer not valid');
|
||||
}
|
||||
|
||||
$invite->setStatus($answer);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->messageBus->dispatch(new InviteUpdateMessage($invite, $this->security->getUser()));
|
||||
|
||||
return new JsonResponse(null, Response::HTTP_ACCEPTED, [], false);
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\CalendarBundle\Controller;
|
||||
|
||||
use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\OnBehalfOfUserTokenStorage;
|
||||
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
|
||||
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use TheNetworg\OAuth2\Client\Provider\Azure;
|
||||
use TheNetworg\OAuth2\Client\Token\AccessToken;
|
||||
|
||||
class RemoteCalendarConnectAzureController
|
||||
{
|
||||
private ClientRegistry $clientRegistry;
|
||||
|
||||
private OnBehalfOfUserTokenStorage $MSGraphTokenStorage;
|
||||
|
||||
public function __construct(
|
||||
ClientRegistry $clientRegistry,
|
||||
OnBehalfOfUserTokenStorage $MSGraphTokenStorage
|
||||
) {
|
||||
$this->clientRegistry = $clientRegistry;
|
||||
$this->MSGraphTokenStorage = $MSGraphTokenStorage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{_locale}/connect/azure", name="chill_calendar_remote_connect_azure")
|
||||
*/
|
||||
public function connectAzure(Request $request): Response
|
||||
{
|
||||
$request->getSession()->set('azure_return_path', $request->query->get('returnPath', '/'));
|
||||
|
||||
return $this->clientRegistry
|
||||
->getClient('azure') // key used in config/packages/knpu_oauth2_client.yaml
|
||||
->redirect(['https://graph.microsoft.com/.default', 'offline_access'], []);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/connect/azure/check", name="chill_calendar_remote_connect_azure_check")
|
||||
*/
|
||||
public function connectAzureCheck(Request $request): Response
|
||||
{
|
||||
/** @var Azure $client */
|
||||
$client = $this->clientRegistry->getClient('azure');
|
||||
|
||||
try {
|
||||
/** @var AccessToken $token */
|
||||
$token = $client->getAccessToken([]);
|
||||
|
||||
$this->MSGraphTokenStorage->setToken($token);
|
||||
} catch (IdentityProviderException $e) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return new RedirectResponse($request->getSession()->remove('azure_return_path', '/'));
|
||||
}
|
||||
}
|
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\CalendarBundle\Controller;
|
||||
|
||||
use Chill\CalendarBundle\Messenger\Message\MSGraphChangeNotificationMessage;
|
||||
use JsonException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
use Symfony\Component\Messenger\MessageBusInterface;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use const JSON_THROW_ON_ERROR;
|
||||
|
||||
class RemoteCalendarMSGraphSyncController
|
||||
{
|
||||
private MessageBusInterface $messageBus;
|
||||
|
||||
public function __construct(MessageBusInterface $messageBus)
|
||||
{
|
||||
$this->messageBus = $messageBus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/public/incoming-hook/calendar/msgraph/events/{userId}", name="chill_calendar_remote_msgraph_incoming_webhook_events",
|
||||
* methods={"POST"})
|
||||
*/
|
||||
public function webhookCalendarReceiver(int $userId, Request $request): Response
|
||||
{
|
||||
if ($request->query->has('validationToken')) {
|
||||
return new Response($request->query->get('validationToken'), Response::HTTP_OK, [
|
||||
'content-type' => 'text/plain',
|
||||
]);
|
||||
}
|
||||
|
||||
try {
|
||||
$body = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR);
|
||||
} catch (JsonException $e) {
|
||||
throw new BadRequestHttpException('could not decode json', $e);
|
||||
}
|
||||
|
||||
$this->messageBus->dispatch(new MSGraphChangeNotificationMessage($body, $userId));
|
||||
|
||||
return new Response('', Response::HTTP_ACCEPTED);
|
||||
}
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\CalendarBundle\Controller;
|
||||
|
||||
use Chill\CalendarBundle\RemoteCalendar\Connector\RemoteCalendarConnectorInterface;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||
use Chill\MainBundle\Serializer\Model\Collection;
|
||||
use DateTimeImmutable;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use function count;
|
||||
|
||||
/**
|
||||
* Contains method to get events (Calendar) from remote calendar.
|
||||
*/
|
||||
class RemoteCalendarProxyController
|
||||
{
|
||||
private PaginatorFactory $paginatorFactory;
|
||||
|
||||
private RemoteCalendarConnectorInterface $remoteCalendarConnector;
|
||||
|
||||
private SerializerInterface $serializer;
|
||||
|
||||
public function __construct(PaginatorFactory $paginatorFactory, RemoteCalendarConnectorInterface $remoteCalendarConnector, SerializerInterface $serializer)
|
||||
{
|
||||
$this->paginatorFactory = $paginatorFactory;
|
||||
$this->remoteCalendarConnector = $remoteCalendarConnector;
|
||||
$this->serializer = $serializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("api/1.0/calendar/proxy/calendar/by-user/{id}/events")
|
||||
*/
|
||||
public function listEventForCalendar(User $user, Request $request): Response
|
||||
{
|
||||
if (!$request->query->has('dateFrom')) {
|
||||
throw new BadRequestHttpException('You must provide a dateFrom parameter');
|
||||
}
|
||||
|
||||
if (false === $dateFrom = DateTimeImmutable::createFromFormat(
|
||||
DateTimeImmutable::ATOM,
|
||||
$request->query->get('dateFrom')
|
||||
)) {
|
||||
throw new BadRequestHttpException('dateFrom not parsable');
|
||||
}
|
||||
|
||||
if (!$request->query->has('dateTo')) {
|
||||
throw new BadRequestHttpException('You must provide a dateTo parameter');
|
||||
}
|
||||
|
||||
if (false === $dateTo = DateTimeImmutable::createFromFormat(
|
||||
DateTimeImmutable::ATOM,
|
||||
$request->query->get('dateTo')
|
||||
)) {
|
||||
throw new BadRequestHttpException('dateTo not parsable');
|
||||
}
|
||||
|
||||
$events = $this->remoteCalendarConnector->listEventsForUser($user, $dateFrom, $dateTo);
|
||||
$paginator = $this->paginatorFactory->create(count($events));
|
||||
|
||||
if (count($events) > 0) {
|
||||
$paginator->setItemsPerPage($paginator->getTotalItems());
|
||||
}
|
||||
|
||||
$collection = new Collection($events, $paginator);
|
||||
|
||||
return new JsonResponse(
|
||||
$this->serializer->serialize($collection, 'json', ['groups' => ['read']]),
|
||||
JsonResponse::HTTP_OK,
|
||||
[],
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user