<?php namespace App\Form\Task; use App\Entity\ActorEntity; use App\Enum\StatusEnum; use App\Form\AbstractFormManager; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Doctrine\Common\Collections\Criteria; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\DateType; use Symfony\Component\Form\Extension\Core\Type\ResetType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use App\Entity\TaskEntity; use App\Repository\TaskRepository; use Doctrine\ORM\Query; use Doctrine\ORM\Query\Expr\Join; class TaskFilterForm extends AbstractFormManager { /** @var array List of actors */ protected $actors = []; /** * {@inheritdoc} */ public function __construct(FormBuilderInterface $formBuilder, array $data = [], bool $usesToken = true) { $this->actors = $data['actors']; $formBuilder->setData([ 'actor' => null, 'unassigned' => false, 'followed' => false, 'status' => null, 'active' => false, 'notClosed' => true, 'doneAfter' => null, 'doneBefore' => null, ]); parent::__construct($formBuilder, $data, $usesToken); } /** * Get tasks * * @param TaskRepository $taskRepository * @return array */ public function getTasks(TaskRepository $taskRepository): array { $data = $this->getData(); // Create query $query = $taskRepository->createQueryBuilder('task'); // Create filter $criteria = new Criteria(); // Filter actors if ($data['followed']) { $query->join(ActorEntity::class, 'actor', Join::WITH, 'task.actor = actor'); $criteria->andWhere($criteria->expr() ->eq('actor.followed', true)); } if (!is_null($data['actor'])) { $criteria->andWhere($criteria->expr() ->eq('task.actor', $data['actor'])); } if ($data['unassigned']) { $criteria->andWhere($criteria->expr() ->isNull('task.actor')); } // Filter status if (!is_null($data['status'])) { $criteria->andWhere($criteria->expr() ->eq('task.status', $data['status'])); } if ($data['active']) { $criteria->andWhere($criteria->expr() ->in('task.status', StatusEnum::ACTIVE_STATUS)); } if ($data['notClosed']) { $criteria->andWhere($criteria->expr() ->notIn('task.status', StatusEnum::CLOSED_STATUS)); } // Filter dates if (!is_null($data['doneAfter'])) { $criteria->andWhere($criteria->expr() ->gt('task.executionDate', $data['doneAfter'])); } if (!is_null($data['doneBefore'])) { $criteria->andWhere($criteria->expr() ->lt('task.executionDate', $data['doneBefore'])); } $query->addCriteria($criteria); return $query->getQuery()->execute([], Query::HYDRATE_OBJECT); } /** * {@inheritdoc} */ public function getTemplate(): string { return '_includes/html/form/task/filter.html.twig'; } /** * {@inheritdoc} */ protected function addFields($formBuilder, $options): void { // Actor filters $formBuilder->add('actor', EntityType::class, [ 'class' => ActorEntity::class, 'choices' => $this->actors, 'group_by' => function (ActorEntity $choice) { if ($choice->getFollowed()) { return 'Suivi'; } if ($choice->getActive()) { return 'Actif'; } return 'Inactif'; }, 'choice_label' => 'displayName', 'required' => false, ]) ->add('unassigned', CheckboxType::class, [ 'required' => false, ]) ->add('followed', CheckboxType::class, [ 'required' => false, ]); // Status filters $formBuilder->add('status', ChoiceType::class, [ 'required' => false, 'choices' => TaskEntity::VALID_STATUS, 'choice_label' => function ($choice, $key, $value) { return StatusEnum::STATUS_NAME[$choice]; }, ]) ->add('active', CheckboxType::class, [ 'required' => false, ]) ->add('notClosed', CheckboxType::class, [ 'required' => false, ]); // Date filters $formBuilder->add('doneAfter', DateType::class, [ 'required' => false, 'widget' => 'single_text', ])->add('doneBefore', DateType::class, [ 'required' => false, 'widget' => 'single_text', ]); // Submit $formBuilder->add('submit', SubmitType::class)->add('reset', ResetType::class); } }