fix folder name

This commit is contained in:
2021-03-18 13:37:13 +01:00
parent a2f6773f5a
commit eaa0ad925f
1578 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,295 @@
<?php
/*
* Copyright (C) 2018 Champs Libres Cooperative <info@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/>.
*/
namespace Chill\TaskBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Chill\MainBundle\Entity\User;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Chill\TaskBundle\Repository\SingleTaskRepository;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\TaskBundle\Security\Authorization\TaskVoter;
use Symfony\Component\Security\Core\Role\Role;
use Chill\TaskBundle\Entity\SingleTask;
use Chill\PersonBundle\Form\Type\PickPersonType;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Chill\PersonBundle\Form\DataTransformer\PersonToIdTransformer;
use Chill\TaskBundle\Workflow\TaskWorkflowManager;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class SingleTaskListType extends AbstractType
{
/**
*
* @var EntityManagerInterface
*/
protected $em;
/**
*
* @var TokenStorageInterface
*/
protected $tokenStorage;
/**
*
* @var AuthorizationHelper
*/
protected $authorizationHelper;
/**
*
* @var TaskWorkflowManager
*/
protected $taskWorkflowManager;
public function __construct(
EntityManagerInterface $em,
TokenStorageInterface $tokenStorage,
AuthorizationHelper $authorizationHelper,
TaskWorkflowManager $taskWorkflowManager
) {
$this->em = $em;
$this->tokenStorage = $tokenStorage;
$this->authorizationHelper = $authorizationHelper;
$this->taskWorkflowManager = $taskWorkflowManager;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$statuses = [
'Tasks not started' => SingleTaskRepository::DATE_STATUS_NOT_STARTED,
'Tasks with expired deadline' => SingleTaskRepository::DATE_STATUS_ENDED,
'Tasks with warning deadline reached' => SingleTaskRepository::DATE_STATUS_WARNING,
'Current tasks' => SingleTaskRepository::DATE_STATUS_CURRENT,
'Closed tasks' => 'closed'
];
$builder
->add('user_id', ChoiceType::class, [
'choices' => $this->getUserChoices($options),
'placeholder' => 'Any user',
'required' => false,
'label' => 'Assignee'
])
;
if ($options['add_status']) {
$builder
->add('status', ChoiceType::class, [
'choices' => $statuses,
'expanded' => true,
'multiple' => true,
'label' => 'status'
]);
}
if ($options['add_type']) {
$types = $this->getTaskTypesChoices($options);
if (count($types) > 0) {
$builder->add('types', ChoiceType::class, [
'choices' => $types,
'required' => false,
'expanded' => true,
'multiple' => true,
'label' => 'Task types'
]);
}
}
if ($options['person'] === null) {
$builder
->add('person_id', PickPersonType::class, [
'centers' => $this->authorizationHelper
->getReachableCenters(
$this->tokenStorage->getToken()->getUser(),
new Role(TaskVoter::SHOW)
),
'required' => false,
'label' => 'Associated person'
])
;
$reachablesCenters = $this->getReachablesCenters();
if (count($reachablesCenters) > 1) {
$builder
->add('center_id', EntityType::class, [
'class' => \Chill\MainBundle\Entity\Center::class,
'choices' => $reachablesCenters,
'label' => 'Center',
'required' => false,
'placeholder' => 'All centers'
]);
}
} else {
// add a hidden field
$builder
->add('person_id', HiddenType::class);
$builder->get('person_id')
->addModelTransformer(new PersonToIdTransformer($this->em))
;
}
}
protected function getUserChoices($options)
{
$users = $this->getUsersAssigneedToTask($options);
$choices = \array_combine(
// get usernames
\array_map(function(User $user) { return $user->getUsername(); }, $users),
// get ids
\array_map(function(User $user) { return $user->getId(); }, $users)
);
$choices['Unassigned'] = '_unassigned';
return $choices;
}
protected function getTaskTypesChoices($options)
{
$qb = $this->em->createQueryBuilder();
$user = $this->tokenStorage->getToken()->getUser();
$role = new Role(TaskVoter::SHOW);
$centers = $this->authorizationHelper->getReachableCenters($user, $role);
$qb->select('DISTINCT task.type AS type')
->from(SingleTask::class, 'task')
->join('task.person', 'person')
;
$i = 0;
$orCenters = $qb->expr()->orX();
foreach($centers as $center) {
$circles = $this->authorizationHelper->getReachableCircles($user, $role, $center);
if (count($circles) > 0) {
$andX = $qb->expr()->andX();
$andX
->add($qb->expr()->eq('person.center', ':center_'.$i))
->add($qb->expr()->in('task.circle', ':circles_'.$i))
;
$orCenters->add($andX);
$qb
->setParameter('center_'.$i, $center)
->setParameter('circles_'.$i, $circles)
;
$i++;
}
}
if ($i > 0) {
$qb->where($orCenters);
}
$types = $qb->getQuery()->getResult();
$choices = [];
foreach ($types as $row) {
$fake = (new SingleTask())->setType($row['type']);
$label = $this->taskWorkflowManager->getWorkflowMetadata($fake, 'definition.name');
$choices[$label] = $row['type'];
}
return $choices;
}
/**
* Return a list of user having a task assigned.
*
* @return User[]
*/
protected function getUsersAssigneedToTask($options)
{
$qb = $this->em->createQueryBuilder();
$user = $this->tokenStorage->getToken()->getUser();
$role = new Role(TaskVoter::SHOW);
$centers = $this->authorizationHelper->getReachableCenters($user, $role);
$qb->select('DISTINCT user')
->from(User::class, 'user')
->join(SingleTask::class, 'task', \Doctrine\ORM\Query\Expr\Join::WITH, 'task.assignee = user')
->join('task.person', 'person')
->where("user.enabled = 'TRUE'")
;
if (NULL !== $options['person']) {
$qb
->andWhere($qb->expr()->eq('task.person', ':person'))
->setParameter('person', $options['person'])
;
}
$i = 0;
$circleCenterCond = $qb->expr()->orX();
foreach ($centers as $center) {
$circles = $this->authorizationHelper->getReachableCircles($user, $role, $center);
// add condition about person and circle
$circleCenterCond->add(
$qb->expr()->andX()
->add($qb->expr()->eq('person.center', ':center_'.$i))
->add($qb->expr()->in('task.circle', ':circles_'.$i))
);
$qb->setParameter('center_'.$i, $center)
->setParameter('circles_'.$i, $circles)
;
// increase counter
$i++;
}
$qb->andWhere($circleCenterCond);
return $qb->getQuery()->getResult();
}
protected function getReachablesCenters()
{
$user = $this->tokenStorage->getToken()->getUser();
$role = new Role(TaskVoter::SHOW);
return $this->authorizationHelper->getReachableCenters($user, $role);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setDefined('person')
->setDefault('person', null)
->setAllowedTypes('person', [Person::class, 'null'])
->setDefined('add_status')
->setDefault('add_status', false)
->setAllowedTypes('add_status', ['bool'])
->setDefined('add_type')
->setDefault('add_type', false)
->setAllowedTypes('add_type', ['bool'])
;
}
}

View File

@@ -0,0 +1,80 @@
<?php
/*
* Copyright (C) 2018 Champs Libres Cooperative <info@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/>.
*/
namespace Chill\TaskBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Entity\Center;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Chill\MainBundle\Form\Type\UserPickerType;
use Chill\MainBundle\Form\Type\ScopePickerType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Role\Role;
use Chill\TaskBundle\Security\Authorization\TaskVoter;
use Chill\MainBundle\Form\Type\DateIntervalType;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class SingleTaskType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class)
->add('description', TextareaType::class, [
'required' => false
])
->add('assignee', UserPickerType::class, [
'required' => false,
'center' => $options['center'],
'role' => $options['role'],
'placeholder' => 'Not assigned'
])
->add('circle', ScopePickerType::class, [
'center' => $options['center'],
'role' => $options['role']
])
->add('startDate', ChillDateType::class, [
'required' => false
])
->add('endDate', ChillDateType::class, [
'required' => false
])
->add('warningInterval', DateIntervalType::class, [
'required' => false
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setRequired('center')
->setAllowedTypes('center', [ Center::class ])
->setRequired('role')
->setAllowedTypes('role', [ Role::class ])
;
}
}