add list of task

This commit is contained in:
Julien Fastré 2018-04-17 21:57:56 +02:00
parent fd8b6490d0
commit 9dfa39ff07
6 changed files with 298 additions and 4 deletions

View File

@ -0,0 +1,66 @@
<?php
namespace Chill\TaskBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use Chill\PersonBundle\Entity\Person;
use Chill\TaskBundle\Entity\SingleTask;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
class TaskController extends Controller
{
/**
* @Route("/{_locale}/task/task/list/{personId}")
*/
public function listAction(Request $request, Person $personId)
{
$person = $personId;
$em = $this->getDoctrine()
->getManager();
// collect parameters for filter
$params = [];
$params['person'] = $person;
$singleTasks = $this->get('chill_task.single_task_repository')
->findByParameters($params, $this->getUser());
return $this->render('ChillTaskBundle:Task:index.html.twig', [
'single_tasks' => $singleTasks,
'person' => $person
]);
}
protected function getPersonParam(Request $request, 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(Request $request, EntityManagerInterface $em)
{
$user = $em->getRepository(User::class)
->find($request->query->getInt('user_id'))
;
if (NULL === $user) {
throw $this->createNotFoundException('user not found');
}
return $user;
}
}

View File

@ -6,13 +6,15 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
use Chill\TaskBundle\Security\Authorization\TaskVoter;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
/**
* This is the class that loads and manages your bundle configuration.
*
* @link http://symfony.com/doc/current/cookbook/bundles/extension.html
*/
class ChillTaskExtension extends Extension
class ChillTaskExtension extends Extension implements PrependExtensionInterface
{
/**
* {@inheritdoc}
@ -25,5 +27,22 @@ class ChillTaskExtension extends Extension
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services/controller.yml');
$loader->load('services/security.yml');
$loader->load('services/repositories.yml');
}
public function prepend(ContainerBuilder $container)
{
$this->prependAuthorization($container);
}
public function prependAuthorization(ContainerBuilder $container)
{
$container->prependExtensionConfig('security', array(
'role_hierarchy' => array(
TaskVoter::UPDATE => [TaskVoter::SHOW],
TaskVoter::CREATE => [TaskVoter::SHOW]
)
));
}
}

View File

@ -142,6 +142,28 @@ class SingleTask extends AbstractTask
return $this->warningInterval;
}
/**
* Get the Warning date, computed from the difference between the
* end date and the warning interval
*
* Return null if warningDate or endDate is null
*
* @return \DateTimeImmutable
*/
public function getWarningDate()
{
if ($this->getWarningInterval() === null) {
return null;
}
if ($this->getEndDate() === null) {
return null;
}
return \DateTimeImmutable::createFromMutable($this->getEndDate())
->sub($this->getWarningInterval());
}
function getRecurringTask(): RecurringTask
{
return $this->recurringTask;

View File

@ -2,12 +2,83 @@
namespace Chill\TaskBundle\Repository;
use Chill\MainBundle\Entity\User;
use Doctrine\ORM\QueryBuilder;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Symfony\Component\Security\Core\Role\Role;
use Chill\TaskBundle\Security\Authorization\TaskVoter;
/**
* SingleTaskRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class SingleTaskRepository extends \Doctrine\ORM\EntityRepository
{
/**
*
* @var AuthorizationHelper
*/
protected $authorizationHelper;
public function setAuthorizationHelper(AuthorizationHelper $authorizationHelper)
{
$this->authorizationHelper = $authorizationHelper;
}
public function findByParameters($params, User $currentUser)
{
$qb = $this->createQueryBuilder('st');
$this->buildQuery($qb, $params, $currentUser);
return $qb
->getQuery()
->getResult()
;
}
protected function buildQuery(QueryBuilder $qb, $params, User $currentUser)
{
$this->buildACLQuery($qb, $currentUser);
if (\array_key_exists('person', $params)) {
$qb->andWhere($qb->expr()->eq('st.person', ':person'));
$qb->setParameter('person', $params['person']);
}
}
protected function buildACLQuery(QueryBuilder $qb, User $currentUser)
{
if (NULL === $this->authorizationHelper) {
throw new \LogicException("Injecting the authorization helper is "
. "required to run this query. Please use dependency injection "
. "to initialize this repository or use the method "
. "`setAuthorizationHelper`");
}
$role = new Role(TaskVoter::SHOW);
$qb->join('st.person', 'p');
$centers = $this->authorizationHelper
->getReachableCenters($currentUser, $role)
;
$i = 0;
$where = $qb->expr()->orX();
foreach($centers as $center) {
$circles = $this->authorizationHelper
->getReachableCircles($currentUser, $role, $center);
$centerWhere = $qb->expr()->andX();
$centerWhere->add($qb->expr()->eq('p.center', ':center_'.$i));
$qb->setParameter('center_'.$i, $center);
$centerWhere->add($qb->expr()->in('st.circle', ':circles_'.$i));
$qb->setParameter('circles_'.$i, $circles);
$where->add($centerWhere);
$i ++;
}
$qb->where($where);
}
}

View File

@ -0,0 +1,10 @@
services:
chill_task.single_task_repository:
class: Chill\TaskBundle\Repository\SingleTaskRepository
factory: ['@doctrine.orm.entity_manager', getRepository]
arguments:
- 'Chill\TaskBundle\Entity\SingleTask'
calls:
- method: setAuthorizationHelper
arguments:
- "@chill.main.security.authorization.helper"

View File

@ -0,0 +1,106 @@
{#
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
#}
{% extends "ChillPersonBundle::layout.html.twig" %}
{% set activeRouteKey = 'chill_task_single_task_new' %}
{% block title %}{{ 'Task list'|trans }}{% endblock %}
{% macro thead() %}
<thead>
<tr>
<th>{{ 'Title'|trans }}</th>
<th>{{ 'Task type'|trans }}</th>
<th>{{ 'Task status'|trans }}</th>
<th>{{ 'Task start date'|trans }}</th>
<th>{{ 'Task warning date'|trans }}</th>
<th>{{ 'Task end date'|trans }}</th>
</tr>
</thead>
{% endmacro %}
{% macro row(task) %}
<tr>
<td>{{ task.title }}</td>
<td>{{ task.type }}</td>
<td>todo</td>
<td>{{ task.startDate|localizeddate('medium', 'none') }}</td>
<td>{{ task.warningDate|localizeddate('medium', 'none') }}</td>
<td>{{ task.endDate|localizeddate('medium', 'none') }}</td>
</tr>
{% endmacro %}
{% import _self as helper %}
{# filter tasks #}
{% set ended_tasks = [] %}
{% for task in single_tasks if (task.endDate|date("U") > 'now'|date("U")) %}
{% set ended_tasks = ended_tasks|merge([ task ]) %}
{% endfor %}
{% set warning_tasks = [] %}
{% for task in single_tasks if (task.warningDate|date('U') > 'now'|date("U") and task not in ended_tasks) %}
{% set warning_tasks = warning_tasks|merge([ task ]) %}
{% endfor %}
{% set rest_tasks = [] %}
{% for task in single_tasks if (task not in ended_tasks and task not in warning_tasks) %}
{% set rest_tasks = rest_tasks|merge([ task ]) %}
{% endfor %}
{% block personcontent %}
<h1>{{ 'Task list'|trans }}</h1>
{% if ended_tasks|length > 0 %}
<h2>{{ 'Task with expired deadline'|trans }}</h2>
<table>
{{ helper.thead() }}
<tbody>
{% for task in ended_tasks %}
{{ helper.row(task) }}
{% endfor %}
</tbody>
</table>
{% endif %}
{% if warning_tasks|length > 0 %}
<h2>{{ 'Task with warning'|trans }}</h2>
<table>
{{ helper.thead() }}
<tbody>
{% for task in warning_tasks %}
{{ helper.row(task) }}
{% endfor %}
</tbody>
</table>
{% endif %}
{% if rest_tasks|length > 0 %}
<h2>{{ 'Task '|trans }}</h2>
<table>
{{ helper.thead() }}
<tbody>
{% for task in rest_tasks %}
{{ helper.row(task) }}
{% endfor %}
</tbody>
</table>
{% endif %}
{% endblock %}