<?php
/**
 * OM_UTILISATEUR - Surcharge du core
 *
 * @package openads
 * @version SVN : $Id$
 */

require_once PATH_OPENMAIRIE."obj/om_utilisateur.class.php";

class om_utilisateur extends om_utilisateur_core {

    /**
     * Clause select pour la requête de sélection des données de l'enregistrement.
     *
     * @return array
     */
    public function get_var_sql_forminc__champs() {
        $champs = parent::get_var_sql_forminc__champs();
        $champs[] = "'' as om_utilisateur_princ";
        return $champs;
    }

    /**
     * SURCHARGE
     *
     * Configuration du formulaire (VIEW formulaire et VIEW sousformulaire).
     *
     * @param formulaire $form Instance formulaire.
     * @param integer $maj Identifant numérique de l'action.
     *
     * @return void
     */
    public function setType(&$form, $maj) {
        parent::setType($form, $maj);
        // Récupération du mode de l'action
        $crud = $this->get_action_crud($maj);

        // Gestion du champ om_utilisateur_princ
        $form->setType("om_utilisateur_princ", "hidden");
        if ($this->is_a_linked_user() === true) {
            // MODE modifier, supprimer et consulter
            if ($maj == 1 || $crud == 'update'
                || $maj == 2 || $crud == 'delete'
                || $maj == 3 || $crud == 'read') {
                //
                $form->setType("om_utilisateur_princ", "hiddenstatic");
                $form->setType('email', 'hiddenstatic');
                $form->setType('pwd', 'hiddenstatic');
            }
            // MODE modifier
            if ($maj == 1 || $crud == 'update') {
                //
                if ($_SESSION["niveau"] == "2") {
                    $form->setType("om_collectivite", "select");
                } else {
                    $form->setType("om_collectivite", "selecthiddenstatic");
                }
            }
            // MODE supprimer et consulter
            if ($maj == 2 || $crud == 'delete'
                || $maj == 3 || $crud == 'read') {
                //
                $form->setType("om_collectivite", "selectstatic");
            }
        }

        // Dans le contexte d'un utilisateur lié en sousform
        if ($this->is_in_context_linked_user() === true) {
            $form->setType('email', 'hidden');
            $form->setType('pwd', 'hidden');
            // MODE ajouter et modifier
            if ($crud == 'create'
                || $crud == 'update') {
                //
                if ($_SESSION["niveau"] == "2") {
                    $form->setType("om_collectivite", "select");
                } else {
                    $form->setType("om_collectivite", "selecthiddenstatic");
                }
            }
            // MODE modifier
            if ($crud == 'update') {
                $form->setType("login", "hiddenstatic");
            }
            // MODE consulter et supprimer
            if ($crud == 'read'
                || $crud == 'delete') {
                //
                $form->setType("om_collectivite", "selectstatic");
            }
        }
    }

    /**
     * SURCHARGE
     *
     * Configuration du formulaire (VIEW formulaire et VIEW sousformulaire).
     *
     * @param formulaire $form Instance formulaire.
     * @param integer $maj Identifant numérique de l'action.
     * @param integer $validation Marqueur de validation du formulaire.
     *
     * @return void
     */
    public function set_form_default_values(&$form, $maj, $validation) {
        parent::set_form_default_values($form, $maj, $validation);
        // Récupération du mode de l'action
        $crud = $this->get_action_crud($maj);

        // Dans le contexte d'un utilisateur lié en sousform en action 100 (ajout)
        if ($this->is_in_context_linked_user(array(100, )) === true) {
            $inst_omu_princ = $this->f->get_inst__om_dbform(array(
                "obj" => 'om_utilisateur',
                "idx" => $this->getParameter('idxformulaire'),
            ));
            // Par défaut sélectionne la collectivité de l'utilisateur principal
            $form->setVal('om_collectivite', intval($inst_omu_princ->getVal('om_collectivite')));
        }

        // MODE modifier, supprimer et consulter
        // et si c'est un utilisateur lié
        if (($maj == 1 || $crud == 'update'
                || $maj == 2 || $crud == 'delete'
                || $maj == 3 || $crud == 'read')
            && $this->is_a_linked_user() === true) {
            // Si l'utilisateur est un utilisateur lié
            $get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur_lie = $this->get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur_lie($this->getVal($this->clePrimaire));
            if ($get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur_lie != '') {
                // Instanciation de la classe lien_om_utilisateur_om_utilisateur
                $lien_om_utilisateur_om_utilisateur = $this->f->get_inst__om_dbform(array(
                    "obj" => "lien_om_utilisateur_om_utilisateur",
                    "idx" => $get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur_lie,
                ));
                // Instanciation de l'utilisateur parent
                $om_utilisateur_princ = $this->f->get_inst__om_dbform(array(
                    "obj" => "om_utilisateur",
                    "idx" => $lien_om_utilisateur_om_utilisateur->getVal('om_utilisateur'),
                ));
                // Affiche le nom de l'utilisateur parent à l'utilisateur lié
                $form->setVal("om_utilisateur_princ", $om_utilisateur_princ->getVal('nom'));
            }
        }
    }

