Commit ef62d110 authored by Thibaut Vallee's avatar Thibaut Vallee
Browse files

filtre de recherche par formulaire

parent 0bd1efcd
Loading
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
Journal des versions
====================

6.5.0
-----
- [Sécu] Mise en place d'un formulaire de filtre

6.4.0
-----
- Suppression de la vilaine dépendance avec unicaen/mail. Nécessite une adpatation de votre appli ssi vous avez besoin de recevoir le mail intitulé 'le journal vient d'être débloqué' (cf. [migration.md](doc/migration.md#640)).
+3 −0
Original line number Diff line number Diff line
@@ -6,6 +6,8 @@ use Laminas\Router\Http\Literal;
use Laminas\Router\Http\Segment;
use UnicaenEvenement\Controller\EvenementController;
use UnicaenEvenement\Controller\EvenementControllerFactory;
use UnicaenEvenement\Form\Evenement\EvenementFilterForm;
use UnicaenEvenement\Form\Evenement\EvenementFilterFormFactory;
use UnicaenEvenement\Form\Evenement\EvenementForm;
use UnicaenEvenement\Form\Evenement\EvenementFormFactory;
use UnicaenEvenement\Form\Evenement\EvenementHydrator;
@@ -140,6 +142,7 @@ return [
    'form_elements' => [
        'factories' => [
            EvenementForm::class => EvenementFormFactory::class,
            EvenementFilterForm::class => EvenementFilterFormFactory::class,
        ],
    ],
    'hydrators' => [
+16 −4
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@

namespace UnicaenEvenement\Controller;

use UnicaenEvenement\Form\Evenement\EvenementFormAwareTrait;
use UnicaenEvenement\Service\Etat\EtatServiceAwareTrait;
use UnicaenEvenement\Service\Evenement\EvenementServiceAwareTrait;
use UnicaenEvenement\Service\Journal\JournalServiceAwareTrait;
@@ -15,15 +16,26 @@ class IndexController extends AbstractActionController
    use EvenementServiceAwareTrait;
    use JournalServiceAwareTrait;
    use TypeServiceAwareTrait;
    use EvenementFormAwareTrait;


    public function indexAction() : ViewModel
    {
        $types = $this->getTypeService()->getEntityRepository()->findAll();
        $etats = $this->getEtatEvenementService()->getEntityRepository()->findAll();

        $filterForm = $this->getEvenementFilterForm();
        $filtre = $this->params()->fromQuery();
        if (!isset($filtre['date']) OR $filtre['date'] === '') $filtre['date'] = '1M';

        if (!isset($filtre['date']) or $filtre['date'] === '') $filtre['date'] = '1W';
        $filterForm->setData($filtre);
        if ($filterForm->isValid()) {
            $filtre = $filterForm->getData();
        }
        else{ //On force la date pour ne pas avoir tous les événements par défaut
            $filtre = ['date' => '1W'];
        }

        $types = $this->getTypeService()->getEntityRepository()->findAll();
        $etats = $this->getEtatEvenementService()->getEntityRepository()->findAll();

        $evenements = $this->getEvenementService()->getEvenementsWithFiltre($filtre);
        $journaux = $this->getJournalService()->getJounaux();
@@ -33,8 +45,8 @@ class IndexController extends AbstractActionController
            'countEvents' => count(($evenements)??[]),
            'types' => ($types)??[],
            'etats' => ($etats)??[],
            'params' => $filtre,
            'journaux' => $journaux,
            'filterForm' => $filterForm,
        ]);
    }
}
 No newline at end of file
+7 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ namespace UnicaenEvenement\Controller;

use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use UnicaenEvenement\Form\Evenement\EvenementFilterForm;
use UnicaenEvenement\Service\Etat\EtatService;
use UnicaenEvenement\Service\Evenement\EvenementService;
use UnicaenEvenement\Service\Journal\JournalService;
@@ -29,11 +30,17 @@ class IndexControllerFactory {
        $journalService = $container->get(JournalService::class);
        $typeService = $container->get(TypeService::class);

        /**
        * @var EvenementFilterForm $evenementFilterForm
        */
        $evenementFilterForm = $container->get('FormElementManager')->get(EvenementFilterForm::class);

        $controller = new IndexController();
        $controller->setEtatEvenementService($etatService);
        $controller->setEvenementService($evenementService);
        $controller->setJournalService($journalService);
        $controller->setTypeService($typeService);
        $controller->setEvenementFilterForm($evenementFilterForm);
        return $controller;
    }
}
 No newline at end of file
+198 −0
Original line number Diff line number Diff line
<?php

namespace UnicaenEvenement\Form\Evenement;

