diff --git a/readme.md b/readme.md index 23d659d52987ef433dcbabf806aaac5a56d1dd57..81fd837752ec8416f340d7f2171c6d29791683ba 100644 --- a/readme.md +++ b/readme.md @@ -20,13 +20,25 @@ Alors, on pourra filtrer les données pour les référents selon les domaines do ## Périmètres implementés/hardcodés -Seulement un périmètre est aujourd'hui implemnté dans la bibliothèque : +## Déclaration de périmètres -* Structure : -Filtrage selon les structures associés aux rôles. -Ce périmètre suppose d'ajouter la colonne `perimetre_structure_id` dans les colonnes déclarées de l'indicateur. +Les périmètres que l'application exploite sont à déclarer en configuration. +Le tableau de déclaration contient comme clef le nom du périmètre et en valeur une description qui sera présentée dans le formulaire de création des indicateurs. -**N.B.** : Les colonnes de travail seront masqué des affichages et exportations. +peut être déclarer dans le fichier [unicaen-indicateur.global.php](config/unicaen-indicateur.global.php.dist) +```php +return [ + 'unicaen-indicateur' => [ + 'role' => "Affichage restreint aux rôles de l'usagers", + 'structure' => "Affichage restreint aux structures de l'usagers", + ], +]; +``` + +**Attention** : l'usage d'un périmètre suppose la déclatation d'une colonne perimetre_NOM_id dans l'indicateur qui sera exploité par le filtrage. +Ainsi pour le périmetre `structure` la colonne de filtrage sera nommée `perimetre_structure_id`. + +**N.B.** : Les colonnes de travail seront masquées des affichages et exportations. ## Récupération des périmètres depuis l'application maîtresse @@ -52,4 +64,5 @@ Améliorations ------------- 1. **PERIMÈTRE** Exposer plusieurs périmètres -1. **PERIMÈTRE** Déclarer des périmètres hors de l'application \ No newline at end of file +1. **SECURITE** Verifier qu'il n'y est que des selects +1. **QoL** Coloration tinyMCE \ No newline at end of file diff --git a/src/UnicaenIndicateur/Controller/IndicateurController.php b/src/UnicaenIndicateur/Controller/IndicateurController.php index 88a9dde3f582730f6cf4e05a40b03069c83bc6fa..840afa29b6fb563dc9254cb4cb63d1bf9afb6c77 100644 --- a/src/UnicaenIndicateur/Controller/IndicateurController.php +++ b/src/UnicaenIndicateur/Controller/IndicateurController.php @@ -92,7 +92,7 @@ class IndicateurController extends AbstractActionController { return $this->redirect()->toRoute('indicateur/afficher', ['indicateur' => $indicateur->getId()], [], true); } - public function creerAction() : ViewModel + public function creerAction() : ViewModel|Response { $indicateur = new Indicateur(); $namespace = $this->params()->fromQuery('namespace'); @@ -117,7 +117,8 @@ class IndicateurController extends AbstractActionController { $count = $this->getIndicateurService()->getCount($indicateur); $indicateur->setNbElements($count); $this->getIndicateurService()->update($indicateur); - exit(); + + return $this->redirect()->toRoute('indicateur/afficher', ['indicateur' => $indicateur->getId()], [], true); } } diff --git a/src/UnicaenIndicateur/Controller/IndicateurControllerFactory.php b/src/UnicaenIndicateur/Controller/IndicateurControllerFactory.php index 8badfef1bfc5f52dfc1fe34acce6739259965cc7..652038062d3cc62d0a23df5c1eb8741eda5708f7 100644 --- a/src/UnicaenIndicateur/Controller/IndicateurControllerFactory.php +++ b/src/UnicaenIndicateur/Controller/IndicateurControllerFactory.php @@ -10,7 +10,7 @@ use UnicaenIndicateur\Service\Indicateur\IndicateurService; use Interop\Container\ContainerInterface; use UnicaenIndicateur\Service\Perimetre\PerimetreServiceInterface; use UnicaenMail\Service\Mail\MailService; -use UnicaenUtilisateur\Service\User\UserService;; +use UnicaenUtilisateur\Service\User\UserService; class IndicateurControllerFactory { @@ -36,6 +36,7 @@ class IndicateurControllerFactory { $config = $container->get('config'); $perimetreServiceKey = $container->get($config['unicaen-indicateur']['perimetreService']); + /** @var PerimetreServiceInterface $perimetreService */ $perimetreService = $container->get($perimetreServiceKey::class); /** diff --git a/src/UnicaenIndicateur/Entity/Db/Indicateur.php b/src/UnicaenIndicateur/Entity/Db/Indicateur.php index 3e82ed2f1b8adb08fd744854291d1356da8a823c..0cd6c0b99f64983111d451a003e69f1762948144 100644 --- a/src/UnicaenIndicateur/Entity/Db/Indicateur.php +++ b/src/UnicaenIndicateur/Entity/Db/Indicateur.php @@ -13,9 +13,6 @@ class Indicateur { const ENTITY_LIBRE = 'Libre'; const ENTITY_ADAPTATIF = 'Adaptatif'; - const PERIMETRE_AUCUN = 'aucun'; - const PERIMETRE_STRUCTURE = 'structure'; - private ?int $id = null; private ?string $code = null; private ?string $titre = null; diff --git a/src/UnicaenIndicateur/Form/Indicateur/IndicateurForm.php b/src/UnicaenIndicateur/Form/Indicateur/IndicateurForm.php index 7f0039d9a540c4d5e91dce5d8a15ffb9fdeb4cd9..018928894247098f3ee9eb6119ccfb50aaff96b9 100644 --- a/src/UnicaenIndicateur/Form/Indicateur/IndicateurForm.php +++ b/src/UnicaenIndicateur/Form/Indicateur/IndicateurForm.php @@ -17,12 +17,18 @@ class IndicateurForm extends Form { use CategorieServiceAwareTrait; private ?string $oldCode = null; + private array $perimetres = []; public function setOldCode(?string $oldCode): void { $this->oldCode = $oldCode; } + public function setPerimetres(array $perimetres): void + { + $this->perimetres = $perimetres; + } + public function init(): void { // code @@ -126,11 +132,8 @@ class IndicateurForm extends Form { 'options' => [ 'label' => "Périmètre associé <span class='icon icon-obligatoire' title='champ obligatoire'></span> :", 'label_options' => [ 'disable_html_escape' => true, ], - 'empty_option' => "Sélection d'un périmtre", - 'value_options' => [ - Indicateur::PERIMETRE_AUCUN => "Non soumis à un périmètre", - Indicateur::PERIMETRE_STRUCTURE => "Liés aux structures (requiert une colonne perimetre_structure_id)", - ], + 'empty_option' => "Sélection des périmètres", + 'value_options' => $this->perimetres, ], 'attributes' => [ 'id' => 'perimetre', diff --git a/src/UnicaenIndicateur/Form/Indicateur/IndicateurFormFactory.php b/src/UnicaenIndicateur/Form/Indicateur/IndicateurFormFactory.php index 580648176608926c7b579c1a630c144304efdaa8..2460f496a4ed82b7b2dd5b4971e8bc47c1544623 100644 --- a/src/UnicaenIndicateur/Form/Indicateur/IndicateurFormFactory.php +++ b/src/UnicaenIndicateur/Form/Indicateur/IndicateurFormFactory.php @@ -7,6 +7,7 @@ use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use UnicaenIndicateur\Service\Categorie\CategorieService; use UnicaenIndicateur\Service\Indicateur\IndicateurService; +use UnicaenIndicateur\Service\Perimetre\PerimetreServiceInterface; class IndicateurFormFactory { @@ -26,11 +27,18 @@ class IndicateurFormFactory { $indicateurService = $container->get(IndicateurService::class); $hydrator = $container->get('HydratorManager')->get(IndicateurHydrator::class); + $config = $container->get('config'); + /** @var PerimetreServiceInterface $perimetreService */ + $perimetreServiceKey = $container->get($config['unicaen-indicateur']['perimetreService']); + $perimetreService = $container->get($perimetreServiceKey::class); + /** @var array $perimetres */ + $perimetres = $config['unicaen-indicateur']['perimetres']; + $form = new IndicateurForm(); $form->setCategorieService($categorieService); $form->setIndicateurService($indicateurService); $form->setHydrator($hydrator); - $form->init(); + $form->setPerimetres($perimetres); return $form; } } \ No newline at end of file diff --git a/src/UnicaenIndicateur/Service/Indicateur/IndicateurService.php b/src/UnicaenIndicateur/Service/Indicateur/IndicateurService.php index a9f3f790412a4adbadfd8e71bfc2665540e1633d..9693865e13cb356b0933673ccc99c593130b0f33 100644 --- a/src/UnicaenIndicateur/Service/Indicateur/IndicateurService.php +++ b/src/UnicaenIndicateur/Service/Indicateur/IndicateurService.php @@ -6,7 +6,6 @@ use DateTime; use Doctrine\DBAL\Driver\Exception as DBA_Driver_Exception; use Doctrine\DBAL\Exception as DBA_Exception; use Doctrine\ORM\EntityManager; -use Doctrine\ORM\Exception\ORMException; use Doctrine\ORM\NonUniqueResultException; use Doctrine\ORM\QueryBuilder; use DoctrineModule\Persistence\ProvidesObjectManager; @@ -14,6 +13,7 @@ use Exception; use Laminas\Mvc\Controller\AbstractActionController; use RuntimeException; use UnicaenIndicateur\Entity\Db\Indicateur; +use UnicaenIndicateur\Service\Perimetre\PerimetreServiceInterface; /** * @property EntityManager $objectManager @@ -42,11 +42,7 @@ class IndicateurService */ public function update(Indicateur $indicateur): Indicateur { - try { - $this->getObjectManager()->flush($indicateur); - } catch (ORMException $e) { - throw new RuntimeException("Un problème est survenue lors de l'enregistrement en base.", $e); - } + $this->getObjectManager()->flush($indicateur); return $indicateur; } @@ -56,12 +52,8 @@ class IndicateurService */ public function delete(Indicateur $indicateur): Indicateur { - try { - $this->getObjectManager()->remove($indicateur); - $this->getObjectManager()->flush($indicateur); - } catch (ORMException $e) { - throw new RuntimeException("Un problème est survenue lors de l'enregistrement en base.", $e); - } + $this->getObjectManager()->remove($indicateur); + $this->getObjectManager()->flush($indicateur); return $indicateur; } @@ -91,21 +83,20 @@ class IndicateurService if ($exist === false) return null; - $sql = "SELECT * FROM " . $indicateur->getViewId(); + $sql = "SELECT * FROM " . $indicateur->getViewId() . " WHERE 1=1"; + + if ($indicateur->getPerimetre() !== null and $indicateur->getPerimetre() !== "aucun") { + $perimetresActifs = explode(PerimetreServiceInterface::PERIMETRE_SEPARATOR, $indicateur->getPerimetre()); - switch ($indicateur->getPerimetre()) { - case Indicateur::PERIMETRE_STRUCTURE: + foreach ($perimetresActifs as $perimetreActif) { if ($userPerimetre !== null) { - if (!empty($userPerimetre)) { - $sql .= " WHERE perimetre_structure_id IN (" . implode(",", $userPerimetre) . ")"; - } else { - $sql .= " WHERE perimetre_structure_id IS NULL"; + if (!empty($userPerimetre) AND isset($userPerimetre[$perimetreActif])) { + $sql .= " AND perimetre_" . $perimetreActif . "_id IN (" . implode(",", $userPerimetre[$perimetreActif]) . ")"; + } else { + $sql .= " AND perimetre_" . $perimetreActif . "_id IS NULL"; } } - break; - case Indicateur::PERIMETRE_AUCUN: - default: - break; + } } try { @@ -122,12 +113,9 @@ class IndicateurService return $tmp; } - /** - * @param Indicateur $indicateur - */ - public function refresh(Indicateur $indicateur) + + public function manipulateDatabaseView(string $sql): void { - $sql = "REFRESH MATERIALIZED VIEW " . $indicateur->getViewId(); try { $query = $this->getObjectManager()->getConnection()->prepare($sql); } catch (DBA_Exception $e) { @@ -138,6 +126,15 @@ class IndicateurService } catch (DBA_Driver_Exception $e) { throw new RuntimeException("Un problème est survenu lors de la récupération de des données de l'indicateur.", 0, $e); } + } + + /** + * @param Indicateur $indicateur + */ + public function refresh(Indicateur $indicateur): void + { + $sql = "REFRESH MATERIALIZED VIEW " . $indicateur->getViewId(); + $this->manipulateDatabaseView($sql); $indicateur->setDernierRafraichissement(new DateTime()); $count = $this->getCount($indicateur); $indicateur->setNbElements($count); @@ -147,37 +144,19 @@ class IndicateurService /** * @param Indicateur $indicateur */ - public function dropView(Indicateur $indicateur) + public function dropView(Indicateur $indicateur): void { $sql = "DROP MATERIALIZED VIEW IF EXISTS " . $indicateur->getViewId(); - try { - $query = $this->getObjectManager()->getConnection()->prepare($sql); - } catch (DBA_Exception $e) { - throw new RuntimeException("Un problème est survenu lors de la récupération de la session.", 0, $e); - } - try { - $query->execute(); - } catch (DBA_Driver_Exception $e) { - throw new RuntimeException("Un problème est survenu lors de la récupération de des données de l'indicateur.", 0, $e); - } + $this->manipulateDatabaseView($sql); } /** * @param Indicateur $indicateur */ - public function createView(Indicateur $indicateur) + public function createView(Indicateur $indicateur): void { $sql = "CREATE MATERIALIZED VIEW " . $indicateur->getViewId() . " AS " . $indicateur->getRequete(); - try { - $query = $this->getObjectManager()->getConnection()->prepare($sql); - } catch (DBA_Exception $e) { - throw new RuntimeException("Un problème est survenu lors de la récupération de la session.", 0, $e); - } - try { - $query->execute(); - } catch (DBA_Driver_Exception $e) { - throw new RuntimeException("Un problème est survenu lors de la récupération de des données de l'indicateur.", 0, $e); - } + $this->manipulateDatabaseView($sql); $indicateur->setDernierRafraichissement(new DateTime()); $count = $this->getCount($indicateur); $indicateur->setNbElements($count); @@ -186,7 +165,7 @@ class IndicateurService /** * @param Indicateur $indicateur */ - public function updateView(Indicateur $indicateur) + public function updateView(Indicateur $indicateur): void { $this->dropView($indicateur); $this->createView($indicateur); @@ -247,14 +226,14 @@ class IndicateurService return $this->getIndicateur($id); } - public function getIndicateurByCode(string $code)//: ?Indicateur + public function getIndicateurByCode(string $code): ?Indicateur { $qb = $this->createQueryBuilder() ->andWhere('indicateur.code = :code')->setParameter('code', $code); try { $indicateur = $qb->getQuery()->getOneOrNullResult(); } catch (NonUniqueResultException $e) { - throw new RuntimeException("Plusieurs [" . Indicateur::class . "] partagent le même code [".$code."]",0,$e); + throw new RuntimeException("Plusieurs [" . Indicateur::class . "] partagent le même code [" . $code . "]", 0, $e); } return $indicateur; } @@ -276,7 +255,7 @@ class IndicateurService /** * @param Indicateur $indicateur - * @param ?string[] $perimetres (un tableau présentant les périmètres ) + * @param ?string[] $perimetres (un tableau présentant les périmètres) * @return array|null */ public function getIndicateurData(Indicateur $indicateur, ?array $perimetres = null): ?array @@ -285,7 +264,7 @@ class IndicateurService $exist = $this->verifierExistanceMaterializedView($indicateur->getViewId()); if (!$exist) return null; - $userPerimetre = $this->extractPerimetresValides($indicateur, $perimetres); + $userPerimetre = $this->extractPerimetres($perimetres); $rawdata = $this->fetch($indicateur, $userPerimetre); if ($rawdata === null) return null; $rubriques = []; @@ -293,37 +272,39 @@ class IndicateurService if ($indicateur->getEntity() === Indicateur::ENTITY_LIBRE) { if (!empty($rawdata)) { foreach ($rawdata[0] as $key => $value) { - $rubriques[] = $key; + $rubriques[] = $key; } } } - if ($indicateur->getEntity() === Indicateur::ENTITY_ADAPTATIF) { - if (!empty($rawdata)) { - foreach ($rawdata[0] as $key => $value) $rubriques[] = $key; - } - } - if ($indicateur->getEntity() === Indicateur::ENTITY_STRUCTURE) { - $rubriques = [ - 'Code' => 'code', - 'Libelle' => 'libelle_court', - 'Libelle long' => 'libelle_long', - 'Type' => 'type', - - ]; - } - if ($indicateur->getEntity() === Indicateur::ENTITY_AGENT) { - $rubriques = [ - 'ID' => 'c_src_individu', - 'SOURCE' => 'c_source', - 'Prenom' => 'prenom', - 'Nom' => 'nom_usage', - ]; - } +// if ($indicateur->getEntity() === Indicateur::ENTITY_ADAPTATIF) { +// if (!empty($rawdata)) { +// foreach ($rawdata[0] as $key => $value) $rubriques[] = $key; +// } +// } +// if ($indicateur->getEntity() === Indicateur::ENTITY_STRUCTURE) { +// $rubriques = [ +// 'Code' => 'code', +// 'Libelle' => 'libelle_court', +// 'Libelle long' => 'libelle_long', +// 'Type' => 'type', +// +// ]; +// } +// if ($indicateur->getEntity() === Indicateur::ENTITY_AGENT) { +// $rubriques = [ +// 'ID' => 'c_src_individu', +// 'SOURCE' => 'c_source', +// 'Prenom' => 'prenom', +// 'Nom' => 'nom_usage', +// ]; +// } + /** RETRAIT DES RUBRIQUES ASSOCIEES AUX PERIMETRES */ - switch($indicateur->getPerimetre()) { - case Indicateur::PERIMETRE_STRUCTURE: $rubriques = array_diff($rubriques, ['perimetre_structure_id']); - break; + $perimetresActifs = []; + if ($indicateur->getPerimetre() !== null) { $perimetresActifs = explode(PerimetreServiceInterface::PERIMETRE_SEPARATOR, $indicateur->getPerimetre()); } + foreach ($perimetresActifs as $perimetre) { + $rubriques = array_diff($rubriques, ['perimetre_'.$perimetre.'_id']); } $data = []; @@ -343,25 +324,27 @@ class IndicateurService $exist = $this->verifierExistanceMaterializedView($indicateur->getViewId()); if (!$exist) return null; - $userPerimetre = $this->extractPerimetresValides($indicateur, $perimetres); + $userPerimetre = $this->extractPerimetres($perimetres); $rawdata = $this->fetch($indicateur, $userPerimetre); return count($rawdata); } /** - * @param Indicateur $indicateur * @param string[]|null $perimetres * @return string[] */ - public function extractPerimetresValides(Indicateur $indicateur, ?array $perimetres = null): array + public function extractPerimetres(?array $perimetres = null): array { + $array = []; + if ($perimetres === null) return []; - $indicateurPerimetre = $indicateur->getPerimetre(); - $perimetreValides = array_filter($perimetres, function(string $p) use ($indicateurPerimetre) { - return (strtolower(explode('_', $p)[0]) === strtolower($indicateurPerimetre)); - }); - $perimetresValides = array_map(function ($p) { return explode('_', $p)[1];}, $perimetreValides); - return $perimetresValides; + foreach ($perimetres as $perimetre) { + $perimetre = strtolower($perimetre); + [$type, $valeur] = explode('_', $perimetre); + $array[$type][] = $valeur; + } + + return $array; } } \ No newline at end of file diff --git a/src/UnicaenIndicateur/Service/Perimetre/PerimetreServiceAwareTrait.php b/src/UnicaenIndicateur/Service/Perimetre/PerimetreServiceAwareTrait.php index da45d603da76a1a61d0267e3f25c872783c9532e..3938e513b9c025e83ca8af305141fb9f7d059f4a 100644 --- a/src/UnicaenIndicateur/Service/Perimetre/PerimetreServiceAwareTrait.php +++ b/src/UnicaenIndicateur/Service/Perimetre/PerimetreServiceAwareTrait.php @@ -16,5 +16,4 @@ trait PerimetreServiceAwareTrait $this->perimetreService = $perimetreService; } - } \ No newline at end of file diff --git a/src/UnicaenIndicateur/Service/Perimetre/PerimetreServiceInterface.php b/src/UnicaenIndicateur/Service/Perimetre/PerimetreServiceInterface.php index f099ec6a7a75c46a19010e54373a708cd0c7069a..4fa49bf98ae14ff699d99e9e27838782efc05516 100644 --- a/src/UnicaenIndicateur/Service/Perimetre/PerimetreServiceInterface.php +++ b/src/UnicaenIndicateur/Service/Perimetre/PerimetreServiceInterface.php @@ -7,5 +7,9 @@ use UnicaenUtilisateur\Entity\Db\AbstractUser; interface PerimetreServiceInterface { + const PERIMETRE_SEPARATOR = '||'; + + public function setListePerimetres(array $liste): void; + public function getListePerimetres(): array; public function getPerimetres(AbstractUser $user, AbstractRole $role) : array; } \ No newline at end of file diff --git a/src/UnicaenIndicateur/Service/Perimetre/PerimetreServiceTrait.php b/src/UnicaenIndicateur/Service/Perimetre/PerimetreServiceTrait.php new file mode 100644 index 0000000000000000000000000000000000000000..1368e00547f4cfd4e284fed7b9ddae2b79f7f789 --- /dev/null +++ b/src/UnicaenIndicateur/Service/Perimetre/PerimetreServiceTrait.php @@ -0,0 +1,18 @@ +<?php + +namespace UnicaenIndicateur\Service\Perimetre; + +trait PerimetreServiceTrait { + + private array $perimetres = []; + + public function getListePerimetres(): array + { + return $this->perimetres; + } + + public function setListePerimetres(array $liste): void + { + $this->perimetres = $liste; + } +} \ No newline at end of file diff --git a/view/unicaen-indicateur/indicateur/afficher.phtml b/view/unicaen-indicateur/indicateur/afficher.phtml index 37409897fa2f99479b03e3378a807ec73982f14d..7943a6094375dd291b630aca513c33e8063d84e8 100644 --- a/view/unicaen-indicateur/indicateur/afficher.phtml +++ b/view/unicaen-indicateur/indicateur/afficher.phtml @@ -36,7 +36,7 @@ use UnicaenIndicateur\Entity\Db\Indicateur; <?php else : ?> <?php /** @see IndicateurController::exportAction() */ ?> <a href="<?php echo $this->url('indicateur/exporter', ['indicateur' => $indicateur->getId()], [], true); ?>" - class="btn btn-primary action" + class="btn btn-primary" > <span class="icon icon-csv"></span> Exporter l'indicateur @@ -44,7 +44,7 @@ use UnicaenIndicateur\Entity\Db\Indicateur; <?php /** @see IndicateurController::rafraichirAction() */ ?> <a href="<?php echo $this->url('indicateur/rafraichir', ['indicateur' => $indicateur->getId()], [], true); ?>" - class="btn btn-primary action" + class="btn btn-primary" > <span class="icon icon-refresh"></span> Rafraichir l'indicateur diff --git a/view/unicaen-indicateur/indicateur/index.phtml b/view/unicaen-indicateur/indicateur/index.phtml index c3c5b98c24e687aa388c27a58a506bf3b11c5c9e..c5464bb3dab14c9cc1fc8e905b8d60a87193be5d 100644 --- a/view/unicaen-indicateur/indicateur/index.phtml +++ b/view/unicaen-indicateur/indicateur/index.phtml @@ -50,7 +50,7 @@ $canCategories = $this->isAllowed(IndicateurPrivileges::getResourceId(Indicateur <?php if ($canEditer) :?> <?php /** @see IndicateurController::creerAction() */?> <a href="<?php echo $this->url("indicateur/creer", [], [], true); ?>" - class="btn btn-primary ajax-modal action" data-event="modification" + class="btn btn-primary" > <span class="icon icon-ajouter"></span> Créer un nouvel indicateur @@ -58,7 +58,7 @@ $canCategories = $this->isAllowed(IndicateurPrivileges::getResourceId(Indicateur <?php /** @see AbonnementController::notifierAction() */?> <a href="<?php echo $this->url("abonnement/notifier", [], [], true); ?>" - class="btn btn-primary action" + class="btn btn-primary" > <span class="icon icon-mail"></span> Notifier