rewrite task list action

This commit is contained in:
Julien Fastré 2021-10-30 00:41:28 +02:00
parent c63b1015e1
commit e0cb5a88bd
4 changed files with 123 additions and 203 deletions

View File

@ -126,6 +126,7 @@ final class SingleTaskController extends AbstractController
}
$task->setPerson($person);
$role = TaskVoter::CREATE_PERSON;
break;
case 'course':
$course = $this->getDoctrine()->getManager()
@ -137,15 +138,16 @@ final class SingleTaskController extends AbstractController
}
$task->setCourse($course);
$role = TaskVoter::CREATE_COURSE;
break;
default:
return new BadRequestHttpException("context with {$entityType} is not supported");
}
$this->denyAccessUnlessGranted(TaskVoter::CREATE, $task, 'You are not '
$this->denyAccessUnlessGranted($role, $task, 'You are not '
. 'allowed to create this task');
$form = $this->setCreateForm($task, new Role(TaskVoter::CREATE));
$form = $this->setCreateForm($task, new Role($role));
$form->handleRequest($request);
@ -266,8 +268,8 @@ final class SingleTaskController extends AbstractController
$this->addFlash('success', $this->translator
->trans("The task has been updated"));
if ($person = $task->getContext() instanceof Person) {
$event = new PrivacyEvent($person, array(
if ($task->getContext() instanceof Person) {
$event = new PrivacyEvent($task->getPerson(), array(
'element_class' => SingleTask::class,
'element_id' => $task->getId(),
'action' => 'update'
@ -301,8 +303,8 @@ final class SingleTaskController extends AbstractController
return $event->getResponse();
}
if ($person = $task->getContext() instanceof Person) {
$event = new PrivacyEvent($person, array(
if ($task->getContext() instanceof Person) {
$event = new PrivacyEvent($task->getPerson(), array(
'element_class' => SingleTask::class,
'element_id' => $task->getId(),
'action' => 'edit'
@ -511,7 +513,7 @@ final class SingleTaskController extends AbstractController
* Arguments:
* - user_id
* - scope_id
* - course_id
* - s
* - person_id
* - hide_form (hide the form to filter the tasks)
* - status: date state, amongst SingleTaskRepository::DATE_STATUSES, or 'closed'
@ -522,212 +524,44 @@ final class SingleTaskController extends AbstractController
* )
*/
public function listAction(
PaginatorFactory $paginatorFactory,
SingleTaskRepository $taskRepository,
PersonRepository $personRepository,
AccompanyingPeriodRepository $courseRepository,
CenterRepository $centerRepository,
FormFactoryInterface $formFactory,
Request $request
) {
/* @var $viewParams array The parameters for the view */
/* @var $params array The parameters for the query */
$this->denyAccessUnlessGranted(TaskVoter::SHOW, null);
$viewParams['person'] = null;
$params['person'] = null;
$viewParams['user'] = null;
$params['user'] = null;
$viewParams['center'] = null;
$params['types'] = null;
$viewParams['accompanyingCourse'] = null;
$params['accompanyingCourse'] = null;
if (!empty($request->query->get('person_id', NULL))) {
$personId = $request->query->getInt('person_id', 0);
$person = $personRepository->find($personId);
if ($person === null) {
throw $this->createNotFoundException("This person ' $personId ' does not exist.");
}
$this->denyAccessUnlessGranted(PersonVoter::SEE, $person);
$viewParams['person'] = $person;
$params['person'] = $person;
}
if (!empty($request->query->get('course_id', NULL))) {
$courseId = $request->query->getInt('course_id', 0);
$course = $courseRepository->find($courseId);
if ($course === null) {
throw $this->createNotFoundException("This accompanying course ' $courseId ' does not exist.");
}
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $course);
$viewParams['accompanyingCourse'] = $course;
$params['accompanyingCourse'] = $course;
}
if (!empty($request->query->get('center_id', NULL))) {
$center = $centerRepository->find($request->query->getInt('center_id'));
if ($center === null) {
throw $this->createNotFoundException('center not found');
}
$params['center'] = $center;
}
if(!empty($request->query->get('types', []))) {
$types = $request->query->get('types', []);
if (count($types) > 0) {
$params['types'] = $types;
}
}
if (!empty($request->query->get('user_id', null))) {
if ($request->query->get('user_id') === '_unassigned') {
$params['unassigned'] = true;
} else {
$userId = $request->query->getInt('user_id', 0);
$user = $this->getDoctrine()->getManager()
->getRepository(User::class)
->find($userId);
if ($user === null) {
throw $this->createNotFoundException("This user ' $userId ' does not exist.");
}
$viewParams['user'] = $user;
$params['user'] = $user;
}
}
if (!empty($request->query->get('scope_id'))) {
$scopeId = $request->query->getInt('scope_id', 0);
$scope = $this->getDoctrine()->getManager()
->getRepository(Scope::class)
->find($scopeId);
if ($scope === null) {
throw $this->createNotFoundException("This scope' $scopeId 'does not exist.");
}
$viewParams['scope'] = $scope;
$params['scope'] = $scope;
}
$possibleStatuses = \array_merge(SingleTaskRepository::DATE_STATUSES, [ 'closed' ]);
$statuses = $request->query->get('status', $possibleStatuses);
$diff = \array_diff($statuses, $possibleStatuses);
if (count($diff) > 0) {
return new Response(
'date_status not allowed: '. \implode(', ', $diff),
Response::HTTP_BAD_REQUEST
$filterOrder = $this->buildFilterOrder();
$flags = \array_merge(
$filterOrder->getCheckboxData('status'),
\array_map(fn ($i) => 'state_'.$i, $filterOrder->getCheckboxData('states'))
);
}
$nb = $this->singleTaskAclAwareRepository->countByAllViewable(
$filterOrder->getQueryString(),
$flags
);
$paginator = $this->paginatorFactory->create($nb);
$viewParams['isSingleStatus'] = $singleStatus = count($statuses) === 1;
$tasks_count = 0;
foreach($statuses as $status) {
if($request->query->has('status')
&& FALSE === \in_array($status, $statuses)) {
continue;
}
if (in_array($status, SingleTaskRepository::DATE_STATUSES)) {
$params['date_status'] = $status;
$params['is_closed'] = false;
if (0 < $nb) {
$tasks = $this->singleTaskAclAwareRepository->findByAllViewable(
$filterOrder->getQueryString(),
$flags,
$paginator->getCurrentPageFirstItemNumber(),
$paginator->getItemsPerPage(),
[
'startDate' => 'DESC',
'endDate' => 'DESC',
]
);
} else {
$params['date_status'] = null;
$params['is_closed'] = true;
$tasks = [];
}
$count = $taskRepository
->countByParameters($params, $this->getUser())
;
$paginator = $paginatorFactory->create($count);
$viewParams['single_task_'.$status.'_count'] = $count;
$viewParams['single_task_'.$status.'_paginator'] = $paginator;
$viewParams['single_task_'.$status.'_tasks'] = $taskRepository
->findByParameters($params, $this->getUser(),
$singleStatus ? $paginator->getCurrentPage()->getFirstItemNumber() : 0,
$singleStatus ? $paginator->getItemsPerPage() : 10)
;
$tasks_count = $tasks_count + $count;
}
$viewParams['tasks_count'] = $tasks_count;
if ($viewParams['person'] !== null){
$viewParams['layout'] = '@ChillPerson/Person/layout.html.twig';
} else if ($viewParams['accompanyingCourse'] !== null){
$viewParams['layout'] = '@ChillPerson/AccompanyingCourse/layout.html.twig';
} else {
$viewParams['layout'] = '@ChillMain/layout.html.twig';
}
$form = $formFactory->createNamed(null, SingleTaskListType::class, null, [
'person' => $viewParams['person'],
'method' => Request::METHOD_GET,
'csrf_protection' => false,
'add_type' => true
return $this->render('@ChillTask/SingleTask/List/index.html.twig', [
'tasks' => $tasks,
'paginator' => $paginator,
'filter_order' => $filterOrder
]);
$form->handleRequest($request);
if (isset($person)) {
$event = new PrivacyEvent($person, array(
'element_class' => SingleTask::class,
'action' => 'list'
));
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
}
return $this->render('@ChillTask/SingleTask/index.html.twig',
array_merge($viewParams, [ 'form' => $form->createView() ]));
}
/*
protected function getPersonParam(EntityManagerInterface $em)
{
$person = $em->getRepository(Person::class)
->find($request->query->getInt('person_id'))
;
if (NULL === $person) {
throw $this->createNotFoundException('person not found');
}
$this->denyAccessUnlessGranted(PersonVoter::SEE, $person, "You are "
. "not allowed to see this person");
return $person;
}
protected function getUserParam(EntityManagerInterface $em)
{
$user = $em->getRepository(User::class)
->find($request->query->getInt('user_id'))
;
if (NULL === $user) {
throw $this->createNotFoundException('user not found');
}
return $user;
}
*/
/**
* Creates a form to delete a Task entity by id.
*

View File

@ -19,6 +19,10 @@ use Doctrine\Common\Collections\Collection;
* @ORM\Index(
* name="by_current_state",
* columns={ "current_states" }
* ),
* @ORM\Index(
* name="by_end_date",
* columns={ "end_date" }
* )
* }
* )

View File

@ -106,6 +106,31 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository
->getQuery()->getSingleScalarResult();
}
public function countByAllViewable(
?string $pattern = null,
?array $flags = []
): int {
$qb = $this->buildBaseQuery($pattern, $flags);
return $this
->addACLGlobal($qb)
->select('COUNT(t)')
->getQuery()->getSingleScalarResult();
}
public function findByAllViewable(
?string $pattern = null,
?array $flags = [],
?int $start = 0,
?int $limit = 50,
?array $orderBy = []
): array {
$qb = $this->buildBaseQuery($pattern, $flags);
$qb = $this->addACLGlobal($qb);
return $this->getResult($qb, $start, $limit, $orderBy);
}
public function buildQueryByCourse(
AccompanyingPeriod $course,
?string $pattern = null,
@ -175,6 +200,50 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository
->setParameter('scopes', $scopes);
}
private function addACLGlobal(
QueryBuilder $qb
): QueryBuilder {
$allowedCenters = $this->authorizationHelper
->getReachableCenters($this->security->getUser(), TaskVoter::SHOW);
if ([] === $allowedCenters) {
$qb
->andWhere($qb->expr()->lt('t.id', ':falseid'))
->setParameter('falseid', -1);
}
$qb->leftJoin('t.person', 'person')
->leftJoin('t.course', 'course')
->leftJoin('course.participations', 'participation')
->leftJoin('participation.person', 'person_p')
;
$qb->distinct(true);
$k = 0;
$orX = $qb->expr()->orX();
foreach ($allowedCenters as $center) {
$allowedScopes = $this->authorizationHelper->getReachableScopes($this->security->getUser(),
TaskVoter::SHOW, $center);
$and = $qb->expr()->andX(
$qb->expr()->orX(
$qb->expr()->eq('person.center', ':center_'.$k),
$qb->expr()->eq('person_p.center', ':center_'.$k)
),
$qb->expr()->in('t.circle', ':scopes_'.$k)
);
$qb
->setParameter('center_'.$k, $center)
->setParameter('scopes_'.$k, $allowedScopes);
$orX->add($and);
$k++;
}
$qb->andWhere($orX);
return $qb;
}
public function buildBaseQuery (
?string $pattern = null,
?array $flags = []

View File

@ -40,4 +40,17 @@ interface SingleTaskAclAwareRepositoryInterface
?string $pattern = null,
?array $flags = []
): int;
public function countByAllViewable(
?string $pattern = null,
?array $flags = []
): int;
public function findByAllViewable(
?string $pattern = null,
?array $flags = [],
?int $start = 0,
?int $limit = 50,
?array $orderBy = []
): array;
}