type_doc, $this->photo_formats); } //@Override parent protected function setAuthorizations() { // Action 'add' (ajout d'une nouvelle entité) $this->setAuthorizationsForAction('add', ['VALIDATED',1]); //$this->setAuthorizationsForAction('edit', ['VALIDATED',1]); //$this->setAuthorizationsForAction('add', 'edit'); // Action 'edit' (modif d'une entité) => comme pour 'add' $this->setAuthorizationsForAction('edit', 'add', [ 'super' => ['default',0] ]); // Action 'edit' (modif d'une entité) => comme pour 'add' $this->setAuthorizationsForAction('delete', 'add', [ 'super' => ['default',0] ]); // Action 'ficheMateriel' $this->setAuthorizationsForAction('ficheMateriel', 0); // Action 'ficheMaterielPdf' // DOMPDF $this->setAuthorizationsForAction('ficheMaterielPdf', 0); // Action 'mailDevis' $this->setAuthorizationsForAction('mailDevis', 0); // Action 'admission' $this->setAuthorizationsForAction('admission', ['VALIDATED',0], ['user'=>-1, 'resp'=>-1]); // Action 'admissionPdf' $this->setAuthorizationsForAction('admissionPdf', 'admission', ['user'=>-1, 'resp'=>-1]); // Action 'sortie' $this->setAuthorizationsForAction('sortie', ['ARCHIVED',0], ['user'=>-1, 'resp'=>-1]); } // setAuthorizations /** * Give authorization for documents * * @param * $user * @return boolean */ //public function isAuthorized($user) { return $this->isAuthorizedAction($user = $user); } //public function isAuthorizedAction($action = null, $id=null, $role=null, $user=null, $userCname=null) { public function isAuthorized($user, $action = null, $id=null, $role=null) { //$action = null, $id=null, $role=null, $userCname=null) { //if (!$id) $id = $this->getIdPassed(); if (!$id) $id = $this->e_id; //$action = $this->getActionPassed(); if (!$action) $action = $this->a; /* $IS_RELATED_ENTITY_ID = false; if ($action=='add') $IS_RELATED_ENTITY_ID = true; return $this->isAuthorizedAction($action, $id, $IS_RELATED_ENTITY_ID); // $user, $userCname */ $related_matos_id = null; if (in_array($action,['add','admission','sortie'])) { // Aucune de ces actions n'est autorisée sans préciser (à l'avance, dans l'url) le matériel concerné // => access denied if (!$id) return false; // L'id est celui du matos associé $related_matos_id = $id; $id=null; } return $this->isAuthorizedAction($action, $id, $related_matos_id); // $user, $userCname // LA SUITE EST A VIRER $configuration = $this->confLabinvent; //$action = $this->request->getAttribute('params')['action']; if (!$action) $action = $this->request->getAttribute('params')['action']; $role = $this->getUserRole($user); /* * $role = TableRegistry::get('Users')->find() * ->where(['username' => $user[$configuration->authentificationType_ldap][0]]) * ->first()['role']; */ // Pour tout le monde if (in_array($action, [ // 'view', // 'add', // FPDF 'ficheMateriel', // DOMPDF 'ficheMaterielPdf', 'mailDevis' ])) return true; // Super-Admin peut accéder à chaque action /* * if ($role == 'Super Administrateur') * return true; */ if (in_array($action, [ // FPDF 'admission', // DOMPDF 'admissionPdf', 'sortie' ])) { //return true; return $this->userHasRoleAtLeast('Administration'); } if (in_array($action, [ 'delete', 'edit' ])) { if ($this->userHasRoleAtLeast('Administration')) return true; $u = TableRegistry::get('Users')->find() ->where([ 'username' => $user[$configuration->ldap_authenticationType][0] ]) ->first(); $doc = $this->Documents->get((int) $this->request->getAttribute('params')['pass'][0]); $id = $doc->get('materiel_id'); if (empty($id)) { $id = $doc->get('suivi_id'); $suiviTable = TableRegistry::get('Suivis'); if ($role == 'Responsable') { if ($u['groupes_metier_id'] !== null && $u['groupes_metier_id'] != TableRegistry::get('GroupesMetiers')->find() ->where([ 'nom =' => 'N/A' ]) ->first()['id']) { return ($suiviTable->exists([ 'id' => $id, 'groupes_metier_id' => $u['groupes_metier_id'] ])); } else if ($u['groupes_thematique_id'] !== null && $u['groupes_thematique_id'] != TableRegistry::get('GroupesThematiques')->find() ->where([ 'nom =' => 'N/A' ]) ->first()['id']) { return ($suiviTable->exists([ 'id' => $id, 'groupes_thematique_id' => $u['groupes_thematique_id'] ])); } else { return false; } } if ($role == 'Utilisateur') { return $suiviTable->exists([ 'id' => $id, 'nom_createur' => $user['sn'][0] . ' ' . $user['givenname'][0] ]); } } else { $materielTable = TableRegistry::get('Materiels'); if ($role == 'Responsable') { if ($u['groupes_metier_id'] !== null && $u['groupes_metier_id'] != TableRegistry::get('GroupesMetiers')->find() ->where([ 'nom =' => 'N/A' ]) ->first()['id']) { return ($materielTable->exists([ 'id' => $id, 'groupes_metier_id' => $u['groupes_metier_id'] ])); } else if ($u['groupes_thematique_id'] !== null && $u['groupes_thematique_id'] != TableRegistry::get('GroupesThematiques')->find() ->where([ 'nom =' => 'N/A' ]) ->first()['id']) { return ($materielTable->exists([ 'id' => $id, 'groupes_thematique_id' => $u['groupes_thematique_id'] ])); } else { return false; } } if ($role == 'Utilisateur') { return ($materielTable->exists([ 'id' => $id, 'nom_createur' => $user['sn'][0] . ' ' . $user['givenname'][0] ]) || $materielTable->exists([ 'id' => $id, 'nom_responsable' => $user['sn'][0] . ' ' . $user['givenname'][0] ])); } } } // return false; //return parent::isAuthorized($user); //debug("here0"); return parent::isAuthorized($user, $action); //return parent::isAuthorizedAction($user); } /** * Index method * * @return \Cake\Network\Response|null */ public function index() { $this->paginate = [ 'contain' => [ 'TypeDocuments' ] ]; $documents = $this->paginate($this->Documents); $materiel = $this->Documents->Materiels; $this->set(compact('documents', 'materiel')); $this->set('_serialize', [ 'documents' ]); } /** * View method * * @param string|null $id * Document id. * @return \Cake\Network\Response|null * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. */ public function view($id = null) { // cf https://book.cakephp.org/3/fr/orm/retrieving-data-and-resultsets.html#eager-loading-associations // Ceci permettra des accès du type $document->type_document->nom depuis la vue $document = $this->Documents->get($id, [ 'contain' => ['TypeDocuments'] ]); /* $materiel = $this->Documents->Materiels->find() ->where([ 'id =' => $document->materiel_id ])->first(); */ // $materiel //debug($document->materiel_id); //exit; if ($document->materiel_id !== null) { $parent_controller = 'Materiels'; $parent_fk = 'materiel_id'; $PARENT_IS_MATERIEL = true; } else { $parent_controller = 'Suivis'; $parent_fk = 'suivi_id'; $PARENT_IS_MATERIEL = false; } $parent = $this->Documents->$parent_controller->get($document->$parent_fk); /* // suivi $parent = $this->Documents->Suivis->find() ->where([ 'id =' => $document->suivi_id ])->first(); */ $this->set(compact('document', 'PARENT_IS_MATERIEL', 'parent', 'parent_controller')); //$this->set(compact('document', 'parent', 'parent_controller')); /* (EP) inutile $this->set('_serialize', [ 'document' ]); */ } /** * Add method * * @return \Cake\Network\Response|void Redirects on successful add, renders view otherwise. */ // (EP 20200323) NEW add() action //public function add() public function add($valeurs = null, $erreurs = null) { $this->add_or_edit(TRUE, null, $valeurs, $erreurs); } /** * EDit method * * @return \Cake\Network\Response|void Redirects on successful edit, renders view otherwise. */ // (EP 20200323) NEW edit() action public function edit($id = null) { $this->add_or_edit(FALSE, $id); } /** * Add or Edit method (do either add() or edit()) * => Factorisation de add() et edit() * (voir aussi https://book.cakephp.org/3.0/en/orm.html) * * @param $IS_ADD: True = add ; False = edit * @return \Cake\Network\Response|void Redirects on successful add/edit, renders view otherwise. */ protected function add_or_edit($IS_ADD, $id=null, $valeurs=null, $erreurs=null, // uniquement à cause de parent::add_or_edit() : $entity_name=null, array $associated_entities=[], $with_parent=false) { $this->myDebug("step 3: DocumentsController.add_or_edit()"); $document = $IS_ADD ? $this->Documents->newEntity() : $this->Documents->get($id, ['contain' => []]); // POST (on vient de soumettre un nouveau doc) // add // if ($this->request->is('post')) { // (EP) Je suppose qu'on peut utiliser le meme test pour ADD ou EDIT // edit if ($this->request->is(['post','patch','put'])) { $document = $this->Documents->patchEntity($document, $this->request->getData()); //debug($document); //exit; if ($IS_ADD) { /* $nomType = $this->Documents->TypeDocuments->find() ->where([ 'id =' => $document->type_document_id ])->first()['nom']; */ $nomType = $this->Documents->TypeDocuments->get($document->type_document_id)['nom']; if (isset($this->request->getAttribute('params')['pass'][2]) && $this->request->getAttribute('params')['pass'][2] == 'photo') $document->set('photo', 1); } // SAVE $verb = $IS_ADD ? 'ajouté' : 'modifié'; // - NOT SAVED if (! $this->Documents->save($document)) { //$this->myDebug($document->getErrors()); //debug($document->getErrors()); //debug($document); $this->Flash->error(__("Le fichier n'a pas pu être $verb")); } // - SAVED ok else { $this->Flash->success(__("Le fichier a bien été $verb")); //$id = $document->materiel_id; $parent_id = $document->materiel_id; if (!empty($parent_id)) { $parent_type = 'matériel'; //$parent_name = $parent->designation." (id = $parent->id)"; $parent_controller = 'materiels'; } else { $parent_id = $document->suivi_id; $parent_type = 'suivi'; //$parent_name = 'Suivi#'.$document->suivi_id; $parent_controller = 'suivis'; } if ($IS_ADD) { /* // materiel if (! empty($parent_id)) { //$materielTable = TableRegistry::get('Materiels'); $materielTable = TableRegistry::getTableLocator()->get('Materiels'); //$materiel = $materielTable->get($id); $parent = $materielTable->get($parent_id); } */ $parentTable = TableRegistry::getTableLocator()->get($parent_controller); $parent = $parentTable->get($parent_id); // (EP 20200320) Ca n'est plus utilisé, mais je garde au cas où // S'il y avait déjà une photo UNIQUE (mais ça n'est plus le cas puisqu'on associe N photos) liée au parent (materiel ou suivi) // on la remplace par cette nouvelle photo if (isset($this->request->getAttribute('params')['pass'][2]) && $this->request->getAttribute('params')['pass'][2] == 'photo') { //$photoIdOld = $materiel->get('photo_id'); $photoIdOld = $parent->get('photo_id'); if ($photoIdOld !== null) { $docOld = TableRegistry::get('Documents')->get($photoIdOld); $this->Documents->delete($docOld); } //$materiel->set('photo_id', $document->id); //$materielTable->save($materiel); $parent->set('photo_id', $document->id); $parentTable->save($parent); } $userName = $this->LdapAuth->user('sn')[0] . ' ' . $this->LdapAuth->user('givenname')[0]; $userEmail = $this->LdapAuth->user('mail')[0]; // send EMAIL et redirige vers vue détaillée /* //$id = $document->materiel_id; if (!empty($parent_id)) { $parent_type = 'matériel'; $parent_name = $parent->designation." (id = $parent->id)"; //$parent_controller = 'materiels'; } else { $parent_id = $document->suivi_id; $parent_type = 'suivi'; $parent_name = 'Suivi#'.$document->suivi_id; //$parent_controller = 'suivis'; } */ $parent_name = $parent_controller=='materiels' ? $parent->designation." (id = $parent->id)" : 'Suivi#'.$parent->id; //'Suivi#'.$document->suivi_id; $this->sendEmail($document, "[LabInvent] Ajout d'un document : $userName a ajouté un document de type '$nomType' au $parent_type $parent_name"); } // ADD //$parent_controller = empty($parent_id) ? 'suivis' : 'materiels'; return $this->redirect([ 'controller' => $parent_controller, 'action' => 'view', $parent_id ]); } // SAVED ok } // fin du traitement POST // Traitement juste avant d'afficher la vue ADD ou EDIT // On crée les variables nécessaires à la vue et on les lui passe // ADD if ($IS_ADD) { $PARENT_IS_MATOS = (isset($this->request->getAttribute('params')['pass'][1]) && $this->request->getAttribute('params')['pass'][1] == 'mat'); $parent_id = $this->request->getAttribute('params')['pass'][0]; } // EDIT else { $PARENT_IS_MATOS = ! empty($document->materiel_id); $parent_id = $PARENT_IS_MATOS ? $document->materiel_id : $document->suivi_id; } //$parent_controller = $PARENT_IS_MATOS ? 'Materiels' : 'Suivis'; $parent_controller = $PARENT_IS_MATOS ? 'materiels' : 'suivis'; $parent = $this->Documents->$parent_controller->get($parent_id); // Set some variables for the view $this->set(compact('parent')); $parent_type = $PARENT_IS_MATOS ? 'matériel' : 'suivi'; //$parent_name = $PARENT_IS_MATOS ? $parent->designation." (id = $parent->id)" : 'Suivi#'.$document->suivi_id; //$parent_name = $PARENT_IS_MATOS ? $parent->designation." (id = $parent->id)" : 'Suivi#'.$parent->id; $parent_name = $PARENT_IS_MATOS ? $parent->designation." (id = $parent->id)" : "$parent->intitule (suivi#$parent->id)"; $this->set(compact('parent_type','parent_controller','parent_name')); $IS_PHOTO = $IS_ADD ? (isset($this->request->getAttribute('params')['pass'][2]) && $this->request->getAttribute('params')['pass'][2] == 'photo') : $document->photo; if ($IS_PHOTO) $this->set('photo', 1); $typesD = $this->Documents->TypeDocuments->find('list', [ 'keyField' => 'id', 'valueField' => 'nom', 'order' => 'TypeDocuments.nom' ]); // ADD only if ($IS_ADD && $IS_PHOTO) { $typesD = $this->Documents->TypeDocuments->find('list', [ 'keyField' => 'id', 'valueField' => 'nom' ])->where([ 'nom =' => 'Photo' ]); $idType = $this->Documents->TypeDocuments->find() ->where([ 'nom =' => 'Photo' ])->first()['id']; $this->set('idType', $idType); } // ADD $this->set(compact('IS_ADD', 'document', 'typesD')); /* inutile $this->set('_serialize', [ 'document' ]); */ } // add_or_edit() /** * Delete method * * @param string|null $id * Document id. * @return \Cake\Network\Response|null Redirects to index. * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. */ public function delete($id = null) { $this->request->allowMethod([ 'post', 'delete' ]); $document = $this->Documents->get($id); if ($document->photo) { $materielTable = TableRegistry::get('Materiels'); $materiel = $materielTable->get($document->materiel_id); $materiel->set('photo_id', null); $materielTable->save($materiel); } if ($this->Documents->delete($document)) $this->Flash->success(__('Le fichier a bien été supprimé.')); else $this->Flash->error(__('Le fichier n\'a pas pu être supprimé.')); $id = $document->materiel_id; if (empty($id)) { $id = $document->suivi_id; return $this->redirect([ 'controller' => 'suivis', 'action' => 'view', $id ]); } else return $this->redirect([ 'controller' => 'materiels', 'action' => 'view', $id ]); } //public function sortiePdf($filename) { public function sortiePdf() { $this->viewBuilder() ->className('Dompdf.Pdf') ->layout('Dompdf.default') ->options(['config' => [ //'filename' => $filename, 'filename' => "doc-sortie.pdf", //'render' => 'browser', 'render' => 'download', 'size' => 'A4', 'orientation' => 'portrait', //'landscape' /* 'paginate' => [ 'x' => 550, 'y' => 5, ], */ ]]); } public function sortie($labNumber) { $this->set('fpdf', new FPDF('P', 'mm', 'A4')); //$this->set('fpdf', new FPDF()); //$this->set('fpdf', new TCPDF('P', 'mm', 'A4')); } public function admission($labNumber, $pdfEngine="fpdf") { // only for FPDF if ($pdfEngine == "fpdf") $this->set('fpdf', new FPDF('P', 'mm', 'A4')); //$this->set('fpdf', new TCPDF('P', 'mm', 'A4')); // Find the related materiel $materiel = TableRegistry::get('Materiels')->find('all', [ 'conditions' => [ 'numero_laboratoire' => $labNumber ], 'contain' => ['Fournisseurs', 'Organismes'] ])->first(); // End find // Get the administration user name $userName = $this->LdapAuth->user('username'); $numeroLab = $materiel->numero_laboratoire; $dateAcquisition = $materiel->date_acquisition; $dateAcquisition = $dateAcquisition; $numeroCommande = $materiel->numero_commande; $designation = $materiel->designation; /* if ($materiel->organisme_id !== null && ! empty($materiel->organisme_id)) $organisme = TableRegistry::get('Organismes')->find('all') ->where([ 'id =' => $materiel->organisme_id ]) ->first()->nom; else $organisme = ""; */ $numeroOrganisme = $materiel->numero_inventaire_organisme; $eotp = $materiel->eotp; $prix = $materiel->prix_ht; // Build the data array $TDoc = [ 'organisme' => $materiel->organisme ? $materiel->organisme->nom : "", 'numlab' => $numeroLab, 'designation' => $designation, 'dateAcquis' => $dateAcquisition, 'numCde' => $numeroCommande, 'fournisseur' => $materiel->fournisseur ? $materiel->fournisseur->nom : "", 'eotp' => $eotp, 'prix' => $prix, 'numOrg' => $numeroOrganisme ]; // set the data for the document (accessible par $data dans la vue Template/Documents/admission.ctp) $this->set('data', $TDoc); } // admission() public function admissionPdf($labNumber) { $this->admission($labNumber, "dompdf"); $this->viewBuilder() ->className('Dompdf.Pdf') ->layout('Dompdf.default') ->options(['config' => [ //'filename' => $filename, 'filename' => "admission.pdf", //'render' => 'browser', 'render' => 'download', 'size' => 'A4', 'orientation' => 'portrait', //'landscape' /* 'paginate' => [ 'x' => 550, 'y' => 5, ], */ ]]); } public function ficheMaterielPdf($labNumber) { $this->ficheMateriel($labNumber, "dompdf"); $this->viewBuilder() ->className('Dompdf.Pdf') ->layout('Dompdf.default') ->options(['config' => [ //'filename' => $filename, 'filename' => "fiche-materiel.pdf", //'render' => 'browser', 'render' => 'download', 'size' => 'A4', 'orientation' => 'portrait', //'landscape' /* 'paginate' => [ 'x' => 550, 'y' => 5, ], */ ]]); } //public function ficheMateriel($labNumber) public function ficheMateriel($labNumber, $pdfEngine="fpdf") { // Find the concerned materiel /* $materiel = TableRegistry::get('Materiels')->find('all', [ 'conditions' => [ 'numero_laboratoire' => $labNumber ] ])->first(); */ $materiel = TableRegistry::get('Materiels')->find('all', [ 'conditions' => [ 'numero_laboratoire' => $labNumber ], 'contain' => ['SurCategories', 'Categories', 'SousCategories', 'Fournisseurs', 'Organismes'] ] )->first(); // End find /* if ($materiel->sur_categorie_id !== null) $surCategorie = TableRegistry::get('SurCategories')->find() ->where([ 'id =' => $materiel->sur_categorie_id ]) ->first()->nom; else $surCategorie = ' '; if ($materiel->categorie_id !== null) $categorie = TableRegistry::get('Categories')->find() ->where([ 'id =' => $materiel->categorie_id ]) ->first()->nom; else $categorie = ' '; if ($materiel->sous_categorie_id !== null) $sousCategorie = TableRegistry::get('SousCategories')->find() ->where([ 'id =' => $materiel->sous_categorie_id ]) ->first()->nom; else $sousCategorie = ' '; */ if ($materiel->groupes_thematique_id !== null) $groupesThematique = TableRegistry::get('GroupesThematiques')->find() ->where([ 'id =' => $materiel->groupes_thematique_id ]) ->first()->nom; else $groupesThematique = ' '; if ($materiel->groupes_metier_id !== null) $groupesMetier = TableRegistry::get('GroupesMetiers')->find() ->where([ 'id =' => $materiel->groupes_metier_id ]) ->first()->nom; else $groupesMetier = ' '; /* if ($materiel->organisme_id !== null) $organisme = TableRegistry::get('Organismes')->find() ->where([ 'id =' => $materiel->organisme_id ]) ->first()->nom; else $organisme = ' '; */ if ($materiel->site_id !== null) $site = TableRegistry::get('Sites')->find() ->where([ 'id =' => $materiel->site_id ]) ->first()->nom; else $site = ' '; $configuration = $this->confLabinvent; $nom_groupe_thematique = $configuration->nom_groupe_thematique; $nom_groupe_metier = $configuration->nom_groupe_metier; // set the data materiel for the document (accessible par $materiel dans le document) //$this->set(compact('materiel', 'surCategorie', 'categorie', 'sousCategorie', 'groupesThematique', 'groupesMetier', 'organisme', 'site', 'nom_groupe_metier', 'nom_groupe_thematique')); $this->set(compact('materiel', 'groupesThematique', 'groupesMetier', 'site', 'nom_groupe_metier', 'nom_groupe_thematique')); // only for FPDF if ($pdfEngine == "fpdf") $this->set('fpdf', new FPDF('P', 'mm', 'A4')); } public function ficheMetrologique($id) { // Find the concerned suivi $fiche = TableRegistry::get('Fichemetrologiques')->find('all', [ 'conditions' => [ 'id' => $id ] ])->first(); $suivi = TableRegistry::get('Suivis')->find('all', [ 'conditions' => [ 'id' => $fiche->suivi_id ] ])->first(); $mesures = TableRegistry::get('Mesures')->find('all', [ 'conditions' => [ 'fichemetrologique_id' => $fiche->id ] ]); if ($suivi->unite_id !== null) $unite = TableRegistry::get('Unites')->find() ->where([ 'id =' => $suivi->unite_id ]) ->first()->nom; else $unite = ' '; if ($suivi->unite_id !== null) $symbole = TableRegistry::get('Unites')->find() ->where([ 'id =' => $suivi->unite_id ]) ->first()->symbole; else $symbole = ' '; // set the data materiel for the document (accessible par $materiel dans le document) $this->set(compact('suivi', 'unite', 'fiche', 'symbole', 'mesures')); $this->set('fpdf', new FPDF('P', 'mm', 'A4')); } /** MI * Envoi de mail - cette fonction sera appelée si l'on clique sur le bouton envelloppe d'un document sur la page vue d'un matériel * Met en place l'envoi de mail * @param string $id : document id */ public function mailDevis($id) { $document = $this->Documents->get($id); /* debug($document); exit; Exemple de résultat : object(App\Model\Entity\Document) { 'id' => (int) 63, 'type_doc' => 'pdf', 'materiel_id' => (int) 12007, 'suivi_id' => null, 'type_document_id' => (int) 12, 'description' => 'df', 'nom' => 'flkqjsd', 'photo' => false, '[new]' => false, '[accessible]' => [ '*' => true, 'id' => false ], '[dirty]' => [], '[original]' => [], '[virtual]' => [], '[hasErrors]' => false, '[errors]' => [], '[invalid]' => [], '[repository]' => 'Documents' } */ if ($this->request->is([ 'patch', 'post', 'put', 'mailDevis' ])) { $document = $this->Documents->patchEntity($document, $this->request->getData()); } //Si le document existe, on vérifie si c'est une photo ou autre chose if(!empty($document)){ //Si c'est une photo on l'envoi avec le mode d'envoi de mail adapté,.. //pareil pour les autres docs if($document->photo){ $this->sendmail($document,1); $this->Flash->success(__('Le mail avec la photo en pièce jointe a bien été envoyé.')); } else { $this->sendmail($document,2); $this->Flash->success(__('Le mail avec le document a bien été envoyé.')); } } else { $this->Flash->error(__('Le mail n\'a pas pu être envoyé.')); } //puis on retourne sur la page vue du matériel si on était sur matériel, sinon sur la page de suivi if(!empty($document->materiel_id)) { return $this->redirect([ 'controller' => 'materiels', 'action' => 'view', $document->materiel_id ]); } else { return $this->redirect([ 'controller' => 'suivis', 'action' => 'view', $document->suivi_id ]); } } }