Loading CHANGELOG.md +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)). Loading config/merged/evenement.config.php +3 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -140,6 +142,7 @@ return [ 'form_elements' => [ 'factories' => [ EvenementForm::class => EvenementFormFactory::class, EvenementFilterForm::class => EvenementFilterFormFactory::class, ], ], 'hydrators' => [ Loading src/UnicaenEvenement/Controller/IndexController.php +16 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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(); Loading @@ -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 src/UnicaenEvenement/Controller/IndexControllerFactory.php +7 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 src/UnicaenEvenement/Form/Evenement/EvenementFilterForm.php 0 → 100644 +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
CHANGELOG.md +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)). Loading
config/merged/evenement.config.php +3 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -140,6 +142,7 @@ return [ 'form_elements' => [ 'factories' => [ EvenementForm::class => EvenementFormFactory::class, EvenementFilterForm::class => EvenementFilterFormFactory::class, ], ], 'hydrators' => [ Loading
src/UnicaenEvenement/Controller/IndexController.php +16 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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(); Loading @@ -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
src/UnicaenEvenement/Controller/IndexControllerFactory.php +7 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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
src/UnicaenEvenement/Form/Evenement/EvenementFilterForm.php 0 → 100644 +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