Skip to content

Commit

Permalink
[Training] enhances presences
Browse files Browse the repository at this point in the history
  • Loading branch information
Elorfin committed Feb 28, 2024
1 parent 09bac91 commit 313b495
Show file tree
Hide file tree
Showing 75 changed files with 1,317 additions and 568 deletions.
1 change: 1 addition & 0 deletions src/main/app/Resources/styles/_utilities.scss
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
margin-right: -$grid-gutter-width*.5; // to escape the page-content container-fluid
flex: 1 0 auto;
display: flex;
flex-direction: column;
}

// Cursors
Expand Down
18 changes: 4 additions & 14 deletions src/plugin/cursus/Controller/EventController.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,14 @@ class EventController extends AbstractCrudController
{
use PermissionCheckerTrait;

private TokenStorageInterface $tokenStorage;
private TranslatorInterface $translator;
private EventManager $manager;
private PdfManager $pdfManager;

public function __construct(
AuthorizationCheckerInterface $authorization,
TokenStorageInterface $tokenStorage,
TranslatorInterface $translator,
EventManager $manager,
PdfManager $pdfManager
private readonly TokenStorageInterface $tokenStorage,
private readonly TranslatorInterface $translator,
private readonly EventManager $manager,
private readonly PdfManager $pdfManager
) {
$this->authorization = $authorization;
$this->tokenStorage = $tokenStorage;
$this->translator = $translator;
$this->manager = $manager;
$this->pdfManager = $pdfManager;
}

public function getName(): string
Expand Down Expand Up @@ -128,7 +119,6 @@ public function listPublicAction(Request $request, Workspace $workspace = null):
$query = $request->query->all();
$query['hiddenFilters'] = $this->getDefaultHiddenFilters();
$query['hiddenFilters']['registrationType'] = Session::REGISTRATION_PUBLIC;
$query['hiddenFilters']['terminated'] = false;
if ($workspace) {
$query['hiddenFilters']['workspace'] = $workspace->getUuid();
}
Expand Down
65 changes: 50 additions & 15 deletions src/plugin/cursus/Controller/EventPresenceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
use Claroline\AppBundle\Controller\RequestDecoderTrait;
use Claroline\AppBundle\Manager\PdfManager;
use Claroline\AppBundle\Persistence\ObjectManager;
use Claroline\CoreBundle\Entity\User;
use Claroline\CoreBundle\Entity\Workspace\Workspace;
use Claroline\CoreBundle\Library\Normalizer\TextNormalizer;
use Claroline\CoreBundle\Security\PermissionCheckerTrait;
use Claroline\CoreBundle\Security\ToolPermissions;
use Claroline\CursusBundle\Component\Tool\TrainingEventsTool;
use Claroline\CursusBundle\Entity\Event;
use Claroline\CursusBundle\Entity\EventPresence;
use Claroline\CursusBundle\Manager\EventManager;
Expand All @@ -29,6 +31,7 @@
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

/**
* @Route("/cursus_event_presence")
Expand Down Expand Up @@ -73,17 +76,50 @@ public function listAction(Event $event, Request $request): JsonResponse
}

/**
* Updates the status of an EventPresence list.
* @Route("/workspace/{id}", name="apiv2_cursus_workspace_presence_list", methods={"GET"})
*
* @Route("/{id}/{status}", name="apiv2_cursus_event_presence_update", methods={"PUT"})
* @EXT\ParamConverter("workspace", class="Claroline\CoreBundle\Entity\Workspace\Workspace", options={"mapping": {"id": "uuid"}})
*/
public function listByWorkspaceAction(Workspace $workspace, Request $request): JsonResponse
{
$isManager = $this->checkPermission(ToolPermissions::getPermission(TrainingEventsTool::getName(), 'EDIT'), $workspace, [])
|| $this->checkPermission(ToolPermissions::getPermission(TrainingEventsTool::getName(), 'REGISTER'), $workspace, []);

if (!$isManager) {
throw new AccessDeniedException();
}

$params = $request->query->all();
$params['hiddenFilters'] = [
'workspace' => $workspace->getUuid(),
];

return new JsonResponse(
$this->finder->search(EventPresence::class, $params)
);
}

/**
* Updates the status of an EventPresence list.
*
* @EXT\ParamConverter("event", class="Claroline\CursusBundle\Entity\Event", options={"mapping": {"id": "uuid"}})
* @Route("/status/{status}", name="apiv2_cursus_event_presence_update", methods={"PUT"})
*/
public function updateStatusAction(Event $event, string $status, Request $request): JsonResponse
public function updateStatusAction(string $status, Request $request): JsonResponse
{
$this->checkPermission('EDIT', $event, [], true);
$data = $this->decodeRequest($request);
if (empty($data)) {
return new JsonResponse(null, 404);
}

$presences = $this->om->getRepository(EventPresence::class)->findBy(['uuid' => $data]);
$this->om->startFlushSuite();
foreach ($presences as $presence) {
$this->checkPermission('EDIT', $presence, [], true);

$this->manager->setStatus([$presence], $status);
}

$presences = $this->manager->setStatus($this->decodeIdsString($request, EventPresence::class), $status);
$this->om->endFlushSuite();

return new JsonResponse(array_map(function (EventPresence $presence) {
return $this->serializer->serialize($presence);
Expand All @@ -110,22 +146,21 @@ public function downloadPdfAction(Event $event, Request $request, int $filled):
}

/**
* @Route("/{id}/user/{userId}/download", name="apiv2_cursus_user_presence_download", methods={"GET"})
* @Route("/{id}/pdf", name="apiv2_cursus_user_presence_download", methods={"GET"})
*
* @EXT\ParamConverter("event", class="Claroline\CursusBundle\Entity\Event", options={"mapping": {"id": "uuid"}})
* @EXT\ParamConverter("user", class="Claroline\CoreBundle\Entity\User", options={"mapping": {"userId": "uuid"}})
* @EXT\ParamConverter("eventPresence", class="Claroline\CursusBundle\Entity\EventPresence", options={"mapping": {"id": "uuid"}})
*/
public function downloadUserPdfAction(Event $event, User $user, Request $request): StreamedResponse
public function downloadUserPdfAction(EventPresence $eventPresence, Request $request): StreamedResponse
{
$this->checkPermission('EDIT', $event, [], true);
$this->checkPermission('OPEN', $eventPresence, [], true);

return new StreamedResponse(function () use ($event, $request, $user) {
return new StreamedResponse(function () use ($eventPresence, $request) {
echo $this->pdfManager->fromHtml(
$this->manager->downloadUser($event, $request->getLocale(), $user)
$this->manager->downloadUser($eventPresence, $request->getLocale())
);
}, 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename='.TextNormalizer::toKey($event->getName()).'-presence.pdf',
'Content-Disposition' => 'attachment; filename='.TextNormalizer::toKey($eventPresence->getEvent()->getName()).'-presence.pdf',
]);
}
}
30 changes: 2 additions & 28 deletions src/plugin/cursus/Controller/User/EventController.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ public function __construct(
/**
* List the active (in progress and forthcoming) session events of the current user.
*
* @Route("/active/{workspace}", name="apiv2_cursus_my_events_active", methods={"GET"})
* @Route("/{workspace}", name="apiv2_cursus_my_events", methods={"GET"})
*
* @EXT\ParamConverter("workspace", class="Claroline\CoreBundle\Entity\Workspace\Workspace", options={"mapping": {"workspace": "uuid"}})
*/
public function listActiveAction(Request $request, Workspace $workspace = null): JsonResponse
public function listAction(Request $request, Workspace $workspace = null): JsonResponse
{
if (!$this->authorization->isGranted('IS_AUTHENTICATED_FULLY')) {
throw new AccessDeniedException();
Expand All @@ -52,30 +52,4 @@ public function listActiveAction(Request $request, Workspace $workspace = null):
$this->finder->search(Event::class, $params)
);
}

/**
* List the ended session events of the current user.
*
* @Route("/ended/{workspace}", name="apiv2_cursus_my_events_ended", methods={"GET"})
*
* @EXT\ParamConverter("workspace", class="Claroline\CoreBundle\Entity\Workspace\Workspace", options={"mapping": {"workspace": "uuid"}})
*/
public function listEndedAction(Request $request, Workspace $workspace = null): JsonResponse
{
if (!$this->authorization->isGranted('IS_AUTHENTICATED_FULLY')) {
throw new AccessDeniedException();
}

$params = $request->query->all();
$params['hiddenFilters'] = [];
$params['hiddenFilters']['user'] = $this->tokenStorage->getToken()->getUser()->getUuid();
$params['hiddenFilters']['terminated'] = true;
if ($workspace) {
$params['hiddenFilters']['workspace'] = $workspace->getUuid();
}

return new JsonResponse(
$this->finder->search(Event::class, $params)
);
}
}
62 changes: 60 additions & 2 deletions src/plugin/cursus/Finder/EventPresenceFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ public static function getClass(): string

public function configureQueryBuilder(QueryBuilder $qb, array $searches = [], array $sortBy = null, ?int $page = 0, ?int $limit = -1): QueryBuilder
{
$eventJoin = false;
$userJoin = false;
$sessionJoin = false;

if (!array_key_exists('user', $searches)) {
$qb->join('obj.user', 'u');
$userJoin = true;
Expand All @@ -39,8 +42,12 @@ public function configureQueryBuilder(QueryBuilder $qb, array $searches = [], ar
foreach ($searches as $filterName => $filterValue) {
switch ($filterName) {
case 'event':
$qb->join('obj.event', 'se');
$qb->andWhere("se.uuid = :{$filterName}");
if (!$eventJoin) {
$qb->join('obj.event', 'e');
$eventJoin = true;
}

$qb->andWhere("e.uuid = :{$filterName}");
$qb->setParameter($filterName, $filterValue);
break;

Expand All @@ -54,6 +61,38 @@ public function configureQueryBuilder(QueryBuilder $qb, array $searches = [], ar
$qb->setParameter($filterName, $filterValue);
break;

case 'session':
if (!$eventJoin) {
$qb->join('obj.event', 'e');
$eventJoin = true;
}

if (!$sessionJoin) {
$qb->join('e.session', 's');
$sessionJoin = true;
}

$qb->andWhere("s.uuid = :{$filterName}");
$qb->setParameter($filterName, $filterValue);
break;

case 'workspace':
if (!$eventJoin) {
$qb->join('obj.event', 'e');
$eventJoin = true;
}

if (!$sessionJoin) {
$qb->join('e.session', 's');
$sessionJoin = true;
}

$qb->join('s.workspace', 'w');
$qb->andWhere("w.uuid = :{$filterName}");

$qb->setParameter($filterName, $filterValue);
break;

default:
$this->setDefaults($qb, $filterName, $filterValue);
}
Expand All @@ -70,6 +109,25 @@ public function configureQueryBuilder(QueryBuilder $qb, array $searches = [], ar
}
$qb->orderBy('u.lastName, u.firstName', $sortByDirection);
break;

case 'session':
if (!$sessionJoin) {
$qb->join('e.session', 's');
}
$qb->orderBy('s.name', $sortByDirection);
break;

case 'event':
if (!$eventJoin) {
$qb->join('obj.event', 'e');
}

if (!$sessionJoin) {
$qb->join('e.session', 's');
}

$qb->orderBy('e.name', $sortByDirection);
break;
}
}

Expand Down
25 changes: 15 additions & 10 deletions src/plugin/cursus/Manager/EventManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
use Claroline\CursusBundle\Repository\Registration\EventUserRepository;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

/**
* @todo use Crud to manage registrations
*/
class EventManager
{
private EventUserRepository $eventUserRepo;
Expand Down Expand Up @@ -81,7 +84,6 @@ public function addUsers(Event $event, array $users, string $type = AbstractRegi
$eventUser->setEvent($event);
$eventUser->setUser($user);

// TODO : use CRUD
$eventUser->setType($type);
$eventUser->setDate($registrationDate);
// no validation for events
Expand All @@ -103,6 +105,9 @@ public function addUsers(Event $event, array $users, string $type = AbstractRegi
}, $results));
}

// initialize presences
$this->presenceManager->generate($event, $users);

$this->om->endFlushSuite();

return $results;
Expand All @@ -115,7 +120,6 @@ public function removeUsers(Event $event, array $eventUsers): void
{
$this->om->startFlushSuite();

// TODO : use CRUD
foreach ($eventUsers as $eventUser) {
$this->om->remove($eventUser);

Expand Down Expand Up @@ -160,7 +164,6 @@ public function addGroups(Event $event, array $groups, string $type = AbstractRe
if (empty($eventGroup)) {
$eventGroup = new EventGroup();

// TODO : use CRUD
$eventGroup->setEvent($event);
$eventGroup->setGroup($group);
$eventGroup->setType($type);
Expand All @@ -183,6 +186,9 @@ public function addGroups(Event $event, array $groups, string $type = AbstractRe
$this->sendSessionEventInvitation($event, $users);
}

// initialize presences
$this->presenceManager->generate($event, $users);

$this->om->endFlushSuite();

return $results;
Expand All @@ -195,7 +201,6 @@ public function removeGroups(Event $event, array $eventGroups): void
{
$this->om->startFlushSuite();

// TODO : use CRUD
foreach ($eventGroups as $eventGroup) {
$this->om->remove($eventGroup);

Expand Down Expand Up @@ -315,27 +320,27 @@ public function getICS(Event $event, bool $toFile = false): string
public function getRegisteredUsers(Event $event): array
{
/** @var EventUser[] $sessionLearners */
$sessionLearners = $this->eventUserRepo->findBy([
$eventLearners = $this->eventUserRepo->findBy([
'event' => $event,
'type' => AbstractRegistration::LEARNER,
'validated' => true,
]);

/** @var EventGroup[] $sessionGroups */
$sessionGroups = $this->eventGroupRepo->findBy([
$eventGroups = $this->eventGroupRepo->findBy([
'event' => $event,
'type' => AbstractRegistration::LEARNER,
]);

$users = [];

foreach ($sessionLearners as $sessionLearner) {
$user = $sessionLearner->getUser();
foreach ($eventLearners as $eventLearner) {
$user = $eventLearner->getUser();
$users[$user->getUuid()] = $user;
}

foreach ($sessionGroups as $sessionGroup) {
$group = $sessionGroup->getGroup();
foreach ($eventGroups as $eventGroup) {
$group = $eventGroup->getGroup();
$groupUsers = $group->getUsers();

foreach ($groupUsers as $user) {
Expand Down
Loading

0 comments on commit 313b495

Please sign in to comment.