    /**
     * SURCHARGE
     *
     * Mutateur pour la propriéré 'valF'.
     *
     * Suppression de l'espace sur les logins pour éviter l'erreur
     * d'accès via le bloqueur de publicité
     *
     * @param array $val Tableau des valeurs brutes.
     *
     * @return void
     */
    public function setValF($val = array()) {
        parent::setValF($val);

        // On supprime les espaces en début et fin du login, du nom et de l'email
        $this->valF["login"] = trim($val["login"]);
        $this->valF['nom'] = trim($val["nom"]);
        $this->valF['email'] = trim($val["email"]);
    }

    /**
     * SURCHARGE
     *
     * Mutateur pour la propriéré 'valF' en mode CREATE.
     *
     * initialisation valF pour la cle primaire (si pas de cle automatique)
     * [value primary key to database - not automatic primary key]
     *
     * @param array $val Tableau des valeurs brutes.
     *
     * @return void
     */
    public function setValFAjout($val = array()) {
        parent::setValFAjout($val);
        //
        if ($this->is_in_context_linked_user(array(100, )) === true) {
            //
            $this->valF['om_type'] = 'linked';
            $this->valF['pwd'] = uniqid('pwd');
            $inst_omu_princ = $this->f->get_inst__om_dbform(array(
                "obj" => 'om_utilisateur',
                "idx" => $this->getParameter('idxformulaire'),
            ));
            $this->valF['email'] = $inst_omu_princ->getVal('email');

            //
            if (is_numeric($val['om_collectivite']) === false
                && $_SESSION['niveau'] == '1') {
                //
                $this->valF['om_collectivite'] = intval($inst_omu_princ->getVal('om_collectivite'));
            }
        }
    }

    /**
     * SURCHARGE
     *
     * Configuration du formulaire (VIEW formulaire et VIEW sousformulaire).
     *
     * @param formulaire $form Instance formulaire.
     * @param integer $maj Identifant numérique de l'action.
     *
     * @return void
     */
    public function setLib(&$form, $maj) {
        parent::setLib($form, $maj);
        //
        $form->setLib('om_utilisateur_princ', __('Utilisateur principal'));
    }

    function cleSecondaire($id, &$dnu1 = null, $val = array(), $dnu2 = null) {
        // Initialisation de l'attribut correct a true
        $this->correct = true;
        // Recherche si le login a supprimer est identique au login de
        // l'utilisateur connecte
        $qres = $this->f->get_all_results_from_db_query(
            sprintf(
                'SELECT
                    *
                FROM
                    %1$som_utilisateur
                WHERE
                    om_utilisateur = %2$d',
                DB_PREFIXE,
                intval($id)
            ),
            array(
                'origin' => __METHOD__
            )
        );
        if ($qres['code'] !== 'OK') { // PP
            $this->erreur_db($qres['message'], $qres['message'], "");
        } else {
            //
            $row = array_shift($qres['result']);
            if ($row['login'] == $_SESSION ['login']) {
                $this->msg .= __("Vous ne pouvez pas supprimer votre utilisateur.")."<br/>";
                $this->correct = false;
            }
        }
        // Si la suppression n'est pas possible, on ajoute un message clair
        // pour l'utilisateur
        if ($this->correct == false) {
            $this->msg .= __("SUPPRESSION IMPOSSIBLE")."<br />";
        }
    }

    /**
     * TRIGGER - triggerajouterapres.
     *
     * @param string $id
     * @param null &$dnu1 @deprecated  Ne pas utiliser.
     * @param array $val Tableau des valeurs brutes.
     * @param null $dnu2 @deprecated  Ne pas utiliser.
     *
     * @return boolean
     */
    public function triggerajouterapres($id, &$dnu1 = null, $val = array(), $dnu2 = null) {
        parent::triggerajouterapres($id, $dnu1, $val, $dnu2);
        $this->addToLog(__METHOD__."(): start", EXTRA_VERBOSE_MODE);
    
        // ACTION 100
        if ($this->is_in_context_linked_user() === true) {
            //
            $inst_lien_omu_omu = $this->f->get_inst__om_dbform(array(
                "obj" => "lien_om_utilisateur_om_utilisateur",
                "idx" => "]",
            ));
            $lien_omu_omu_val = array(
                'lien_om_utilisateur_om_utilisateur' => null,
                'om_utilisateur' => $this->getParameter('idxformulaire'),
                'om_utilisateur_lie' => $id,
            );
            //
            $add_lien_omu_omu = $inst_lien_omu_omu->ajouter($lien_omu_omu_val);
            if ($add_lien_omu_omu === false) {
                $this->addToMessage($inst_lien_omu_omu->msg);
                $this->addToLog(
                    sprintf(
                        '%s() : %s %s : %s',
                        __METHOD__,
                        __("Echec lors de l'ajout d'un utilisateur lié."),
                        __('Values: '),
                        var_export($lien_omu_omu_val, true)
                    ),
                    DEBUG_MODE
                );
                return false;
            }
        }

        $this->addToLog(__METHOD__."(): end", EXTRA_VERBOSE_MODE);
        return true;
    }