use DoctrineModule\Form\Element\ObjectSelect;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use Laminas\Filter\StringTrim;
use Laminas\Filter\StripTags;
use Laminas\Filter\ToInt;
use Laminas\Filter\ToNull;
use Laminas\Form\Element\Button;
use Laminas\Form\Element\Select;
use Laminas\Form\Form;
use Laminas\InputFilter\InputFilter;
use Laminas\InputFilter\InputFilterProviderInterface;
use DoctrineModule\Persistence\ProvidesObjectManager;
use Laminas\Validator\Callback;
use UnicaenEvenement\Entity\Db\Etat;
use UnicaenEvenement\Entity\Db\Type;

class
EvenementFilterForm extends Form
    implements
    InputFilterProviderInterface,
    ObjectManagerAwareInterface
{
    use ProvidesObjectManager;

    public function init()
    {

        $this
            ->setAttribute('method', 'get')
            ->setInputFilter(new InputFilter());
//        TODO : permetre depuis la config de passer en post ou en get
//        Mettre le csrf si l'on est en post
//        $this->add(new Csrf('csrf'));

        //button
        $this->add([
            'type' => Button::class,
            'name' => 'filter',
            'options' => [
                'label' => '<i class="icon icon-filtrer"></i> Filtrer',
                'label_options' => [
                    'disable_html_escape' => true,
                ],
            ],
            'attributes' => [
                'id' => 'filter',
                'type' => 'submit',
                'class' => 'btn btn-primary',
            ],
        ]);
        $this->add([
            'type' => Button::class,
            'name' => 'clear',
            'options' => [
                'label' => '<i class="icon icon-gommer"></i> Remise à zéro',
                'label_options' => [
                    'disable_html_escape' => true,
                ],
            ],
            'attributes' => [
                'id' => 'clear',
                'type' => 'submit',
                'class' => 'btn btn-primary',
            ],
        ]);

        $this->add([
            'type' => Select::class,
            'name' => 'etat',
            'options' => [
                'label' => 'État',
                'value_options' =>  $this->getEtatsOptions(),
                'empty_option' => "Peu importe",
            ],
            'attributes' => [
                'class' => "selectpicker",
                'autofocus' => true,
                'id' => 'etat',
            ],
        ]);

        $this->add([
            'type' => ObjectSelect::class,
            'name' => 'type',
            'options' => [
                'object_manager' => $this->getObjectManager(),
                'target_class'   => Type::class,
                'label_generator' => function (Type $type) {
                    return $type->getLibelle();
                },
                'find_method'    => [
                    'name'   => 'findBy',
                    'params' => [
                        'criteria' => [],
                        'orderBy'  => ['libelle' => 'ASC'],
                    ],
                ],
                'label' => "Type",
                'empty_option' => "Peu importe",

            ],
            'attributes' => [
                'id' => 'type',
                'class' =>  'selectpicker'
            ],
        ]);

        $this->add([
            'type' => Select::class,
            'name' => 'date',
            'options' => [
                'label' => 'Historique',
                'value_options' =>  $this->getDatesOptions(),
            ],
            'attributes' => [
                'class' => "selectpicker",
                'autofocus' => true,
                'id' => 'date',
            ],
        ]);
    }


    public function getInputFilterSpecification()
    {
        return [
            'etat' => [
                "name" => 'etat',
                'required' => false,
                'filters' => [
                    ['name' => ToNull::class],
                    ['name' => StripTags::class],
                    ['name' => StringTrim::class],
                ],
                'validators' => []
            ],
            'type' => [
                "name" => 'type',
                'required' => false,
                'filters' => [
                    ['name' => ToNull::class],
                    ['name' => ToInt::class],
                ],
                'validators' => []
            ],
            'date' => [
                "name" => 'date',
                'required' => false,
                'filters' => [
                    ['name' => StripTags::class],
                    ['name' => StringTrim::class],
                ],
                'validators' => []
            ],
        ];
    }

    /**
     * TODO : permettre depuis la configuration de UnicaenMail modifier les valeurs des champs
     */
    protected array $datesOptions = [
        ['value' => '1W', 'label' => '1 semaine'],
        ['value' => '2W', 'label' => '2 semaine'],
        ['value' => '1M', 'label' => '1 mois'],
        ['value' => '3M', 'label' => '3 mois'],
        ['value' => '6M', 'label' => '6 mois'],
        ['value' => '1Y', 'label' => '1 an'],
    ];

    public function getDatesOptions(): array
    {
        return $this->datesOptions;
    }

    public function setDatesOptions(array $datesOptions): void
    {
        $this->datesOptions = $datesOptions;
    }

    /**
     * @return array|array[]
     * @desc choix fait de ne pas utiliser un ObjectSelect de doctrine pour concerver le fonctionnement original du filtre
     * l'input doit retourner le code des états d'événément et non l'objet
     */
    public function getEtatsOptions(): array
    {
        $types = $this->objectManager->getRepository(Etat::class)->findBy([], ['libelle' => 'ASC']);
        $typesOptions = [];
        foreach ($types as $type) {
            $typesOptions[] = ['value' => $type->getCode(), 'label' => $type->getLibelle()];
        }
        return $typesOptions;
    }
}
 No newline at end of file
Loading