diff --git a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php index b11601589..90ec16ec3 100644 --- a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php +++ b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php @@ -472,7 +472,11 @@ final class SingleTaskController extends AbstractController $filterOrder->getQueryString(), $flags, $paginator->getCurrentPageFirstItemNumber(), - $paginator->getItemsPerPage() + $paginator->getItemsPerPage(), + [ + 'startDate' => 'DESC', + 'endDate' => 'DESC', + ] ); return $this->render('@ChillTask/SingleTask/List/index.html.twig', [ @@ -694,6 +698,7 @@ final class SingleTaskController extends AbstractController } + /* protected function getPersonParam(EntityManagerInterface $em) { $person = $em->getRepository(Person::class) @@ -722,6 +727,7 @@ final class SingleTaskController extends AbstractController return $user; } + */ /** * Creates a form to delete a Task entity by id. @@ -750,34 +756,40 @@ final class SingleTaskController extends AbstractController public function listCourseTasks( AccompanyingPeriod $course, - SingleTaskRepository $taskRepository, FormFactoryInterface $formFactory, Request $request ): Response { - - $em = $this->getDoctrine()->getManager(); - - $tasks = $taskRepository - ->findBy( - array('course' => $course) - ); - - $form = $formFactory->createNamed(null, SingleTaskListType::class, null, [ - 'accompanyingCourse' => $course, - 'method' => Request::METHOD_GET, - 'csrf_protection' => false, - 'add_type' => true - ]); + $filterOrder = $this->buildFilterOrder(); + $flags = \array_merge( + $filterOrder->getCheckboxData('status'), + \array_map(fn ($i) => 'state_'.$i, $filterOrder->getCheckboxData('states')) + ); + $nb = $this->singleTaskAclAwareRepository->countByCourse( + $course, + $filterOrder->getQueryString(), + $flags + ); + $paginator = $this->paginatorFactory->create($nb); + $tasks = $this->singleTaskAclAwareRepository->findByCourse( + $course, + $filterOrder->getQueryString(), + $flags, + $paginator->getCurrentPageFirstItemNumber(), + $paginator->getItemsPerPage(), + [ + 'startDate' => 'DESC', + 'endDate' => 'DESC', + ] + ); return $this->render( - '@ChillTask/SingleTask/index.html.twig', + '@ChillTask/SingleTask/AccompanyingCourse/list.html.twig', [ 'tasks' => $tasks, 'accompanyingCourse' => $course, - 'layout' => '@ChillPerson/AccompanyingCourse/layout.html.twig', - 'form' => $form->createView(), - 'title' => $this->translator->trans('Tasks for this accompanying period') + 'paginator' => $paginator, + 'filter_order' => $filterOrder ]); } diff --git a/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php b/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php index bc5124d95..cd3f819f4 100644 --- a/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php +++ b/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php @@ -2,20 +2,32 @@ namespace Chill\TaskBundle\Repository; +use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; +use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher; +use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\TaskBundle\Entity\SingleTask; +use Chill\TaskBundle\Security\Authorization\TaskVoter; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Security\Core\Security; final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepositoryInterface { + private AuthorizationHelperInterface $authorizationHelper; private EntityManagerInterface $em; private Security $security; + private CenterResolverDispatcher $centerResolverDispatcher; - public function __construct(EntityManagerInterface $em, Security $security) - { + public function __construct( + CenterResolverDispatcher $centerResolverDispatcher, + EntityManagerInterface $em, + Security $security, + AuthorizationHelperInterface $authorizationHelper + ) { + $this->centerResolverDispatcher = $centerResolverDispatcher; $this->em = $em; $this->security = $security; + $this->authorizationHelper = $authorizationHelper; } public function findByCurrentUsersTasks( @@ -26,12 +38,83 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository ?array $orderBy = [] ): array { $qb = $this->buildQueryMyTasks($pattern, $flags); + + return $this->getResult($qb, $start, $limit, $orderBy); + } + + public function countByCurrentUsersTasks( + ?string $pattern = null, + ?array $flags = [] + ): int { + return $this->buildQueryMyTasks($pattern, $flags) + ->select('COUNT(t)') + ->getQuery()->getSingleScalarResult(); + } + + public function findByCourse( + AccompanyingPeriod $course, + ?string $pattern = null, + ?array $flags = [], + ?int $start = 0, + ?int $limit = 50, + ?array $orderBy = [] + ): array { + $qb = $this->buildQueryByCourse($course, $pattern, $flags); + $qb = $this->addACL($qb, $course); + + return $this->getResult($qb, $start, $limit, $orderBy); + } + + public function countByCourse( + AccompanyingPeriod $course, + ?string $pattern = null, + ?array $flags = [] + ): int { + $qb = $this->buildQueryByCourse($course, $pattern, $flags); + + return $this + ->addACL($qb, $course) + ->select('COUNT(t)') + ->getQuery()->getSingleScalarResult(); + } + + public function buildQueryByCourse( + AccompanyingPeriod $course, + ?string $pattern = null, + ?array $flags = [] + ) : QueryBuilder { + $qb = $this->buildBaseQuery($pattern, $flags); + + return $qb + ->andWhere($qb->expr()->eq('t.course', ':course')) + ->setParameter('course', $course) + ; + } + + public function buildQueryMyTasks( + ?string $pattern = null, + ?array $flags = [] + ): QueryBuilder { + $qb = $this->buildBaseQuery($pattern, $flags); + + return $qb + ->andWhere($qb->expr()->eq('t.assignee', ':user')) + ->setParameter('user', $this->security->getUser()) + ; + } + + public function getResult( + QueryBuilder $qb, + ?int $start = 0, + ?int $limit = 50, + ?array $orderBy = [] + ): array { $qb->select('t'); $qb ->setFirstResult($start) ->setMaxResults($limit) - ; + ; foreach ($orderBy as $field => $direction) { $qb->addOrderBy('t.'.$field, $direction); @@ -40,25 +123,24 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository return $qb->getQuery()->getResult(); } - public function countByCurrentUsersTasks( - ?string $pattern = null, - ?array $flags = [] - ): int { - $qb = $this->buildQueryMyTasks($pattern, $flags); - $qb->select('COUNT(t)'); + public function addACL( + QueryBuilder $qb, + $entity + ): QueryBuilder { + $scopes = $this->authorizationHelper->getReachableScopes($this->security->getUser(), + TaskVoter::SHOW, $this->centerResolverDispatcher->resolveCenter($entity)); - return $qb->getQuery()->getSingleScalarResult(); + return $qb->andWhere($qb->expr()->in('t.circle', ':scopes')) + ->setParameter('scopes', $scopes); } - public function buildQueryMyTasks( + public function buildBaseQuery ( ?string $pattern = null, ?array $flags = [] ): QueryBuilder { $qb = $this->em->createQueryBuilder(); $qb ->from(SingleTask::class, 't') - ->where($qb->expr()->eq('t.assignee', ':user')) - ->setParameter('user', $this->security->getUser()) ; if (!empty($pattern)) { diff --git a/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepositoryInterface.php b/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepositoryInterface.php index b5d83a5f0..55c5f07ff 100644 --- a/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepositoryInterface.php +++ b/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepositoryInterface.php @@ -2,9 +2,27 @@ namespace Chill\TaskBundle\Repository; +use Chill\PersonBundle\Entity\AccompanyingPeriod; + interface SingleTaskAclAwareRepositoryInterface { public function findByCurrentUsersTasks(?string $pattern = null, ?array $flags = [], ?int $start = 0, ?int $limit = 50, ?array $orderBy = []): array; public function countByCurrentUsersTasks(?string $pattern = null, ?array $flags = []): int; + + public function findByCourse( + AccompanyingPeriod $course, + ?string $pattern = null, + ?array $flags = [], + ?int $start = 0, + ?int $limit = 50, + ?array $orderBy = [] + ): array; + + public function countByCourse( + AccompanyingPeriod $course, + ?string $pattern = null, + ?array $flags = [] + ): int; + } diff --git a/src/Bundle/ChillTaskBundle/Resources/views/SingleTask/AccompanyingCourse/list.html.twig b/src/Bundle/ChillTaskBundle/Resources/views/SingleTask/AccompanyingCourse/list.html.twig index be491e2f9..480ea705f 100644 --- a/src/Bundle/ChillTaskBundle/Resources/views/SingleTask/AccompanyingCourse/list.html.twig +++ b/src/Bundle/ChillTaskBundle/Resources/views/SingleTask/AccompanyingCourse/list.html.twig @@ -1,106 +1,42 @@ -{% if tasks|length > 0 %} -