    /**
     * TRIGGER - triggermodifierapres.
     *
     * @param string $id
     * @param null &$dnu1 @deprecated  Ne pas utiliser.
     * @param array $val Tableau des valeurs brutes.
     * @param null $dnu2 @deprecated  Ne pas utiliser.
     *
     * @return boolean
     */
    public function triggermodifierapres($id, &$dnu1 = null, $val = array(), $dnu2 = null) {
        parent::triggermodifierapres($id, $dnu1, $val, $dnu2);
        $this->addToLog(__METHOD__."(): start", EXTRA_VERBOSE_MODE);

        //
        if ($this->is_not_a_linked_user() === true
            && $this->getVal('email') != $this->valF['email']) {
            //
            $get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur = $this->get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur($id);
            if (is_array($get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur) === true) {
                foreach ($get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur as $lien_omu_omu) {
                    $inst_om_utilisateur_lie = $this->f->get_inst__om_dbform(array(
                        "obj" => "om_utilisateur",
                        "idx" => $lien_omu_omu['om_utilisateur_lie'],
                    ));
                    $linst_om_utilisateur_lie_valF = array();
                    foreach ($inst_om_utilisateur_lie->champs as $champ) {
                        $linst_om_utilisateur_lie_valF[$champ] = $inst_om_utilisateur_lie->getVal($champ);
                    }
                    $linst_om_utilisateur_lie_valF['email'] = $this->valF['email'];
                    $inst_om_utilisateur_lie->setParameter('maj', 101);
                    $update = $inst_om_utilisateur_lie->modifier($linst_om_utilisateur_lie_valF);
                    if ($update === false) {
                        $this->addToMessage(sprintf(
                            '%s :<br><br>%s',
                            sprintf(
                                __("Erreur lors de la mise à jour de l'utilisateur lié <b>%s</b>"),
                                $inst_om_utilisateur_lie->getVal('login')
                            ),
                            $inst_om_utilisateur_lie->msg
                        ));
                        return false;
                    }
                }
            }
        }

        $this->addToLog(__METHOD__."(): end", EXTRA_VERBOSE_MODE);
        return true;
    }

