From 026f6fb0a87e67b99844d47e3f1b6ab5e7afbd2d Mon Sep 17 00:00:00 2001 From: Etienne Pallier Date: Wed, 23 Sep 2020 13:44:21 +0200 Subject: [PATCH] Grosse amélioration et rationalisation de la gestion des notifications : log et/ou email (étape 3) : - généralisaiton des types de notifications : log ou/et email - notification envoyée systématiquement pour toute action de toute entité, via afterFilter(), et ensuite invalidée éventuellement si pas autorisée --- CHANGES.txt | 32 +++++++++++++++++++++++++++++--- PUSH_MODIFS | 11 +++++++++-- README.md | 4 ++-- src/Controller/AppController.php | 378 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------- src/Controller/DocumentsController.php | 39 ++++++++++++++++++++++++++++++--------- src/Controller/FournisseursController.php | 6 +----- src/Controller/MaterielsController.php | 432 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------------------ src/Controller/UsersController.php | 26 ++++++++++++++++++++++++-- 8 files changed, 696 insertions(+), 232 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 635a7c1..752c421 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -13,12 +13,24 @@ CHANGEMENTS ------- -11/09/2020 NEWS#3 (v3.7.9.100) : +23/09/2020 NEWS#4 (v4.103.3-3.7.9) : + +- Remaniement complet du système de notification : + - desormais, on notifie soit par mail, soit par log, soit par les 2 moyens (mail et log) + - toute action (création, modification, suppression...) faite sur toute entité (Materiel, Document, Suivi, Emprunt, ...) + peut désormais générer une notificaiton (email, log, ou les 2) à une liste configurable de destinataires prédéfinis (seulement pour les mails) + - par défaut, seules quelques actions de quelques entités importantes (matériels et documents) envoient des notifications + - la définition des actions "notifiantes" est configurable indépendamment pour chaque labo + (comme pour les acls, au niveau du code source, pas encore via la BD, ca viendre plus tard...) - La sélection d'un "gestionnaire de référence" est désormais obligatoire lors de la validation d'une fiche matériel. Par défaut, si c'est un gestionnaire qui valide (et c'est normalement le cas...), c'est lui qui est mis comme "gestionnaire de référence" (sauf s'il y en avait déjà un de déclaré avant) + +------- +11/09/2020 NEWS#3 (v3.7.9.100) : + - Nouvelle entité "Projet", à laquelle un matériel peut (ou pas) être associé - Nouveau filtre de la liste des matériels (index) => par "Projet" @@ -94,8 +106,22 @@ Outre ces changements, voici d'autres changements importants : ======= CHANGES ======= ------- -18/09/2020 v4.103.0-3.7.9 (EP) - - (e) Grosse amélioration et rationalisation de la gestion des emails (étape 1 sur 2) +22/09/2020 v4.103.3-3.7.9 (EP) + - (i) Grosse amélioration et rationalisation de la gestion des notifications : log et/ou email (étape 3) : + - (i) généralisaiton des types de notifications : log ou/et email + - (i) notification envoyée systématiquement pour toute action de toute entité, via afterFilter(), + et ensuite invalidée éventuellement si pas autorisée + +------- +22/09/2020 v4.103.2-3.7.9 (EP) + - (e) Grosse amélioration et rationalisation de la gestion des emails (étapes 1 et 2) : + - une seule fonction sendmail(), suppression de sendEmail() + - meilleur algo général + - toute entité peut envoyer un email (Materiel, Document, Suivi, Emprunt, ...) + - on peut définir au niveau de chaque entité, quelle(s) action(s) envoient un mail + - cette définition est configurable pour chaque labo + (comme pour les acls, au niveau du code source, pas encore via la BD, ca va viendre plus tard...) + ------- 17/09/2020 v4.102.0-3.7.9 (EP) diff --git a/PUSH_MODIFS b/PUSH_MODIFS index e9a12d2..f03a7af 100755 --- a/PUSH_MODIFS +++ b/PUSH_MODIFS @@ -1,11 +1,18 @@ #!/usr/bin/env bash # 1) Mise à jour du code source actuel +echo +echo "Mise à jour du code source actuel :" ./UPDATE +echo -exit # 2) Envoi de mes modifs (sur la branche en cours, a priori master) +echo +echo "Voulez-vous vraiment envoyer ces modifications sur le dépot officiel du logiciel LabInvent (o/n) ? [o]" +read do_it ; [[ -z $do_it ]] && do_it="o" +#echo $do_it +[[ $do_it != "o" ]] && exit 0 git add . git commit -m "Ajout de mes modifications" git push - +echo diff --git a/README.md b/README.md index 331956b..fb08944 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,8 @@ Logiciel testé et validé sur les configurations suivantes : -------------------------------------------------------------------------------------------- -Date: 18/09/2020 -Version: 4.103.0-3.7.9 +Date: 22/09/2020 +Version: 4.103.3-3.7.9 HISTORIQUE DES CHANGEMENTS DE VERSION : voir le fichier CHANGES.txt (ou la page web /pages/changes) diff --git a/src/Controller/AppController.php b/src/Controller/AppController.php index e015640..7fd5edf 100755 --- a/src/Controller/AppController.php +++ b/src/Controller/AppController.php @@ -67,6 +67,9 @@ class AppController extends Controller // - ATTRIBUTS VARIABLES + // Par défaut, genre masculin + protected $is_masculin = true; + // (EP) Seulement pour les tests // Permet à un test de forcer (si true) le re-chargement d'une entité (car modifiée en BD) protected static $RELOAD = FALSE; @@ -192,15 +195,44 @@ class AppController extends Controller ]; */ + + + /* + * + * Tableau (array) des actions autorisées à envoyer des notifications (log et/ou email) + * + * 'log' = logger seulement + * 'mail' => envoyer un mail seulement + * 'both' = faire les 2 (logger ET envoyer un mail) + * + * Hérité par CHAQUE controleur (qui a donc sa propre instance de ce tableau, indépendante des instances des autres controleurs) + * + * On l'initialise déjà avec les actions autorisées par défaut, pour tout controleur + * On le complètera ensuite pour les autres actions + * + * protected $notifier_actions = [ + 'add' => 'both', + 'edit' => 'log', + 'delete' => 'both', + // ... + ]; + * + * Par défaut => aucune action autorisée + * + */ + protected $notifier_actions = []; + + /* - * Tableau des autorisations pour les actions du controleur + * Tableau (array) des autorisations pour les actions du controleur * * Hérité par CHAQUE controleur (qui a donc sa propre instance de ce tableau, indépendante des instances des autres controleurs) * - * On l'initialise déjà avec les actions autorisées par défaut + * On l'initialise déjà avec les actions autorisées par défaut, pour tout controleur * On le complètera ensuite pour les autres actions - //protected $is_authorized_action = []; - // Pour tous les controleurs + * + * Par défaut => aucune action autorisée + * */ protected $is_authorized_action = []; /* @@ -294,6 +326,43 @@ class AppController extends Controller ) ); // $easyACL + + const actionNounAndPastVerbs = [ + // C + 'add' => ['Ajout','ajouté'], + // R + 'view' => ['Visualisation (détail)','visualisé'], + 'index' => ['Visualisation (liste)','visualisé'], + // U + 'edit' => ['Modification','modifié'], + // D + 'delete' => ['Suppression','supprimé'], + ]; + + + protected function is_vowel($char) { return in_array($char, ['a','e','i','o','u','y']); } + + // $form=1 => 'le', 'la', ou "l'" + // $form=2 => 'du' ou 'de la' ou "de l'" + // $form=3 => "d'un" ou "d'une" + protected function getMyArticle($form=1) { + $first_char_is_vowel = $this->is_vowel(substr($this->getName(),0,1)); + // $form=1 => 'Le', 'La', ou "L'" + if ($form==1) { + // Si commence par voyelle => "L'" (L'emprunt, L'utilisateur, L'entité...) + if ($first_char_is_vowel) return "l'"; + return $this->is_masculin ? "le" : "la"; + } + // $form=2 => 'du' ou 'de la' ou "de l'" + elseif ($form==2) { + if ($first_char_is_vowel) return "de l'"; + return $this->is_masculin ? "du" : "de la"; + } + // $form=3 => "d'un" ou "d'une" + else + return $this->is_masculin ? "d'un" : "d'une"; + } + public function d($msg) { if ( $this->DEBUG || $this->isLabinventDebugMode() ) pr($msg); @@ -309,6 +378,28 @@ class AppController extends Controller return 'nom'; } + /* + * Retourne ['nom','verbe_au_passé'] correspondants à l'action $action + * + * ex: + * => ['Ajout','ajouté'] pour l'action 'add' + * => ['Modification','modifié'] pour l'action 'edit' + * ... + * + * Actions générales : add, edit, delete, view... + * + */ + protected function getActionNounAndPastVerb($action) { + //if (in_array($action, array_keys($this->actionNounAndPastVerbs))) return $this->actionNounAndPastVerbs[$action]; + if (in_array($action, array_keys($this->actionNounAndPastVerbs))) return $this->actionNounAndPastVerbs[$action]; + if (in_array($action, array_keys(AppController::actionNounAndPastVerbs))) return AppController::actionNounAndPastVerbs[$action]; + // Pas de définition pour cette action + //return [null,null]; + // par défaut, par exemple 'edit-ion' et 'edit-é' pour action 'edit' + return [$action.'ion', $action.'é']; + } + + /* * Retourne le matériel courant, c'est à dire : @@ -326,6 +417,27 @@ class AppController extends Controller */ /** + * + * (EP 20200922) NEW NOTIFICATIONS MANAGEMENT + * + */ + protected function setNotificationAllowedOnActions(array $actions) { + $this->notifier_actions = $actions; + } + protected function isNotifierAction($action) { + //debug($action); + //debug($this->notifier_actions); + return in_array( $action, array_keys($this->notifier_actions) ); + } + protected function isNotifierActionSendingLog($action) { + return $this->isNotifierAction($action) && in_array( $this->notifier_actions[$action], ['log','both'] ); + } + protected function isNotifierActionSendingEmail($action) { + return $this->isNotifierAction($action) && in_array( $this->notifier_actions[$action], ['mail','both'] ); + } + + + /** * (EP 20200525) NEW ACL * * @param string $action @@ -753,7 +865,10 @@ class AppController extends Controller $condition_result = $condition_on_status_result && $condition_on_belonging_result; $this->d("2) Condition globale (a && b) evaluée à :"); $this->d2($condition_result); return $condition_result; - } + + } // isAuthorizedActionForCurrentUser() + + /* * Fonction récursive qui évalue une condition de statut matériel. @@ -1092,6 +1207,18 @@ class AppController extends Controller return (int) $this->request->getParam('pass.0'); } + + /* + * Liste minimum d'entités associées à charger lorsqu'on récupère une entité + * + * Par défaut => vide + * + * Peut être surchargé par chaque controleur + */ + protected function getMinimumListOfRelatedEntitiesToLoad() { + return []; + } + /* (EP 20200428) * * Méthode pour optimiser les accès à la BD. @@ -1108,7 +1235,7 @@ class AppController extends Controller // PHP7 only //protected function getEntity($id=null) : Entity { // PHP>=5 - public function getEntity($id=null, $WITH_RELATED_MATERIEL=false) { + public function getEntity($id=null, $WITH_RELATED_MATERIEL=false, $WITH_ASSOCIATED_ENTITIES=true) { // Si pas d'id => exception (stop) //assert($this->e_id>0); if (!$this->e_id && !$id) throw new \Exception(__("cette methode doit etre appelée avec un id déjà positionné !!!")); @@ -1143,7 +1270,10 @@ class AppController extends Controller */ //ex: if (! $this->e) $this->e = $this->Materiels->get($this->e_id); //$this->e = $this->$model->get($this->e_id); - $related_entities = $WITH_RELATED_MATERIEL ? ['Materiels']:[]; + //$related_entities = $WITH_RELATED_MATERIEL ? ['Materiels']:[]; + $related_entities = []; + if ($WITH_ASSOCIATED_ENTITIES) $related_entities = $this->getMinimumListOfRelatedEntitiesToLoad(); + if ($WITH_RELATED_MATERIEL) $related_entities[] = 'Materiels'; $this->e = $this->$model->get($id, ['contain'=>$related_entities]); $this->e_id = $this->e->id; } @@ -1834,6 +1964,7 @@ class AppController extends Controller */ } // beforeFilter() + /** * Add or Edit method (do either add() or edit()) @@ -2037,6 +2168,9 @@ class AppController extends Controller public function afterFilter(Event $event) { + + parent::afterFilter($event); + $this->myDebug("step ?? (general): AppController.afterFilter()"); // Tout le temps 'index', why ??N //debug($this->request->getAttribute('params')['action']); @@ -2048,6 +2182,34 @@ class AppController extends Controller else if ($this->request->getAttribute('params')['action'] != 'creer') $this->request->getSession()->write("retourForm1", false); //exit; + + /* + * A la fin de l'action, envoi d'une notification + * - ssi entité définie + * ET + * - ssi autorisée + * ET + * - pour 'add' et 'edit' : seulement si il y eu un POST de data + */ + //debug($this->e); + //if ($this->e) $emails = $this->sendNotificationForEntityAction($this->e); + //$action = $this->request->getAttribute('params')['action']; + if ( + // Pour toutes les actions autres que 'add' ou 'edit' + ! in_array($this->a,['add','edit']) + || + // Ou bien pour les actions 'add' ou 'edit' après un POST (pas avant) + $this->request->is(['post','patch','put']) + //( in_array($this->a,['add','edit']) && $this->request->is(['post','patch','put']) ) + ) { + //debug("hi"); exit; + //debug($this->e); exit; + //$emails = $this->sendNotificationForEntityAction($this->e); + $emails = $this->sendNotificationForEntityAction(); + } + //debug($emails); + //exit; + } /** @@ -2330,8 +2492,9 @@ class AppController extends Controller // "le materiel", "le suivi", "l'emprunt", "la catégorie"... + // Par défaut public function getArticle() { return "Le "; } - + static function isLabinventDebugMode() { return TableRegistry::getTableLocator()->get('Configurations')->find()->first()->mode_debug; @@ -2351,6 +2514,10 @@ class AppController extends Controller * */ function ilog($msg=null) { + + // true => n'envoie pas de log + $DEBUG = true; + //$controller = $this->request->getParam('controller'); //$action = $this->getActionPassed(); $role = $this->getUserRole(); @@ -2364,7 +2531,9 @@ class AppController extends Controller //debug("$url fait par $user ($role) ($msg)"); //$this->log("$url fait par $user ($role). $msg", 'debug'); //Log::write('info', "$url fait par $user ($role). $msg"); - $this->log("$url fait par $user ($role). $msg\n", 'info'); + $msg = "$url fait par $user ($role) - $msg\n"; + $DEBUG && debug($msg); + (!$DEBUG) && $this->log($msg, 'info'); /* Autres formes possibles @@ -2731,21 +2900,31 @@ class AppController extends Controller //public function sendmail(\App\Model\Entity $entity, $mode=3, $subject = null, $msg = null) //public function sendmail(\App\Model\Entity\Materiel $entity, $mode=3, $subject = null, $msg = null) // PHP5 : - public function sendmail($entity, $mode=3, $subject = null, $msg = null) - { - - $DEBUG = false; + // @obsolete + public function sendmail($entity, $mode=3, $subject = null, $msg = null) { + $this->sendNotificationForEntityAction($mode,$subject,$msg); + } + public function sendNotificationForEntityAction($mode=3, $subject = null, $msg = null) { + //return null; - // Si les deux cases "Activer l'envoi des mails.." sont décochées, on se fatigue pas à exécuter la fonction - $configuration = $this->confLabinvent; - if (!$configuration->envoi_mail && !$configuration->envoi_mail_guests) return null; + // true => n'envoie pas de notif + $DEBUG = true; + + // Entité (Entity) + // Si pas d'entité définie => return + $entity = $this->e; + if ( !$entity ) return null; + + // Action + //$action = $this->request->getAttribute('params')['action']; // add or edit or delete or ... + $action = $this->a; - // Si l'action n'est pas autorisée à déclencher un mail, on quitte - $action = $this->request->getAttribute('params')['action']; // add or edit or delete or ... + // Si l'action n'est pas autorisée à déclencher une notification => on quitte // $this pointe sur le controleur en cours qui a appelé sendmail, par exemple MaterielsController ou DocuentsController... // Donc c'est la methode is_action_with_email() de ce controleur spécifique qui est appelée - if (! in_array($action, $this->get_actions_with_email()) ) return null; - + //if (! in_array($action, $this->get_actions_with_email()) ) return null; + if ( !$this->isNotifierAction($action) ) return null; + //debug("notify"); exit; /* $all_actions_autorisees = [ 'Materiel' => ['add', 'delete'], @@ -2785,17 +2964,112 @@ class AppController extends Controller // ex: 'Etienne Pallier' $acteur = $_SESSION['Auth']['User']['givenname'][0] . ' ' . $_SESSION['Auth']['User']['sn'][0]; - - $materiel = null; + $user = $this->getCurrentUserName(); + + $action_noun_and_verb = $this->getActionNounAndPastVerb($action); + $action_noun = $action_noun_and_verb[0]; + $action_verb = $action_noun_and_verb[1]; + //$entity_type = $this->getEntityTypeName(); + $entity_type = strtolower( substr($this->getName(),0,-1) ); + $article_le = $this->getMyArticle(1); + $article_dun = $this->getMyArticle(3); + $id = $entity->id; + + $materiel = null; + + + + /* + * 2) LOG + */ + + // ex: "Matériel ajouté = 'toto' (id=15)" + // ex: "Document modifié = 'doc-toto' (id=112)" + // ex: "Utilisateur connecté = 'Pierre Durand' (id=112)" + // ex: "Utilisateur déconnecté = 'Pierre Durand' (id=112)" + $msglog = "$entity_type $action_verb = '$entity' (id=$id)"; + //debug($msglog); + //(!$DEBUG) && + //$this->isNotifierActionSendingLog($action) && $this->ilog("$entity_name $action_verb = '$entity' (id=$id)"); + $this->isNotifierActionSendingLog($action) && $this->ilog($msglog); + /* - * 2) CRÉATION DU MAIL (sujet et body) + * 3) CRÉATION DU MAIL (sujet et body) * * On détermine le message et le sujet du mail en fonction de l'action effectuee * */ + // MESSAGE GÉNÉRIQUE + + // Sujet : + + $subject = $subject ? $subject : "$action_noun $article_dun $entity_type"; + debug($subject); + + // Message (body) : + + // - (1) TOUS : User a fait telle action (+url) + $msg_mail = $msg; + $msg_mail .= "$user a $action_verb $article_le $entity_type '$entity'"; + // (EP) Ajout de l'url (ou id) du materiel + $msg_mail .= $action=='delete' ? " (id=$id)" : " ($host/materiels/view/$id)"; + //$msg .= "\n\nURL de la fiche : $host/materiels/view/{$materiel->id}"; + // $msg .= "\n\n"; + + // - (2) Matos (direct ou associé) only : On ajoute quelques informations sur le matériel : domaine, catégorie, description + // Entités (Entity) associées à une entité Materiel (1-N) + $materiel = $entity; + $ENTITY_TYPE_LINKED = false; + $entity_types_linked_to_materiel = ['Suivi', 'Emprunt', 'Document']; + foreach ($entity_types_linked_to_materiel as $Entity_type_linked) + // Si c'est une entité liée et qu'elle a bien un Materiel associé + // (par exemple pour Document, ce n'est pas forcément le cas car il peut être associé à un Suivi et non un Materiel) + if ( is_a($entity, $Entity_type_linked) && $entity->materiel_id ) { + $materiel = $entity->Materiel; + $ENTITY_TYPE_LINKED = true; + break; + } + if ($entity instanceof Materiel || $ENTITY_TYPE_LINKED) { + //$materiel = $entity; + $msg_more = ''; + $fields = [ + 'sur_categorie_id' => ['sur_category', 'Domaine'], + 'categorie_id' => ['category', 'Catégorie'], + 'sous_categorie_id' => ['sous_category', 'Sous-catégorie'], + 'description' => ['hasnot!', 'Description'] + ]; + foreach ($fields as $fname=>$attrs) if ($materiel->$fname) { + $val = $materiel->has($attrs[0]) ? $materiel->{$attrs[0]}->nom : $materiel->$fname; + $msg_more .= "\n\n- $attrs[1] : " . $val; + } + if ($msg_more) $msg_mail .= "\n\nAttributs du matériel : $msg_more"; + } + + // - (3) Matos only (sauf delete, TBA et archive) : Veuillez vérifier... + $actions_no_need_to_be_checked = ['delete', 'statusTobearchived', 'statusArchived']; + if ( $entity instanceof Materiel && !in_array($action,$actions_no_need_to_be_checked) ) + $msg_mail .= "\n\nVeuillez vérifier et compléter si besoin la fiche correspondante."; + + // - (4) TOUS : Vous recevez ce message car... (raison) + //if ($entity != null) { + $msg_mail .= "\n\nVous recevez ce message car"; + $raison = " vous êtes concerné(e) par cette action effectuée sur l'inventaire des matériels du laboratoire"; + $raison .= "\n\n(vous êtes l'utilisateur du matériel, ou bien le gestionnaire, ou encore le responsable thématique, métier ou projet)."; + $msg_mail .= $raison; + //} + debug($msg_mail); + + // Par défaut + /* + $subject = "Action \"$action\" sur un matériel"; + $msg = "$acteur a effectué l'action \"$action\" sur le matériel \"$nom_materiel\""; + */ + + exit; + /* * - mail pour un MATERIEL */ @@ -2989,18 +3263,26 @@ class AppController extends Controller * ... etc ... (il faut qu'on soit plus précis) */ - // Pas de matériel défini => pas de mail (pas de bras, pas de chocolat) ! - if ($materiel == null) return null; - + /* - * 3) DESTINATAIRES : on construit la liste des destinataires + * 4) DESTINATAIRES du mail : on construit la liste des destinataires */ - + + // Si l'action n'est pas autorisée à envoyer un mai => on quitte + if (! $this->isNotifierActionSendingEmail($action) ) return null; + + // Si les deux cases "Activer l'envoi des mails.." sont décochées, on se fatigue pas à exécuter la fonction + $configuration = $this->confLabinvent; + if (!$configuration->envoi_mail && !$configuration->envoi_mail_guests) return null; + + // Pas de matériel défini => pas de mail (pas de bras, pas de chocolat) ! + if ($materiel == null) return null; + $mailList = []; /* - * 3a) Envoi général + * 4a) Envoi général * * Si l'envoi général est activé, on ajoute les mails des personnes concernées : * - le proprio (l'utilisateur) du matériel (sauf s'il est l'acteur de l'action) @@ -3046,17 +3328,19 @@ class AppController extends Controller */ $resp_mails = []; $groups_fk = [ 'groupes_metier_id', 'groupes_thematique_id' ]; - foreach ($groups_fk as $group_fk) if ($materiel->$group_fk) { - //$mailsRespMetier = TableRegistry::getTableLocator()->get('Users')->find() - $resp_mails[$group_fk] = TableRegistry::getTableLocator()->get('Users')->find() - ->select('email') - ->where([ - 'role =' => 'Responsable', - "$group_fk =" => $materiel->$group_fk - ]) - ->toArray(); + foreach ($groups_fk as $group_fk) { + $resp_mails[$group_fk] = []; + if ($materiel->$group_fk) + //$mailsRespMetier = TableRegistry::getTableLocator()->get('Users')->find() + $resp_mails[$group_fk] = TableRegistry::getTableLocator()->get('Users')->find() + ->select('email') + ->where([ + 'role =' => 'Responsable', + "$group_fk =" => $materiel->$group_fk + ]) + ->toArray(); } - $DEBUG && debug($resp_mails); + //$DEBUG && debug($resp_mails); //exit; /* if ($materiel->groupes_metier_id) { @@ -3084,7 +3368,7 @@ class AppController extends Controller //$resp_mails = array_values($resp_mails); //$resp_mails['groupes_metier_id']=[]; $resp_mails['groupes_thematique_id']=[]; $resp_mails = array_merge($resp_mails['groupes_metier_id'], $resp_mails['groupes_thematique_id']); - $DEBUG && debug($resp_mails); + //$DEBUG && debug($resp_mails); foreach ($resp_mails as $resp_mail) $mailList[] = $resp_mail['email']; //exit; /* @@ -3116,7 +3400,7 @@ class AppController extends Controller } // si envoi général activé /* - * 3b) Envoi à la liste spécifique + * 4b) Envoi à la liste spécifique * * Si l'envoi à la liste spécifique est activé, * on ajoute simplement TOUS les mails de cette liste, @@ -3142,7 +3426,7 @@ class AppController extends Controller } /* - * 3c) On supprime + * 4c) On supprime * - les doublons éventuels * ainsi que * - l'auteur de l'action (puisqu'il est déjà au courant) @@ -3158,12 +3442,12 @@ class AppController extends Controller $mailList = array_map('strtolower', $mailList); // - on supprime les doublons $mailList = array_unique($mailList); - $DEBUG && debug($mailList); + //$DEBUG && debug($mailList); // - on supprime l'auteur de l'action le cas échéant //if ($DEBUG) debug($this->u->email); $found = array_search(strtolower($this->u->email), $mailList); //$found = array_search('nathalie.baby@irap.omp.eu', $mailList); - $DEBUG && debug($found); + //$DEBUG && debug($found); if ($found !== false) unset($mailList[$found]); // Eventuellement, pour renuméroter (supprime les indices manquants) sort($mailList); @@ -3207,7 +3491,7 @@ class AppController extends Controller /* - * 5) ENVOI : enfin, on envoie le mail à toute la liste des destinataires + * 5) ENVOI DU MAIL : enfin, on envoie le mail à toute la liste des destinataires */ // On dédoublonne la liste des mails pour éviter de spammer les gens, non mais ! @@ -3229,7 +3513,7 @@ class AppController extends Controller $role = "car vous etes dans la liste spécifique des emails de LabInvent."; $role .= "\n\nPour faire retirer votre mail de cette liste, veuillez contacter un super-administrateur."; */ - $role = "car vous êtes concerné(e) par cette action effectuée sur l'inventaire des matériels du laboratoire."; + $role = "car vous êtes concerné(e) par cette action effectuée sur l'inventaire des matériels du laboratoire"; $role .= "\n\n(vous êtes l'utilisateur du matériel, ou bien le gestionnaire, ou encore le responsable thématique, métier ou projet)."; /* (EP 13/319) : à quoi sert toute cette suite du texte du mail ??? * Ca sent le bon vieux copier-coller sans réfléchir... @@ -3258,7 +3542,7 @@ class AppController extends Controller //debug($message); exit; //debug($mode); - switch($mode) { + if (! $DEBUG) switch($mode) { //si le mode 1 est sélectionné c'est un envoi de mail avec ajout d'une photo //explique le document qui a été ajouté, et le met en pièce jointe diff --git a/src/Controller/DocumentsController.php b/src/Controller/DocumentsController.php index 3e31d1d..205bfbb 100755 --- a/src/Controller/DocumentsController.php +++ b/src/Controller/DocumentsController.php @@ -20,6 +20,11 @@ class DocumentsController extends AppController // Formats autorisés pour photo var $photo_formats = ['png','jpg','jpeg']; + // @override parent + protected $actionNounAndPastVerbs = [ + 'mailDevis' => ['Partage','partagé'], + ]; + // private pour qu'elle ne puisse pas être appelée via url comme une action private function is_photo_type_from_extension($doc) { return in_array($doc->type_doc, $this->photo_formats); @@ -31,6 +36,31 @@ class DocumentsController extends AppController //@Override parent protected function setAuthorizations() { + + /* + * a) Actions de ce controleur qui enverront des notifications (log et/ou email) + * + * 'log' = logger seulement + * 'mail' => envoyer un mail seulement + * 'both' = faire les 2 (logger ET envoyer un mail) + * + */ + $this->setNotificationAllowedOnActions([ + 'add' => 'both', + 'edit' => 'log', + 'delete' => 'both', + // ... + ]); + /* + $this->setNotificationAllowedOnActions([ + 'add', 'edit', 'delete', + 'view', + // ... + ]); + */ + + // b) Règles d'accès (ACLs) + // Action 'add' (ajout d'une nouvelle entité) : statut quelconque mais doit appartenir au user // Proprio only $this->setAuthorizationsForAction('add', [0,1], [ @@ -928,15 +958,6 @@ class DocumentsController extends AppController } - // Actions autorisées à envoyer un email - //@Override parent - protected function get_actions_with_email() { - return [ - 'add', 'edit', 'delete', - // ... - ]; - } - public function ficheMetrologique($id) { diff --git a/src/Controller/FournisseursController.php b/src/Controller/FournisseursController.php index b43b3b6..9f78fe4 100644 --- a/src/Controller/FournisseursController.php +++ b/src/Controller/FournisseursController.php @@ -143,11 +143,7 @@ class FournisseursController extends AppController public function edit($id = null) { $fournisseur = $this->Fournisseurs->get($id); - if ($this->request->is([ - 'patch', - 'post', - 'put' - ])) { + if ($this->request->is(['patch','post','put'])) { $fournisseur = $this->Fournisseurs->patchEntity($fournisseur, $this->request->getData()); if ($this->Fournisseurs->save($fournisseur)) { $this->Flash->success(__('Le fournisseur a bien été édité.')); diff --git a/src/Controller/MaterielsController.php b/src/Controller/MaterielsController.php index 130f3d1..fc615e6 100755 --- a/src/Controller/MaterielsController.php +++ b/src/Controller/MaterielsController.php @@ -53,6 +53,18 @@ class MaterielsController extends AppController { ); + // @override parent + protected $actionNounAndPastVerbs = [ + 'statusCreated' => ['Dé-validation','dé-validé'], + 'statusValidated' => ['Validation','validé'], + //TODO: spécial + 'statusTobearchived' => ["Demande d'archivage","demandé l'archivage", '', "d'un"], + 'statusValidated' => ['Archivage','archivé'], + 'setLabelIsPlaced' => ["Positionnement d'étiquette","posé l'étiquette", 'sur'], + 'printLabelRuban' => ["Impression de l'étiquette", "imprimé l'étiquette", "d'un", 'sur'], + ]; + + // EP 08/2017 // protected $easyACL = array( const OLD_easyACL = array( @@ -173,6 +185,15 @@ class MaterielsController extends AppController { } + // @override parent + // Default 'contain' + protected function getMinimumListOfRelatedEntitiesToLoad() { + return [ + 'SurCategories', 'Categories', 'SousCategories' + ]; + } + + /* * Cette méthode est appelée pendant l’event Controller.initialize qui se produit avant chaque action du controller. * C’est un endroit pratique pour vérifier le statut d’une session ou les permissions d’un utilisateur. @@ -261,6 +282,167 @@ class MaterielsController extends AppController { return 'designation'; } + + /* + * @Override + * + * Initialisation des autorisations PAR DÉFAUT (générales à tous les labos) pour les actions de ce controleur + * + */ + protected function setAuthorizations() { + //debug("GENERIC!"); + + /* + * a) Actions de ce controleur qui enverront des notifications (log et/ou email) + * + * 'log' = logger seulement + * 'mail' => envoyer un mail seulement + * 'both' = faire les 2 (logger ET envoyer un mail) + * + */ + $this->setNotificationAllowedOnActions([ + 'add' => 'both', + 'edit' => 'log', + 'delete' => 'both', + //'view', + 'statusCreated' => 'log', + 'statusTobearchived' => 'both', + 'statusValidated' => 'both', + 'statusArchived' => 'both', + // ... + ]); + /* + $this->setNotificationAllowedOnActions([ + 'add', 'edit', 'delete', + //'view', + 'statusCreated', 'statusTobearchived', 'statusValidated', 'statusArchived', + // ... + ]); + */ + + // b) Règles d'accès (ACLs) + + // - Action 'add' (ajout d'un nouveau matériel) => autorisé pour tous + //$this->setAuthorizationsForAction('add', 0); + $this->setAuthorizationsForAction('add (créer)', 0); + //$this->setAuthorizationsForAction('view', 0); + + // - Action 'add' (ajout d'un nouveau matériel par copie d'un autre) + $this->setAuthorizationsForAction('add_by_copy (ajout par copie)', ['CREATED',0], [ + 'user' => ['CREATED',1], + //'resp' => ['CREATED',0], + //'resp' => 'default', + //$admin = 'default', + //$super = 'default' + ]); + + /* Actions autorisées par défaut par AppController : index et view + // - Action 'index' (affichage de la liste des matériels) + $this->setAuthorizationsForAction('index', + $default = [0,0] // = + vue spécialisée PAR statut + //$user = 'default', // vue simplifiée tout statut confondu (sauf ARCHIVED) + //$resp = 'default', + //$admin = 'default', + //$super = 'default' + ); + // - Action 'view' (vue détaillée d'un matériel) + $this->setAuthorizationsForAction('view', + $default = [0,0] + //$user = 'default', + //$resp = 'default', + //$admin = 'default', + //$super = 'default' // + champs techniques + ); + */ + + // - Action 'edit' (modif d'un matériel) + $this->setAuthorizationsForAction('edit (modifier)', ['CREATED',0], [ + 'user' => ['CREATED',1], + 'resp' => 'user', + //'resp' => -1, + //'resp' => 0, + //'resp' => ['CREATED',1], + //$admin = 'default', + //$super = 'default' // + champs techniques + ]); + + // Action 'delete' (suppression d'un matériel) + $this->setAuthorizationsForAction('delete (supprimer)', ['CREATED',1]); + + // Action 'devalidate' ou 'invalidate' (repasser le matériel au statut 'CREATED', c'est à dire le dé-valider ou l'invalider) + // (VALIDATED ou TBA ou ARCHIVED) => CREATED + //$this->setAuthorizationsForAction('devalidate', + $this->setAuthorizationsForAction('statusCreated (dévalider)', ['NOT CREATED',0], [ + 'user' => -1, // PAS AUTORISÉ + 'resp' => ['NOT CREATED',1] + ]); + + // Action 'updgrade' (avancement du statut d'un matériel) + // CREATED => VALIDATED => TBA => ARCHIVED + /* + $this->setAuthorizationsForAction('upgrade', ['NOT ARCHIVED',0], [ // En fait, l'action fait juste passer au statut "suivant" + //$default = ['PREVIOUS',0], // le matériel doit avoir le statut "précédent" du statut actuel + 'user' => ['VALIDATED',1], // SEULEMENT l'action "demande d'archivage" + //$resp = ['VALIDATED',1] // SEULEMENT l'action "demande d'archivage" + //'resp' => 'Utilisateur' + 'resp' => 'user' + ]); + */ + // Action 'updgrade' (avancement du statut d'un matériel) + // - Validation d'un materiel (passe à VALIDATED) : CREATED => VALIDATED + $this->setAuthorizationsForAction('statusValidated (valider)', ['CREATED',0], [ + 'user' => -1, // interdit + 'resp' => -1 // interdit + ]); + // - Demande d'archivage : VALIDATED => TBA + $this->setAuthorizationsForAction("statusTobearchived (demander l'archivage)", ['VALIDATED',0], [ + //$user = ['default',1], + 'user' => ['VALIDATED',1], + //$resp = ['default',1] + //$resp = ['VALIDATED',1] + 'resp' => 'user' + ]); + // - Archivage : TBA => ARCHIVED + $this->setAuthorizationsForAction('statusArchived (archiver)', ['TOBEARCHIVED',0], [ + 'user' => -1, // interdit + 'resp' => -1 // interdit + ]); + + // Action 'printLabelRuban' (impression d'une étiquette) + $this->setAuthorizationsForAction('printLabelRuban (imprimer étiquette)', ['VALIDATED && conf.hasPrinter',0] ); + $this->setAuthorizationsForAction('setLabelIsPlaced (déclarer étiquette collée)', ['VALIDATED && conf.hasPrinter',0] ); + $this->setAuthorizationsForAction('setLabelIsNotPlaced', ['VALIDATED && conf.hasPrinter',0] ); + /* + $this->setAuthorizationsForAction('setLabelIsPlaced', 0); // autorisé sans condition + $this->setAuthorizationsForAction('setLabelIsNotPlaced', 0); // autorisé sans condition + */ + + // Action 'execActions' + $this->setAuthorizationsForAction('execActions', 0, [ // par défaut autorisé sans condition + // sauf pour user et resp + 'user' => -1, // PAS AUTORISÉ + 'resp' => -1 // PAS AUTORISÉ + ]); + // Action 'export' + $this->setAuthorizationsForAction('export', 0, [// autorisé sans condition + 'user' => -1 // interdit + ]); + $this->setAuthorizationsForAction('getDateGarantie', 0); // autorisé sans condition + + /* + // Action 'ficheMateriel' + $this->setAuthorizationsForAction('createDocFicheMateriel', 0); + // Action 'ficheMaterielPdf' + // DOMPDF + $this->setAuthorizationsForAction('createDocFicheMaterielPdf', 0); + */ + + //debug($this->is_authorized_action);exit; + + } // _setAuthorizations() + + + /* * Méthode de définition des autorisations SPÉCIFIQUES au laboratoire IRAP * @@ -282,8 +464,18 @@ class MaterielsController extends AppController { // 1) On appelle d'abord la méthode générale $this->setAuthorizations(); - // 2) Puis on fait nos petites règles locales pour notre labo à nous tout seul + // 2) Puis on fait nos petites règles locales pour notre petit labo à nous tout seul + /* + // a) Adaptation des règles de notification + // Actions de ce controleur qui enverront des notifications (emails) + $this->setNotificationAllowedOnActions([ + 'add', 'edit', 'delete', + 'statusCreated', 'statusTobearchived', 'statusValidated', 'statusArchived', + // ... + ]); + + // b) Adaptation des règles d'accès (ACLs) // - Adaptation de la règle pour "ajout par copie" $this->setAuthorizationsForAction('add_by_copy', '', ['CREATED',0], [ 'user' => ['CREATED',1], @@ -374,136 +566,6 @@ class MaterielsController extends AppController { return in_array($status, array_keys(self::statuses)); } - /* - * @Override - * - * Initialisation des autorisations PAR DÉFAUT (générales à tous les labos) pour les actions de ce controleur - * - */ - protected function setAuthorizations() { - //debug("GENERIC!"); - - // Action 'add' (ajout d'un nouveau matériel) => autorisé pour tous - //$this->setAuthorizationsForAction('add', 0); - $this->setAuthorizationsForAction('add (créer)', 0); - //$this->setAuthorizationsForAction('view', 0); - - // Action 'add' (ajout d'un nouveau matériel par copie d'un autre) - $this->setAuthorizationsForAction('add_by_copy (ajout par copie)', ['CREATED',0], [ - 'user' => ['CREATED',1], - //'resp' => ['CREATED',0], - //'resp' => 'default', - //$admin = 'default', - //$super = 'default' - ]); - - /* Actions autorisées par défaut par AppController : index et view - // - Action 'index' (affichage de la liste des matériels) - $this->setAuthorizationsForAction('index', - $default = [0,0] // = + vue spécialisée PAR statut - //$user = 'default', // vue simplifiée tout statut confondu (sauf ARCHIVED) - //$resp = 'default', - //$admin = 'default', - //$super = 'default' - ); - // - Action 'view' (vue détaillée d'un matériel) - $this->setAuthorizationsForAction('view', - $default = [0,0] - //$user = 'default', - //$resp = 'default', - //$admin = 'default', - //$super = 'default' // + champs techniques - ); - */ - - // Action 'edit' (modif d'un matériel) - $this->setAuthorizationsForAction('edit (modifier)', ['CREATED',0], [ - 'user' => ['CREATED',1], - 'resp' => 'user', - //'resp' => -1, - //'resp' => 0, - //'resp' => ['CREATED',1], - //$admin = 'default', - //$super = 'default' // + champs techniques - ]); - - // Action 'delete' (suppression d'un matériel) - $this->setAuthorizationsForAction('delete (supprimer)', ['CREATED',1]); - - // Action 'devalidate' ou 'invalidate' (repasser le matériel au statut 'CREATED', c'est à dire le dé-valider ou l'invalider) - // (VALIDATED ou TBA ou ARCHIVED) => CREATED - //$this->setAuthorizationsForAction('devalidate', - $this->setAuthorizationsForAction('statusCreated (dévalider)', ['NOT CREATED',0], [ - 'user' => -1, // PAS AUTORISÉ - 'resp' => ['NOT CREATED',1] - ]); - - // Action 'updgrade' (avancement du statut d'un matériel) - // CREATED => VALIDATED => TBA => ARCHIVED - /* - $this->setAuthorizationsForAction('upgrade', ['NOT ARCHIVED',0], [ // En fait, l'action fait juste passer au statut "suivant" - //$default = ['PREVIOUS',0], // le matériel doit avoir le statut "précédent" du statut actuel - 'user' => ['VALIDATED',1], // SEULEMENT l'action "demande d'archivage" - //$resp = ['VALIDATED',1] // SEULEMENT l'action "demande d'archivage" - //'resp' => 'Utilisateur' - 'resp' => 'user' - ]); - */ - // Action 'updgrade' (avancement du statut d'un matériel) - // - Validation d'un materiel (passe à VALIDATED) : CREATED => VALIDATED - $this->setAuthorizationsForAction('statusValidated (valider)', ['CREATED',0], [ - 'user' => -1, // interdit - 'resp' => -1 // interdit - ]); - // - Demande d'archivage : VALIDATED => TBA - $this->setAuthorizationsForAction("statusTobearchived (demander l'archivage)", ['VALIDATED',0], [ - //$user = ['default',1], - 'user' => ['VALIDATED',1], - //$resp = ['default',1] - //$resp = ['VALIDATED',1] - 'resp' => 'user' - ]); - // - Archivage : TBA => ARCHIVED - $this->setAuthorizationsForAction('statusArchived (archiver)', ['TOBEARCHIVED',0], [ - 'user' => -1, // interdit - 'resp' => -1 // interdit - ]); - - // Action 'printLabelRuban' (impression d'une étiquette) - $this->setAuthorizationsForAction('printLabelRuban (imprimer étiquette)', ['VALIDATED && conf.hasPrinter',0] ); - $this->setAuthorizationsForAction('setLabelIsPlaced (déclarer étiquette collée)', ['VALIDATED && conf.hasPrinter',0] ); - $this->setAuthorizationsForAction('setLabelIsNotPlaced', ['VALIDATED && conf.hasPrinter',0] ); - /* - $this->setAuthorizationsForAction('setLabelIsPlaced', 0); // autorisé sans condition - $this->setAuthorizationsForAction('setLabelIsNotPlaced', 0); // autorisé sans condition - */ - - // Action 'execActions' - $this->setAuthorizationsForAction('execActions', 0, [ // par défaut autorisé sans condition - // sauf pour user et resp - 'user' => -1, // PAS AUTORISÉ - 'resp' => -1 // PAS AUTORISÉ - ]); - // Action 'export' - $this->setAuthorizationsForAction('export', 0, [// autorisé sans condition - 'user' => -1 // interdit - ]); - $this->setAuthorizationsForAction('getDateGarantie', 0); // autorisé sans condition - - /* - // Action 'ficheMateriel' - $this->setAuthorizationsForAction('createDocFicheMateriel', 0); - // Action 'ficheMaterielPdf' - // DOMPDF - $this->setAuthorizationsForAction('createDocFicheMaterielPdf', 0); - */ - - //debug($this->is_authorized_action);exit; - - - - } // _setAuthorizations() - /** * @@ -568,7 +630,9 @@ class MaterielsController extends AppController { //$this->myDebug("isAuthorizedAction ? " . $this->OLD_isAuthorizedAction2($this, $this->userRole, $this->a, $id, $user)); $this->myDebug("isAuthorizedAction ? " . $this->OLD_isAuthorizedAction2($this, $this->user_role, $this->a, $id, $user)); //return $this->isAuthorizedActionForRole($role, $action, $id); // $user, $userCname - if ($action=='add' && $id>0) $action = 'add_by_copy'; + if ($action=='add' && $id>0) { + $action = 'add_by_copy'; + } return $this->isAuthorizedActionForCurrentUser($action, $id); // $user, $userCname } // isAuthorized() @@ -1195,7 +1259,6 @@ class MaterielsController extends AppController { debug($this->getEntity($id)->is_created); debug($this->getEntity($id)->is_validated); */ - $materiel = $this->Materiels->get($id, [ 'contain' => [ 'SurCategories', @@ -1215,6 +1278,7 @@ class MaterielsController extends AppController { 'Fournisseurs' ] ]); + $this->e = $materiel; $e = $materiel; // current user @@ -1483,6 +1547,10 @@ class MaterielsController extends AppController { */ //debug("1"); debug($_SESSION); + // (EP202009) moved to parent.afterFilter() + //$emails = $this->sendNotificationForEntityAction($materiel); + //debug($emails); + } // view @@ -1497,19 +1565,44 @@ class MaterielsController extends AppController { //protected function add_or_edit($IS_ADD, $id=null, $valeurs=null, $erreurs=null, protected function add_or_edit($IS_ADD, $id=null, $erreurs=null, // uniquement à cause de parent::add_or_edit() : - $entity_name=null, array $associated_entities=[], $with_parent=false) { + //debug("ici"); exit; - $this->myDebug("step 3: MaterielsController.add_or_edit()"); - $IS_EDIT = !$IS_ADD; - $usersTable = TableRegistry::getTableLocator()->get('Users'); - - // Set $materiel - $materiel = NULL; - + // Set $materiel : soit un matériel vide (ADD new), soit un matériel de la BD à modifier (EDIT et ADD par copie) + //$materiel = ($IS_ADD && !$id) ? $this->Materiels->newEntity() : $this->Materiels->get($id, ['contain' => []]); + //debug($this->e); debug($this->getEntity($id)); exit; + //$materiel = ($IS_ADD && !$id) ? $this->Materiels->newEntity() : $this->e; + //$materiel = ($IS_ADD && !$id) ? $this->Materiels->newEntity() : $this->getEntity($id); + $materiel = $IS_ADD ? $this->Materiels->newEntity() : $this->getEntity($id); + // ADD par copie : mettre id et numero labo à null + if ($IS_ADD && $id) { + // IMPORTANT: validate=False car sinon, les données sont validées avant la copie, + // et le numero_laboratoire est vu comme invalide car déjà utilisé et doit etre unique !!! + // et on a pour résultat : "le matériel n'a pas pu être ajouté" (sans savoir pourquoi !!!) + //$materiel = $this->Materiels->newEntity($this->getEntity($id)->toArray(), ['validate' => false]); + //$materiel = $this->Materiels->patchEntity($materiel, $this->getEntity($id, false, false)->toArray(), [ + $materiel = $this->Materiels->patchEntity($materiel, $this->Materiels->get($id, ['contain' => []])->toArray(), [ + 'validate' => false, + // Ne pas valider non plus les entités associées + /* + 'associated' => [ + 'SurCategories' => ['validate' => false], + 'Categories' => ['validate' => false], + 'SousCategories' => ['validate' => false], + ] + */ + ]); + // IMPORTANT: on ne doit pas laisser l'id égal à celui du matériel copié !!! il en faut un nouveau + $materiel->id = null; + // on supprime le champ numero_laboratoire car il va être généré automatiquement + //unset($materiel->numero_laboratoire); + $materiel->numero_laboratoire = null; + } + //debug($materiel); exit; + /* // ADD if ($IS_ADD) { // 1) on crée un materiel vide @@ -1517,8 +1610,11 @@ class MaterielsController extends AppController { // - add_by_copy : COPIE de materiel (on a cliqué sur "Copier ce materiel") => id passé en argument if (isset($this->request->getAttribute('params')['pass'][0])) { // On récupère le materiel à copier et on le copie dans $materiel + /S $materiel_to_copy = $this->Materiels->get($this->request->getAttribute('params')['pass'][0]); $materiel_to_copy = $materiel_to_copy->toArray(); + S/ + $materiel_to_copy = $this->e->toArray(); //var_dump($materiel_to_copy); ///foreach ($materiel_to_copy as $key=>$value) $materiel->$key = $value; // IMPORTANT: validate=False car sinon, les données sont validées avant la copie, @@ -1536,45 +1632,46 @@ class MaterielsController extends AppController { //$materiel->id = False; //unset($materiel->id); - /* + /S $attribute="[original]"; $materiel->$attribute = []; - */ + S/ //$materiel->id = FALSE; //$materiel->'[new]' => true, } // - NOUVEAU materiel (on a cliqué sur "Nouveau materiel") else { //$materiel = $this->Materiels->newEntity(); - /* (EP 20200505 plus nécessaire car on utilise désormais NULL) + /S (EP 20200505 plus nécessaire car on utilise désormais NULL) // Set default values : "N/A" $materiel->groupes_thematique_id = 1; $materiel->groupes_metier_id = 1; $materiel->site_id = 9; - */ + S/ } } // EDIT else { - /* + /S $this->log("Edit a doc1 !", 'debug'); Log::write('debug',"Edit a doc2 !"); $this->dlog("Edit a doc1 !"); - */ + S/ $materiel = $this->Materiels->get($id, [ 'contain' => [] // load associated entities ]); //$this->myDebug($materiel); //debug($materiel); } + */ - /* SI POST + /* SI POST... * Les données ont été saisies et postées * On va donc les sauvegarder */ - $authorized_actions = $IS_ADD ? ['post'] : ['post','patch','put']; //if ( $this->request->is(['post','patch','put']) ) { + $authorized_actions = $IS_ADD ? ['post'] : ['post','patch','put']; if ( $this->request->is($authorized_actions) ) { //debug($this->request->getData()); @@ -1594,7 +1691,6 @@ class MaterielsController extends AppController { // (1) On remplit $materiel avec les données de ce materiel $materiel = $this->Materiels->patchEntity($materiel, $this->request->getData()); - //debug($materiel); exit; /* // AVIRER @@ -1655,12 +1751,16 @@ class MaterielsController extends AppController { $verb = $IS_ADD ? "ajouté" : "modifié"; //$action = $IS_ADD ? "add" : "edit"; //debug($materiel); exit; - if (! $this->Materiels->save($materiel)) { $this->myDebug($materiel->getErrors()); + debug($materiel->getErrors()); $this->Flash->error(__("Le matériel n'a pas pu être $verb")); } else { + //debug("iciii"); exit; + // (EP202009) $this->e doit refléter le matériel mis à jour + $this->e = $materiel; + /* debug($materiel->getErrors('jkl')); exit; if ($materiel->getError('numero_laboratoire')) { @@ -1672,11 +1772,12 @@ class MaterielsController extends AppController { if ($IS_ADD) { //(EP202009) //$this->sendEmail($materiel); - $this->sendmail($materiel); + ///////$this->sendmail($materiel); $id = $materiel->id; + //debug($this->e->id);exit; } //$this->dlog("Materiel $verb = '$materiel->designation' (id=$id)"); - $this->ilog("Materiel $verb = '$materiel' (id=$id)"); + //////$this->ilog("Materiel $verb = '$materiel' (id=$id)"); /* * EDIT //En attendant un remaniement complet de la fonction @@ -1688,8 +1789,7 @@ class MaterielsController extends AppController { $id ]); } - } // if POST - + } // if POST... /* SINON (PAS POST) * C'est la première fois qu'on vient sur cette vue, @@ -2156,23 +2256,30 @@ class MaterielsController extends AppController { */ public function delete($id = null) { + + $DEBUG = true; + // $this->request->allowMethod(['post', 'delete']); $verb = 'supprimé'; + /* $materiel = $this->Materiels->get($id, [ 'contain'=>['SurCategories', 'Categories', 'SousCategories'] ] ); + */ + // Optimisation : ne charge l'entité QUE si pas déjà fait + $materiel = $this->getEntity($id); // DEBUG - $emails = $this->sendmail($materiel); - debug($emails); - exit; - /* + //$emails = $this->sendmail($materiel); + //$emails = $this->sendNotificationForEntityAction($materiel); + //debug($emails); + //exit; //if ($materiel->has('sur_category')) debug($materiel->sur_category->nom); //debug($materiel); exit; - if ($this->Materiels->delete($materiel)) { + if ( !$DEBUG && $this->Materiels->delete($materiel) ) { $this->Flash->success(__("Le matériel a bien été $verb")); $this->ilog("Materiel $verb = '$materiel' (id=$id)"); //(EP202009) @@ -2181,11 +2288,12 @@ class MaterielsController extends AppController { } else $this->Flash->error(__("Le matériel n'a pas pu être $verb")); - */ return $this->redirect([ 'action' => 'index' ]); - } + + } // delete() + /** diff --git a/src/Controller/UsersController.php b/src/Controller/UsersController.php index 6e21c67..f17528d 100755 --- a/src/Controller/UsersController.php +++ b/src/Controller/UsersController.php @@ -38,11 +38,18 @@ class UsersController extends AppController } + // @override parent // "l'" utilisateur (et non pas "le utilisateur") public function getArticle() { return "L'"; } + + // @override parent + protected $actionNounAndPastVerbs = [ + 'login' => ['Connexion','connecté'], + 'logout' => ['Déconnexion','déconnecté'], + ]; // 1) AVANT connexion public function beforeFilter(Event $event) @@ -60,15 +67,30 @@ class UsersController extends AppController */ protected function setAuthorizations() { + // Actions qui envoient des notifs + $this->setNotificationAllowedOnActions([ + 'login' => 'log', + 'logout' => 'log', + 'add' => 'log', + 'edit' => 'log', + 'delete' => 'log', + // ... + ]); + // Actions autorisées à tous - foreach (['login', 'logout', 'getLdapLogin', 'getLdapEmail', 'indexRecap'] as $action) $this->setAuthorizationsForAction($action, 0); + foreach (['login', 'logout', 'getLdapLogin', 'getLdapEmail', 'indexRecap'] as $action) + $this->setAuthorizationsForAction($action, 0); // Action autorisées seulement à superadmin // TODO: affiner dans le cas d'un LDAP : même superadmin ne doit pas pouvoir supprimer ou modifier (sauf certains attributs) un utilisateur - foreach (['add', 'edit', 'delete'] as $action) $this->setAuthorizationsForAction($action, -1, ['super'=>0]); + foreach (['add', 'edit', 'delete'] as $action) + $this->setAuthorizationsForAction($action, -1, ['super'=>0]); } // setAuthorizations + + + // 2) APRES connexion /** * Give authorization for users -- libgit2 0.21.2