    /**
     * TRIGGER - triggersupprimer.
     *
     * @return boolean
     */
    function triggersupprimer($id, &$dnu1 = null, $val = array(), $dnu2 = null) {
        $this->addToLog(__METHOD__."(): start", EXTRA_VERBOSE_MODE);

        // Si l'utilisateur est un instructeur
        $get_instructeur_by_om_utilisateur = $this->get_instructeur_by_om_utilisateur($id);
        if ($get_instructeur_by_om_utilisateur != '') {
            // Instanciation de la classe instructeur
            $instructeur = $this->f->get_inst__om_dbform(array(
                "obj" => "instructeur",
                "idx" => $get_instructeur_by_om_utilisateur,
            ));
            // Valeurs de l'enregistrement
            $value_instructeur = array();
            foreach ($instructeur->champs as $key => $champ) {
                //
                $value_instructeur[$champ] = $instructeur->val[$key];
            }
            // Valeur à modifier
            $value_instructeur['om_utilisateur'] = null;
            // Modifie l'enregistrement
            $instructeur->modifier($value_instructeur);
        }

        // Si l'utilisateur est associé à des services
        $get_lien_service_om_utilisateur_by_om_utilisateur = $this->get_lien_service_om_utilisateur_by_om_utilisateur($id);
        if ($get_lien_service_om_utilisateur_by_om_utilisateur != '') {
            foreach ($get_lien_service_om_utilisateur_by_om_utilisateur as $row) {
                $lien_service_om_utilisateur = $this->f->get_inst__om_dbform(array(
                    "obj" => "lien_service_om_utilisateur",
                    "idx" => $row['lien_service_om_utilisateur'],
                ));
                // Valeurs de l'enregistrement
                $value_lien_service_om_utilisateur = array();
                foreach ($lien_service_om_utilisateur->champs as $key => $champ) {
                    //
                    $value_lien_service_om_utilisateur[$champ] = $lien_service_om_utilisateur->val[$key];
                }
                // Valeur à modifier
                $value_lien_service_om_utilisateur['om_utilisateur'] = null;
                // Modifie l'enregistrement
                $lien_service_om_utilisateur->modifier($value_lien_service_om_utilisateur);
            }
        }

        // Si l'utilisateur possède des utilisateurs liés
        $get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur = $this->get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur($id);
        if ($get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur != '') {
            foreach ($get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur as $row) {
                $lien_om_utilisateur_om_utilisateur = $this->f->get_inst__om_dbform(array(
                    "obj" => "lien_om_utilisateur_om_utilisateur",
                    "idx" => $row['lien_om_utilisateur_om_utilisateur'],
                ));
                // Valeurs de l'enregistrement
                $value_lien_om_utilisateur_om_utilisateur = array();
                foreach ($lien_om_utilisateur_om_utilisateur->champs as $key => $champ) {
                    //
                    $value_lien_om_utilisateur_om_utilisateur[$champ] = $lien_om_utilisateur_om_utilisateur->val[$key];
                }
                //
                $om_utilisateur = $this->f->get_inst__om_dbform(array(
                    "obj" => "om_utilisateur",
                    "idx" => $row['om_utilisateur_lie'],
                ));
                // Valeurs de l'enregistrement
                $value_om_utilisateur = array();
                foreach ($om_utilisateur->champs as $key => $champ) {
                    //
                    $value_om_utilisateur[$champ] = $om_utilisateur->val[$key];
                }
                // Supprime les enregistrements
                $lien_om_utilisateur_om_utilisateur->supprimer($value_lien_om_utilisateur_om_utilisateur);
                $om_utilisateur->supprimer($value_om_utilisateur);
            }
        }

        // Si l'utilisateur est un utilisateur lié
        $get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur_lie = $this->get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur_lie($id);
        if ($get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur_lie != '') {
            // Instanciation de la classe instructeur
            $lien_om_utilisateur_om_utilisateur = $this->f->get_inst__om_dbform(array(
                "obj" => "lien_om_utilisateur_om_utilisateur",
                "idx" => $get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur_lie,
            ));
            // Valeurs de l'enregistrement
            $value_lien_om_utilisateur_om_utilisateur = array();
            foreach ($lien_om_utilisateur_om_utilisateur->champs as $key => $champ) {
                //
                $value_lien_om_utilisateur_om_utilisateur[$champ] = $lien_om_utilisateur_om_utilisateur->val[$key];
            }
            // Supprime l'enregistrement
            $lien_om_utilisateur_om_utilisateur->supprimer($value_lien_om_utilisateur_om_utilisateur);
        }
    }

    /**
     * Récupère l'identifiant de l'instructeur par rapport à l'utilisateur
     * @param  integer $om_utilisateur Identifiant de l'utilisateur
     * @return integer                 Identifiant de l'instructeur
     */
    function get_instructeur_by_om_utilisateur($om_utilisateur) {
        // Initialisation résultat
        $instructeur = '';
        // Si la condition n'est pas vide
        if ($om_utilisateur != "" 
            && $om_utilisateur != null
            && is_numeric($om_utilisateur)) {
            // Requête SQL
            $qres = $this->f->get_one_result_from_db_query(
                sprintf(
                    'SELECT
                        instructeur
                    FROM
                        %1$sinstructeur
                    WHERE
                        om_utilisateur = %2$d',
                    DB_PREFIXE,
                    intval($om_utilisateur)
                ),
                array(
                    "origin" => __METHOD__,
                )
            );
            $instructeur = $qres["result"];
        }
        // Retourne résultat
        return $instructeur;
    }


    /**
     * Récupère l'identifiant de l'instructeur par rapport au login de 
     * l'utilisateur.
     *
     * @param string $om_utilisateur_login Login de l'utilisateur.
     *
     * @return integer
     */
    function get_instructeur_by_om_utilisateur_login($om_utilisateur_login) {
        // Initialisation résultat
        $instructeur = '';
        // Si la condition n'est pas vide
        if ($om_utilisateur_login != "" 
            && $om_utilisateur_login != null) {
            // Requête SQL
            $qres = $this->f->get_one_result_from_db_query(
                sprintf(
                    'SELECT
                        instructeur
                    FROM
                        %1$sinstructeur
                        LEFT JOIN %1$som_utilisateur
                            ON instructeur.om_utilisateur = om_utilisateur.om_utilisateur
                    WHERE
                        om_utilisateur.login = \'%2$s\'',
                    DB_PREFIXE,
                    $this->f->db->escapeSimple($om_utilisateur_login)
                ),
                array(
                    "origin" => __METHOD__,
                )
            );
            $instructeur = $qres["result"];
        }
        // Retourne résultat
        return $instructeur;
    }


    /**
     * Récupère l'identifiant de lien_service_om_utilisateur par rapport à 
     * l'utilisateur
     * @param  integer $om_utilisateur Identifiant de l'utilisateur
     * @return object                  Résultat de la requête
     */
    function get_lien_service_om_utilisateur_by_om_utilisateur($om_utilisateur) {

        // Initialisation résultat
        $res = '';

        // Si la condition n'est pas vide
        if ($om_utilisateur != "" 
            && $om_utilisateur != null
            && is_numeric($om_utilisateur)) {

            // Requête SQL
            $qres = $this->f->get_all_results_from_db_query(
                sprintf(
                    'SELECT
                        lien_service_om_utilisateur
                    FROM
                        %1$slien_service_om_utilisateur
                    WHERE
                        om_utilisateur = %2$d',
                    DB_PREFIXE,
                    intval($om_utilisateur)
                ),
                array(
                    'origin' => __METHOD__
                )
            );
        }

        // Retourne résultat
        return $qres['result'];
    }

    /**
     * Récupère le lien depuis l'identifiant utilisateur lié
     *
     * @param  integer $om_utilisateur_lie Identifiant de l'utilisateur lié
     *
     * @return integer
     */
    protected function get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur_lie($om_utilisateur_lie) {
        $lien_omu_omu = '';
        if ($om_utilisateur_lie != "" 
            && $om_utilisateur_lie != null
            && is_numeric($om_utilisateur_lie)) {
            // Requête SQL
            $qres = $this->f->get_one_result_from_db_query(
                sprintf(
                    'SELECT
                        lien_om_utilisateur_om_utilisateur
                    FROM
                        %1$slien_om_utilisateur_om_utilisateur
                    WHERE
                        om_utilisateur_lie = %2$d',
                    DB_PREFIXE,
                    intval($om_utilisateur_lie)
                ),
                array(
                    "origin" => __METHOD__,
                )
            );
            $lien_omu_omu = $qres["result"];
        }
        // Retourne résultat
        return $lien_omu_omu;
    }

    /**
     * Récupère les liens depuis l'identifiant de l'utilisateur principal
     *
     * @param  integer $om_utilisateur Identifiant de l'utilisatreur principal
     * @return array
     */
    protected function get_lien_om_utilisateur_om_utilisateur_by_om_utilisateur($om_utilisateur) {
        $lien_omu_omu = '';
        if ($om_utilisateur != "" 
            && $om_utilisateur != null
            && is_numeric($om_utilisateur)) {
            // Requête SQL
            $qres = $this->f->get_all_results_from_db_query(
                sprintf(
                    'SELECT
                        lien_om_utilisateur_om_utilisateur,
                        om_utilisateur_lie
                    FROM
                        %1$slien_om_utilisateur_om_utilisateur
                    WHERE
                        om_utilisateur = %2$d',
                    DB_PREFIXE,
                    intval($om_utilisateur)
                ),
                array(
                    "origin" => __METHOD__,
                )
            );
            $lien_omu_omu = $qres["result"];
        }
        // Retourne résultat
        return $lien_omu_omu;
    }

    /**
     * Définition des actions disponibles sur la classe.
     *
     * @return void
     */
    public function init_class_actions() {
        // On récupère les actions génériques définies dans la méthode
        // d'initialisation de la classe parente
        parent::init_class_actions();
        // ACTION - 001 - modifier
        if (isset($this->class_actions) === true
            && array_key_exists(1, $this->class_actions) === true
            && is_array($this->class_actions[1]) === true) {
            //
            if (array_key_exists("condition", $this->class_actions)
                && is_array($this->class_actions[1]["condition"])) {
                //
                $this->class_actions[1]["condition"][] = "has_a_higher_profil";
            } elseif (array_key_exists("condition", $this->class_actions)
                && is_string($this->class_actions[1]["condition"])) {
                //
                $this->class_actions[1]["condition"] = array(
                    $this->class_actions[1]["condition"],
                    "has_a_higher_profil"
                );
            } elseif (array_key_exists("condition", $this->class_actions) === false) {
                //
                $this->class_actions[1]["condition"] = array(
                    "has_a_higher_profil"
                );
            }
            //
            $this->class_actions[1]["condition"][] = 'is_not_in_context_linked_user';
            $this->class_actions[1]["condition"][] = 'can_update_linked_user_in_form';
        }
        // ACTION - 002 - supprimer
        if (isset($this->class_actions) === true
            && array_key_exists(2, $this->class_actions) === true
            && is_array($this->class_actions[2]) === true) {
            //
            if (array_key_exists("condition", $this->class_actions)
                && is_array($this->class_actions[2]["condition"])) {
                //
                $this->class_actions[2]["condition"][] = "has_a_higher_profil";
            } elseif (array_key_exists("condition", $this->class_actions)
                && is_string($this->class_actions[2]["condition"])) {
                //
                $this->class_actions[2]["condition"] = array(
                    $this->class_actions[2]["condition"],
                    "has_a_higher_profil"
                );
            } elseif (array_key_exists("condition", $this->class_actions) === false) {
                //
                $this->class_actions[2]["condition"] = array(
                    "has_a_higher_profil"
                );
            }
            //
            $this->class_actions[2]["condition"][] = 'is_not_in_context_linked_user';
            $this->class_actions[2]["condition"][] = 'can_delete_linked_user_in_form';
        }
        // ACTION - 100 - add_linked_user
        $this->class_actions[100] = array(
            "identifier" => "add_linked_user",
            "crud" => "create",
            "view" => "formulaire",
            "permission_suffix" => "ajouter",
        );
        // ACTION - 101 - update_linked_user
        $this->class_actions[101] = array(
            "identifier" => "update_linked_user",
            "portlet" => array(
                "type" => "action-self",
                "libelle" => __("modifier"),
                "order" => 10,
                "class" => "edit-16",
            ),
            "crud" => "update",
            "view" => "formulaire",
            "condition" => array(
                "exists",
                "is_in_context_linked_user",
                "can_update_linked_user",
            ),
            "permission_suffix" => "modifier",
        );
        // ACTION - 102 - delete_linked_user
        $this->class_actions[102] = array(
            "identifier" => "delete_linked_user",
            "portlet" => array(
                "type" => "action-self",
                "libelle"=> __("supprimer"),
                "order"=> 20,
                "class" => "delete-16",
            ),
            "crud" => "delete",
            "view" => "formulaire",
            "condition" => array(
                "exists",
                "is_in_context_linked_user",
                "can_delete_linked_user",
            ),
            "permission_suffix" => "supprimer",
        );
        // ACTION - 103 - read_linked_user
        $this->class_actions[103] = array(
            "identifier" => "read_linked_user",
            "crud" => "read",
            "view" => "formulaire",
            "condition" => array(
                "exists",
                "is_in_context_linked_user",
                "can_read_linked_user",
            ),
            "permission_suffix" => "consulter",
        );
        // ACTION - 200 - redirect_linked_user_form
        $this->class_actions[200] = array(
            "identifier" => "redirect_linked_user_form",
            "portlet" => array(
                "type" => "direct",
                "libelle"=> __("Ouvrir le formulaire de l'utilisateur lié"),
                "order"=> 30,
                "class" => "consult-16",
            ),
            "view" => "redirect_linked_user_form",
            "condition" => array(
                "exists",
                "is_in_context_linked_user",
                "can_read_linked_user_in_form",
            ),
            "permission_suffix" => "consulter",
        );
    }

    /**
     * CONDITION - has_a_higher_profil.
     * 
     * Sans paramètre, cette méthode vérifie que l'utilisateur courant
     * possède un indice hiérarchique supérieur au profil visité
     * 
     * @param Integer $om_profil_selected : permet de faire la même comparaison hiérarchique,
     *                sur la sélection d'un profil en création par sa valeur 'om_profil' :
     *                $this->valF['om_profil']
     * @param Integer $hierarchie_expected : permet de surcharger la hierarchie de
     *                l'utilisateur connecté.
     *
     * @return boolean
     */
    public function has_a_higher_profil($om_profil_selected = null, $hierarchie_expected = null) {
        $hierarchie = 0;
        if (isset($this->f->user_infos) === true
            && is_array($this->f->user_infos) === true
            && array_key_exists("hierarchie", $this->f->user_infos) === true) {
            $hierarchie = intval($this->f->user_infos["hierarchie"]);
        }
        if (isset($hierarchie_expected) === true){
            $hierarchie = $hierarchie_expected;
        }
        if (isset($om_profil_selected) === true){
            $qres = $this->f->get_all_results_from_db_query(
                sprintf(
                    'SELECT hierarchie FROM %1$som_profil WHERE om_profil = %2$d',
                    DB_PREFIXE,
                    intVal($om_profil_selected)
                ),
                array(
                    'origin' => __METHOD__
                )
            );
            if (!empty($qres['result'])) {
                $om_profil_selected_hierarchy = intVal($qres['result'][0]['hierarchie']);
                if ($hierarchie >= $om_profil_selected_hierarchy) {
                    return true;
                }
                return false;
            }
        }
        $inst__om_profil = $this->f->get_inst__om_dbform(array(
            "obj" => "om_profil",
            "idx" => $this->getVal("om_profil")
        ));
        if ($hierarchie >= intval($inst__om_profil->getVal("hierarchie"))) {
            return true;
        }
        return false;
    }

    /**
     * QUERY - sql_om_profil.
     *
     * Liste des profils dont la hiérarchie est inférieure ou égale à celle de
     * l'utilisateur connecté.
     *
     * @return string
     */
    public function get_var_sql_forminc__sql_om_profil() {
        $hierarchie = 0;
        if (isset($this->f->user_infos) === true
            && is_array($this->f->user_infos) === true
            && array_key_exists("hierarchie", $this->f->user_infos) === true) {
            $hierarchie = intval($this->f->user_infos["hierarchie"]);
        }
        $hierarchie_linked_user = '';
        if ($this->is_in_context_linked_user() === true) {
            $inst_omu_princ = $this->f->get_inst__om_dbform(array(
                "obj" => 'om_utilisateur',
                "idx" => $this->getParameter('idxformulaire'),
            ));
            $inst_om_profil = $this->f->get_inst__om_dbform(array(
                "obj" => 'om_profil',
                "idx" => $inst_omu_princ->getVal('om_profil'),
            ));
            $hierarchie_linked_user = sprintf(
                ' AND om_profil.hierarchie <= %d ',
                intval($inst_om_profil->getVal('hierarchie'))
            );
        }
        return sprintf(
            'SELECT om_profil.om_profil, om_profil.libelle FROM %1$som_profil WHERE om_profil.hierarchie <= %2$s %3$s ORDER BY om_profil.libelle ASC',
            DB_PREFIXE,
            $hierarchie,
            $hierarchie_linked_user
        );
    }

    /**
     * CONDITION
     *
     * Est dans un contexte d'utilisateur lié.
     * Il faut être dans le sousformulaire de l'utilisateur principal.
     * Il faut être dans une des actions spécifique à ce mode.
     *
     * @param  array   $actions Précise l'action à vérifier.
     * @return boolean
     */
    protected function is_in_context_linked_user($actions = array()) {
        // ACTION 100 101 102 103
        // Action spécifique pour l'ajout d'un utilisateur lié
        // Action spécifique pour la modification d'un utilisateur lié
        // Action spécifique pour la suppression d'un utilisateur lié
        // Action spécifique pour la consultation d'un utilisateur lié
        // Ces actions sont obligatoirement utilisées dans le contexte d'un
        // autre utilisateur (principal)
        $list_actions = array(100, 101, 102, 103);
        if (is_array($actions) === true
            && empty($actions) === false) {
            //
            foreach ($actions as $action) {
                if (in_array($action, $list_actions) === false) {
                    return false;
                }
            }
            $list_actions = $actions;
        }
        if (in_array($this->getParameter('maj'), $list_actions) === true
            && $this->getParameter('retourformulaire') === 'om_utilisateur'
            && $this->getParameter('idxformulaire') !== null) {
            //
            return true;
        }
        return false;
    }

    /**
     * CONDITION
     *
     * N'est pas dans un contexte d'utilisateur lié.
     * L'inverse de la méthode is_in_context_linked_user().
     *
     * @return boolean
     */
    protected function is_not_in_context_linked_user() {
        //
        return !$this->is_in_context_linked_user();
    }

    /**
     * CONDITION
     *
     * Permission de modifier l'utilisateur lié en sousformulaire.
     *
     * @return boolean
     */
    public function can_update_linked_user() {
        return $this->f->isAccredited(array(
            'lien_om_utilisateur_om_utilisateur',
            'lien_om_utilisateur_om_utilisateur_modifier',
        ), 'OR');
    }

    /**
     * CONDITION
     *
     * Permission de supprimer l'utilisateur lié en sousformulaire.
     *
     * @return boolean
     */
    public function can_delete_linked_user() {
        return $this->f->isAccredited(array(
            'lien_om_utilisateur_om_utilisateur',
            'lien_om_utilisateur_om_utilisateur_supprimer',
        ), 'OR');
    }

    /**
     * CONDITION
     *
     * Permission de consulter l'utilisateur lié en sousformulaire.
     *
     * @return boolean
     */
    public function can_read_linked_user() {
        return $this->f->isAccredited(array(
            'lien_om_utilisateur_om_utilisateur',
            'lien_om_utilisateur_om_utilisateur_consulter',
        ), 'OR');
    }

    /**
     * CONDITION
     *
     * Est un utilisateur lié.
     *
     * @return boolean
     */
    public function is_a_linked_user() {
        if ($this->getVal('om_type') === 'linked') {
            return true;
        }
        return false;
    }

    /**
     * CONDITION
     *
     * N'est pas un utilisateur lié.
     * L'inverse de la méthode is_a_linked_user().
     *
     * @return boolean
     */
    public function is_not_a_linked_user() {
        return !$this->is_a_linked_user();
    }

    /**
     * CONDITION
     *
     * Permission de modifier l'utilisateur lié en formulaire.
     *
     * @return boolean
     */
    public function can_update_linked_user_in_form() {
        if ($this->is_not_a_linked_user() === true) {
            return true;
        }
        if ($this->is_a_linked_user() === true
            && $this->can_update_linked_user() === true) {
            //
            return true;
        }
        return false;
    }

    /**
     * CONDITION
     *
     * Permission de supprimer l'utilisateur lié en formulaire.
     *
     * @return boolean
     */
    public function can_delete_linked_user_in_form() {
        if ($this->is_not_a_linked_user() === true) {
            return true;
        }
        if ($this->is_a_linked_user() === true
            && $this->can_delete_linked_user() === true) {
            //
            return true;
        }
        return false;
    }

    /**
     * CONDITION
     *
     * Permission de consulter l'utilisateur lié en formulaire.
     *
     * @return boolean
     */
    public function can_read_linked_user_in_form() {
        if ($this->is_not_a_linked_user() === true) {
            return true;
        }
        if ($this->is_a_linked_user() === true
            && $this->can_read_linked_user() === true
            && $this->f->isAccredited(array(
                    'lien_om_utilisateur_om_utilisateur',
                    'lien_om_utilisateur_om_utilisateur_tab_om_utilisateur',
                ), 'OR')) {
            //
            return true;
        }
        return false;
    }

    /**
     * VIEW
     *
     * Redirige depuis le sousformulaire vers le formulaire de l'utilisateur lié.
     *
     * @return void
     */
    public function redirect_linked_user_form() {
        // L'utilisation de la méthode checkAccessibility() n'est pas possible
        // dans ce contexte car les conditions de l'action ne peuvent pas être
        // respectées dans le formulaire cible

        // Vérification de la condition à respecter et appel du contenu d'erreur
        // de la méthode checkAccessibility()
        if ($this->can_read_linked_user_in_form() === false) {
            //
            $this->addToLog(__METHOD__."(): acces non autorise", EXTRA_VERBOSE_MODE);
            //
            if ($this->f->isAjaxRequest() == false) {
                $this->f->setFlag(null);
                $this->f->display();
            }
            //
            $message_class = "error";
            $message = __("Droits insuffisants. Vous n'avez pas suffisamment de ".
                    "droits pour acceder a cette page.");
            $this->f->displayMessage($message_class, $message);
            // Arrêt du script
            die();
        }
        // Conception de l'URL
        $href = sprintf('%s&obj=%s&action=%s&idx=%s',
            OM_ROUTE_FORM,
            $this->get_absolute_class_name(),
            '3',
            $this->getVal($this->clePrimaire)
        );
        header("Location: ".$href);
    }

    /**
     * Methode verifier
     * 
     */
    public function verifier($val = array(), &$dnu1 = null, $dnu2 = null) {
        // Appel de methode de la classe parent
        parent::verifier($val, $this->f->db, null);

        // Gestion des restrictions hiérarchiques des utilisateurs
        if (! $this->has_a_higher_profil($this->valF['om_profil'])) {
            $this->correct = false;
            $this->addToMessage(__('L\'utilisateur courant ne dispose pas des droits suffisants.'));
        }

        // Gestion des restrictions hiérarchiques des utilisateurs dans le contexte
        // des utilisateurs liés
        if ($this->is_in_context_linked_user() === true) {
            $inst_omu_princ = $this->f->get_inst__om_dbform(array(
                "obj" => 'om_utilisateur',
                "idx" => $this->getParameter('idxformulaire'),
            ));
            $inst_om_profil = $this->f->get_inst__om_dbform(array(
                "obj" => 'om_profil',
                "idx" => $inst_omu_princ->getVal('om_profil'),
            ));
            if ($this->has_a_higher_profil($this->valF['om_profil'], intval($inst_om_profil->getVal('hierarchie'))) === false) {
                $this->correct = false;
                $this->addToMessage(__('L\'utilisateur principal ne dispose pas des droits suffisants.'));
            }
        }
    }

    /**
     * SURCHARGE
     *
     * Retourne le lien de retour (VIEW formulaire et VIEW sousformulaire).
     *
     * @param string $view Appel dans le contexte de la vue 'formulaire' ou de
     *                     la vue 'sousformulaire'.
     *
     * @return string
     */
    public function get_back_link($view = 'formulaire') {
        $href = parent::get_back_link($view);
        //
        if ($this->is_in_context_linked_user() === true) {
            //
            if ($this->get_back_target() !== 'form') {
                $href = str_replace(
                    '&obj='.$this->get_absolute_class_name(),
                    '&obj=lien_om_utilisateur_om_utilisateur',
                    $href
                );
            }
            //
            if (in_array($this->getParameter('maj'), array(100, 101, 102, )) === true) {
                $href = str_replace(
                    '&action=3',
                    '&action=103',
                    $href
                );
            }
        }
        return $href;
    }

    /**
     * SURCHARGE
     *
     * Permet de modifier le fil d'Ariane depuis l'objet pour un sous-formulaire.
     *
     * @param string $ent Fil d'Ariane récupéréré
     *
     * @return            Fil d'Ariane
     */
    function getSubFormTitle($ent) {
        //
        $out = $ent;
        if ($this->is_in_context_linked_user() === true) {
            $out = sprintf(
                '<span class ="libelle">%s -> %s %s </span>',
                __('Utilisateur lié'),
                $this->getVal($this->clePrimaire),
                $this->getVal('nom')
            );
        }
        //
        return $out;
    }

}
