<?php
//$Id$
//gen openMairie le 10/11/2020 15:00

require_once "../gen/obj/animation.class.php";

class animation extends animation_gen {

    /**
     * Constructeur.
     *
     * @param string $id Identifiant de l'objet.
     * @param null &$dnu1 @deprecated  Ne pas utiliser.
     * @param null $dnu2 @deprecated  Ne pas utiliser.
     */
    function __construct($id, &$dnu1 = null, $dnu2 = null) {
        $this->constructeur($id);
        $this->champs[] = 'modele';
        $this->champs[] = 'election_comparaison';
    }

    /**
     * Definition des actions disponibles sur la classe
     *
     * @return void
     */
    function init_class_actions() {
        parent::init_class_actions();

        //Les actions de modification et de suppression ne sont pas disponible
        //pour les éléments de configuration.
        $this->class_actions[1]['condition'][0] = 'is_not_from_configuration';
        $this->class_actions[1]['condition'][1] = 'election_non_archivee';
        $this->class_actions[2]['condition'][0] = 'is_not_from_configuration';
        $this->class_actions[2]['condition'][1] = 'election_non_archivee';

        //L'accés à la page de l'animation se fait en utilisant deux variables :
        //      - idx : integer -> identifiant de l'élection. Dans la classe de l'affichage,
        //cet identifiant permet de savoir si l'élection existe ou pas. Il sert également à
        //récupérer les informations de l'élection à afficher. Le répertoire où sont stockées
        // ces informations à pour nom ce numéro et c'est donc l'idx qui permet de l'identifier.
        //      - identifier : integer -> identifiant de l'animation. Ce numéros sert à accéder
        // aux informations liées à l'animation. Ces informations sont stockées dans un
        // répertoire ayant pour nom le numéro de l'identifier. Les informations concernées
        // sont :
        //  . Le paramétrage de l'animation
        //  . Les résultats du périmètre choisit en paramètre
        //  . La participation du périmètre choisit en paramètre
        //
        //La récupération de l'idx se fait en récupérant la valeur 'idxformulaire' du GET car le
        //formulaire des animations est un sous formulaire de l'élection
        //
        //La récupération de l'identifier est réalisé par le framework (?) qui va ajouter
        //l'identifiant du formulaire (donc l'identifiant de l'animation) à la suite de l'url
        //donnée dans la définition de l'action
        $idAnimation = $this->f->get_submitted_get_value('idx');
        $idElection = ! empty($idAnimation) ? $this->get_election_animation($idAnimation) : null;

        //L'action de visualisation n'est visible que si l'animation est liées
        //à une election. Lorsque ce n'est pas le cas, il n'y a pas de données
        // à afficher (résultats, ...) et l'animation ne peut donc pas être afficher.
        if (! empty($idElection)) {
            // ACTION - 11 - animation1
            $this->class_actions[11] = array(
                'identifier' => 'animation',
                'portlet' => array(
                    'type' => 'action-blank',
                    'libelle' => 'animation',
                    'class' => 'arrow-right-16',
                    'order' => 120,
                    'url' => '../aff/animation.php?idx='.$idElection.'&identifier=',
                ),
                "permission_suffix" => "voir_animation"
            );
        }
        // ACTION - 006 - activer
        //
        $this->class_actions[6] = array(
            "identifier" => "activer",
            "portlet" => array(
                "type" => "action-direct-with-confirmation",
                "libelle" => _("activer"),
                "order" => 40,
                "class" => "lu-16",
            ),
            "view" => "formulaire",
            "method" => "activer",
            "button" => "activer",
            "permission_suffix" => "activer",
            "condition" => array(
                "is_not_actif",
                "is_modele_animation"
            )
        );
        // ACTION - 007 - desactiver
        //
        $this->class_actions[7] = array(
            "identifier" => "desactiver",
            "portlet" => array(
                "type" => "action-direct-with-confirmation",
                "libelle" => _("desactiver"),
                "order" => 40,
                "class" => "nonlu-16",
            ),
            "view" => "formulaire",
            "method" => "desactiver",
            "button" => "desactiver",
            "permission_suffix" => "desactiver",
            "condition" => array(
                "is_actif",
                "is_modele_animation"
            )
        );

        // ACTION - 008 - enregistrer comme modèle
        //
        $this->class_actions[8] = array(
            "identifier" => "creer_modele",
            "portlet" => array(
                "type" => "action-direct-with-confirmation",
                "libelle" => _("garder comme modele"),
                "order" => 80,
                "class" => "nonlu-16",
            ),
            "view" => "formulaire",
            "method" => "creer_modele",
            "button" => "activer",
            "permission_suffix" => "creer_modele",
            "condition" => "is_not_modele_animation"
        );

        // ACTION - 10 - modèle
        $this->class_actions[10] = array(
            'identifier' => 'modele',
            "view" => "get_parametrage_modele",
            "permission_suffix" => "consulter"
        );
    }

    /**
     * Requête sql permettant de récupérer l'identifiant de l'élection
     * d'une animation.
     *
     * @return integer identifiant de l'élection
     */
    protected function get_election_animation($idAnimation) {
        $idElection = $this->f->simple_query('election', 'animation', 'animation', $idAnimation);
        // Il n'y a qu'un seul résultat donc la première case du tableau est renvoyé
        if (! empty($idElection[0])) {
            return $idElection[0];
        }
        return null;
    }

    /**
     * Récupère un identifiant de d'animation, vérifie que son
     * type correspond bien au type attendu et que cette identifiant
     * existe dans la base de données.
     *
     * @param string $election identifiant de l'animation
     *
     * @return boolean
     */
    protected function validateur_animation($animation) {
        //Vérification du type et de la taille
        if (! $this->f->validateur_entier_positif($animation)) {
            return false;
        }
        // Requête pour chercher l'identifiant dans la base de données
        //si rien n'est trouvé, c'est qu'il n'existe pas et donc qu'il n'est
        //pas valide
        $res = $this->f->simple_query('animation', 'animation', 'animation', $animation);
        if (empty($res)) {
            return false;
        }
        return true;
    }

    public function get_parametrage_modele() {
        // Il est nécessaire de désactiver les logs car si les modes VERBOSE, EXTRA VERBOSE, etc
        // sont activé, les logs sont affichés en HTML ce qui casse le format json attendu en sortie
        $this->f->disableLog();

        //Pour pouvoir récupérer le paramétrage, il faut l'identifiant de l'animation
        //correspondant au modèle choisi
        $modele = $this->f->get_submitted_get_value('modele');
        if (empty($modele) || ! $this->validateur_animation($modele)) {
            // code retour 404 car la valeur de l'election est invalide donc on ne peut
            // trouver aucune objet avec
            header('HTTP/1.1 404 Not Found');
            return;
        }
        //Liste des propriétés du modèle a récupérer
        $elementParametrage = array(
            'titre',
            'sous_titre',
            'couleur_titre',
            'couleur_bandeau',
            'logo',
            'refresh',
            'affichage',
            'feuille_style',
            'script'
        );

        //Récupération des propriétés voulues
        $animation = $this->f->get_element_by_id('animation', $modele);
        $parametrage = array();
        foreach ($elementParametrage as $champ) {
            $parametrage[$champ] = $animation->getVal($champ);
        }
        echo json_encode($parametrage);
    }

    /**
     * SETTER FORM - setType.
     *
     * @param formulaire $form Instance formulaire.
     * @param integer $maj Identifant numérique de l'action.
     *
     * @return void
     */
    function setType(&$form, $maj) {
        parent::setType($form, $maj);
        // Pour les actions appelée en POST en Ajax, il est nécessaire de
        // qualifier le type de chaque champs (Si le champ n'est pas défini un
        // PHP Notice:  Undefined index dans core/om_formulaire.class.php est
        // levé). On sélectionne donc les actions de portlet de type
        // action-direct ou assimilé et les actions spécifiques avec le même
        // comportement.
        if ($this->get_action_param($maj, "portlet_type") == "action-direct"
            || $this->get_action_param($maj, "portlet_type") == "action-direct-with-confirmation") {
            //
            foreach ($this->champs as $value) {
                $form->setType($value, 'hidden');
            }
            $form->setType($this->clePrimaire, "hiddenstatic");
        }

        $form->setType('election_comparaison', 'hidden');
        $form->setType('modele', 'hidden');
        $form->setType('election', 'hidden');
        $form->setType('is_config', 'hidden');
        $form->setType('is_modele', 'hiddenstatic');
        $form->setType('actif', 'checkboxstatic');
        if ($maj < 2) {
            $form->setType('couleur_titre', 'hexa');
            $form->setType('couleur_bandeau', 'hexa');
            $form->setType('modele', 'select');
        }

        //Le perimetre et le type d'unité n'a besoin d'être choisi que pour une animation
        //liée à une élection. Idem pour l'élection de comparaison
        $form->setType('perimetre_aff', 'selectstatic');
        $form->setType('type_aff', 'selectstatic');

        if ($this->is_in_context_of_foreign_key('election', $this->retourformulaire)
            && $maj < 2
        ) {
            // Afin de simplifier les traitements par la suite l'élection est choisie
            // lors de la création de l'animation et ne doit plus être modifier par la suite
            // Permet par exemple d'éviter d'avoir à gérer les répertoires d'animation lorsque
            // l'élection a été modifiée
            $form->setType('election', 'hiddenstatic');
            if ($maj != 1) {
                $form->setType('election', 'select');
            }
            $form->setType('perimetre_aff', 'select');
            $form->setType('type_aff', 'select');
            $form->setType('election_comparaison', 'select_multiple');
        }
    }

    /**
     *
     */
    function setSelect(&$form, $maj, &$dnu1 = null, $dnu2 = null) {
        parent::setSelect($form, $maj, $dnu1, $dnu2);
        // election_comparaison
        $this->init_select(
            $form, 
            $this->f->db,
            $maj,
            null,
            "election_comparaison",
            $this->get_var_sql_forminc__sql("election_comparaison"),
            $this->get_var_sql_forminc__sql("election_comparaison_by_id"),
            false
        );
        // modele
        $this->init_select(
            $form, 
            $this->f->db,
            $maj,
            null,
            "modele",
            $this->get_var_sql_forminc__sql("modele"),
            $this->get_var_sql_forminc__sql("modele_by_id"),
            false
        );
    }

    /**
     * SETTER FORM - setOnchange.
     *
     * @param formulaire $form Instance formulaire.
     * @param integer $maj Identifant numérique de l'action.
     *
     * @return void
     */
    function setOnchange(&$form, $maj) {
        parent::setOnchange($form, $maj);
        if ($maj < 2) {
            $form->setOnchange(
                'modele',
                "applique_parametrage_modele(this.value)"
            );
        }
        $form->setOnchange('election_comparaison', '');
    }

    /**
     * SETTER FORM - setLayout
     *
     * @param formulaire $form Instance formulaire.
     * @param integer $maj Identifant numérique de l'action.
     *
     * @return void
     */
    function setLayout(&$form, $maj) {
        // Fieldset unité contiens dans l'ordre : animation et libellé
        $form->setFieldset('animation', 'D', 'Animation', 'collapsible');
            $form->setBloc('animation', 'D', "", "group");
            $form->setBloc('refresh', 'F');
        $form->setFieldset('refresh', 'F', '');

        // Fieldset Modèle contiens dans l'ordre : modele et is_modele
        $form->setFieldset('is_modele', 'D', 'Modèle', 'collapsible');
            $form->setBloc('is_modele', 'D', "", "group");
            $form->setBloc('actif', 'F');
        $form->setFieldset('actif', 'F', '');

        // Fieldset Personnalisation de l'entête contiens dans l'ordre : titre et couleur_titre
        $form->setFieldset('titre', 'D', 'Personnalisation de l\'entête', 'collapsible');
            $form->setBloc('titre', 'D', "", "group");
            $form->setBloc('sous_titre', 'F');
            $form->setBloc('couleur_titre', 'D', "", "group");
            $form->setBloc('couleur_bandeau', 'F');
            $form->setBloc('logo', 'D', "", "group");
        $form->setFieldset('logo', 'F', '');

        // Fieldset Perimetre contiens dans l'ordre : perimetre_aff, type_aff
        $form->setFieldset('perimetre_aff', 'D', 'Perimetre', 'collapsible');
            $form->setBloc('perimetre_aff', 'D', "", "group");
            $form->setBloc('type_aff', 'F');
        $form->setFieldset('type_aff', 'F', '');

        // Fieldset Personnalisation du contenu contiens : affichage, election_comparaison
        $form->setFieldset('affichage', 'D', 'Personnalisation du contenu', 'collapsible');
            $form->setBloc('affichage', 'D', "", "");
            $form->setBloc('script', 'F');
        $form->setFieldset('script', 'F', '');

        // Fieldset Personnalisation du contenu contiens : affichage, election_comparaison
        $form->setFieldset('modele', 'D', 'Paramétrage', 'collapsible');
            $form->setBloc('modele', 'D', "", "");
            $form->setBloc('election_comparaison', 'F');
        $form->setFieldset('election_comparaison', 'F', '');
    }
    /**
     * SETTER FORM - set_form_default_values
     *
     * @param formulaire $form Instance formulaire.
     * @param integer $maj Identifant numérique de l'action.
     * @param integer $validation Marqueur de validation du formulaire.
     *
     * @return void
     */
    function set_form_default_values(&$form, $maj, $validation) {
        // Evite des "Notice" dans les logs
        $form->setVal('modele', null, $validation);
        $form->setVal('election_comparaison', '', $validation);
        // Valeur par défaut
        if ($maj == 0 && $validation == 0) {
            $form->setVal('refresh', 60);
            $form->setVal('titre', 'Animation');
            if ($this->is_in_context_of_foreign_key("election", $this->retourformulaire)) {
                $idElection = $this->f->get_submitted_get_value('idxformulaire');
                if (! empty($idElection)) {
                    $election = $this->f->get_element_by_id('election', $idElection);
                    $form->setVal('perimetre_aff', $election->getVal('perimetre'));
                }
            } else {
                // Hors contexte élection ce sont forcement des modèles qui sont ajoutés
                $form->setVal('is_modele', true);
            }
        }

        if ($maj < 2 && $validation == 0) {
            if (! empty($this->getVal('election'))) {
                $form->setVal('election', $this->getVal('election'));
            }
        }
    }

    /**
     * Methode setTaille
     */
    function setTaille(&$form, $maj) {
        parent::setTaille($form, $maj);
        $form->setTaille("election_comparaison", 20);
    }

    /**
     *
     * @return string
     */
    function get_var_sql_forminc__sql_modele() {
        return "SELECT
                    animation.animation, animation.libelle
                FROM
                    ".DB_PREFIXE."animation
                WHERE
                    is_modele = true AND
                    actif = true
                ORDER BY
                    animation.libelle ASC";
    }

    /**
     *
     * @return string
     */
    function get_var_sql_forminc__sql_election_comparaison() {
        $sql =  "SELECT
                    election.election, election.libelle
                FROM
                    ".DB_PREFIXE."election
                ORDER BY
                    election.libelle ASC";
        if ($this->is_in_context_of_foreign_key("election", $this->retourformulaire)) {
            $idElection = $this->f->get_submitted_get_value('idxformulaire');
            $sql = sprintf(
                "SELECT
                    election.election, election.libelle
                FROM
                    %selection
                WHERE
                    is_centaine = false AND
                    election != %d
                ORDER BY
                    election.libelle ASC",
                DB_PREFIXE,
                $idElection
            );
        }
        return $sql;
    }

    /**
     *
     * @return string
     */
    function get_var_sql_forminc__sql_election() {
        // Evite une erreur de BD, hors contexte de l'élection
        $sql = sprintf(
            "SELECT
                election.election, election.libelle
            FROM
                %selection
            ORDER BY
                election.libelle ASC",
            DB_PREFIXE
        );

        if ($this->is_in_context_of_foreign_key("election", $this->retourformulaire)) {
            $idElection = $this->f->get_submitted_get_value('idxformulaire');
            $sql = sprintf(
                "SELECT
                    election.election, election.libelle
                FROM
                    %selection
                WHERE
                    election = %d OR
                    election_reference = %d
                ORDER BY
                    election.libelle ASC",
                DB_PREFIXE,
                $idElection,
                $idElection
            );
        }
        return $sql;
    }

    /**
     * N'affiche que les périmètres appartennant à l'élection
     *
     * @return string
     */
    function get_var_sql_forminc__sql_perimetre_aff() {
        // Récupération de l'identifiant de l'élection en utilisant celui du
        // formulaire. C'est possible car le formulaire de l'animation est un
        // sous formulaire de l'élection.
        // L'identifiant de l'élection va permettre de filtrer les unités et
        // de ne garder que celle appartennant à l'élection
        $idElection = $this->getParameter("idxformulaire");
        //Si il n'y a pas d'election il n'est pas possible de choisir le périmètre
        //parmis les unités de l'élection
        if (empty($idElection)) {
            return 'SELECT
                        unite.unite, concat(unite.code_unite, \' \', unite.libelle)
                    FROM
                        '.DB_PREFIXE.'unite';
        }
        // Récupération de l'instance afin de connaitre le périmètre de l'élection
        // Dans le cas, où l'élection porte sur une unité et que cette unité n'est
        // pas un périmètre, aucune unité ne pourra être sélectionné dans formulaire.
        // Pour éviter ce problème l'instance, le select doit afficher toutes les unité
        // étant des périmètre et étant contenues dans le périmètre de l'élection mais
        // également l'unité servant de périmètre si elle n'est pas dans cette liste.
        $election = $this->f->get_inst__om_dbform(array(
            'obj' => 'election',
            'idx' => $idElection
        ));
        $perimetre = $election->getVal('perimetre');
        return "SELECT
                    unite.unite, concat(unite.code_unite, ' ', unite.libelle)
                FROM
                    ".DB_PREFIXE."unite
                    LEFT JOIN ".DB_PREFIXE."election_unite ON unite.unite = election_unite.unite
                WHERE
                    ((unite.om_validite_debut IS NULL AND
                        (unite.om_validite_fin IS NULL OR
                            unite.om_validite_fin > CURRENT_DATE)) OR
                        (unite.om_validite_debut <= CURRENT_DATE AND
                            (unite.om_validite_fin IS NULL
                                OR unite.om_validite_fin > CURRENT_DATE))) AND
                    election = $idElection AND
                    (perimetre is true OR
                    unite.unite = $perimetre)
                ORDER BY
                    unite.libelle ASC";
    }

    /**
     *
     * @return string
     */
    function get_var_sql_forminc__sql_perimetre_aff_by_id() {
        return "SELECT
                unite.unite, concat(unite.code_unite, ' ', unite.libelle)
            FROM
                ".DB_PREFIXE."unite
            WHERE
                unite = <idx>";
    }

    /**
     * Permet d'afficher la liste des types des unités appartennant
     * à l'élection
     *
     * @return string
     */
    function get_var_sql_forminc__sql_type_aff() {
        // Récupération de l'identifiant de l'élection en utilisant celui du
        // formulaire. C'est possible car le formulaire de l'animation est un
        // sous formulaire de l'élection.
        // L'identifiant de l'élection va permettre de filtrer les unités et
        // de ne garder que celle appartennant à l'élection
        $idElection = $this->getParameter("idxformulaire");
        if (empty($idElection)) {
            return 'SELECT
            unite.unite, unite.libelle
        FROM
            '.DB_PREFIXE.'unite';
        }
        return "SELECT
                    DISTINCT type_unite.type_unite, type_unite.libelle
                FROM
                    ".DB_PREFIXE."type_unite
                    LEFT JOIN ".DB_PREFIXE."unite ON type_unite.type_unite = unite.type_unite
                    LEFT JOIN ".DB_PREFIXE."election_unite ON unite.unite = election_unite.unite
                WHERE
                    election = $idElection
                ORDER BY
                    type_unite.libelle ASC";
    }

    function setLib(&$form, $maj) {
        parent::setLib($form, $maj);
        //libelle des champs
            $form->setLib('couleur_bandeau', __('couleur du bandeau de titre'));
            $form->setLib('couleur_titre', __('couleur du titre'));
            $form->setLib('perimetre_aff', __('périmètre à afficher'));
            $form->setLib('type_aff', __('type des unités à afficher'));
            $form->setLib('modele', __('modèle'));
            $form->setLib('is_modele', __('garder comme modèle ?'));
            $form->setLib('election_comparaison', __('comparer à l\'élection'));
            $form->setLib('feuille_style', __('Feuille de style'));
    }

    /**
     * Récupére l'uid du logo dont l'id est passé en paramètre.
     * A partir de cet uid récupère les informations du logo
     * (son contenu et ses métadatas) sous la forme d'un tableau.
     * Les informations sont ensuite mise en forme sous la forme
     * d'une chaine de caractère et cette chaîne.
     * Un fichier contenant cette chaîne de caractère est ensuite écris.
     *
     * Exemple de path vers ce fichier : (pour l'élection 1 et l'animation 2)
     *    - ../aff/res/1/animation_2/logo.inc
     *
     * @param integer $idLogo identifiant du logo
     * @param integer $idElection identifiant de l'election permettant de
     * savoir dans quel dossier ecrire le fichier
     * @param integer $idAnimation identifiant de l'animation permettant de
     * savoir dans quel dossier ecrire le fichier
     * @return boolean indique si l'écriture du fichier à réussi
     */
    protected function envoi_affichage_logo($idLogo, $idElection, $idAnimation) {
        //Initialisation de la variable indiquant si le traitement a fonctionné ou pas
        $succes = false;
        //Vérification que l'on a bien récupéré l'id du logo
        if (! empty($idLogo)) {
            //récupération de l'uid du fichier qui permettra d'accéder à ses informations
            $uid = $this->get_logo_uid($idLogo);
            //Si aucun uid récupéré on ne peut pas récupérer ses informations.
            //Il faut donc vérifier qu'un uid a bien été récupéré
            if (!empty($uid)) {
                //Récupération des informations du fichier à savoir :
                //   - son contenu
                //   - ses métadatas
                $infoFichier = $this->f->storage->get($uid);
                //Ecriture du fichier de l'image à l'endroit voulu.
                //Les metadatas permettent de récupérer l'extension de l'image et le contenu
                //permet de récupérer l'image dans le répertoire de l'animation
                //Le type est donné sous la forme : ex: image/png. Pour récupérer l'extension
                //il faut donc couper la chaîne en 2 en utilisant le / comme délimiteur et
                //prendre la deuxième partie
                $extension = explode('/', $infoFichier['metadata']['mimetype']);
                $extension = $extension[1];
                $succes = $this->f->write_file(
                    '../aff/res/'.$idElection.'/animation_'.$idAnimation.'/logo.'.
                        $extension,
                    $infoFichier['file_content']
                );
            }
        }
        return $succes;
    }

    /**
     * TRIGGER - triggerajouter.
     *
     * @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
     */
    function triggerajouterapres($id, &$dnu1 = null, $val = array(), $dnu2 = null) {
        //Le paramétrage n'a besoin d'être envoyé à l'affichage que si une election est
        // selectionnée
        if ($this->is_in_context_of_foreign_key('election', $this->retourformulaire)) {
            // Creation du repertoire de l'élection. Permet d'éviter les problèmes d'écriture
            // de fichier pour l'envoi à l'affichage. En effet, si plusieurs repertoire doivent
            // être crées le fichier n'arrive pas à s'écrire. C'est par exemple le cas pour les
            // photos des candidats qui sont dans le repertoire photo du repertoire de l'élection.
            if (! file_exists('../aff/res/'.$val['election'])) {
                if (! mkdir('../aff/res/'.$val['election'])) {
                    $this->addToMessage('repertoire aff de l\'élection non crée');
                    return false;
                }
            }
            // Envoie à l'affichage du périmètre de l'élection
            $election = $this->f->get_element_by_id('election', $val['election']);
            if (! file_exists('../aff/res/'.$val['election'].'/perimetres.json')) {
                $election->affichage_perimetre($val['election']);
            }
            // Envoi des paramètres de l'animation
            $this->aff_set_param($val, $id);

            // Envoi du logo à l'affichage
            if ($this->envoi_affichage_logo($val['logo'], $val['election'], $id)) {
                $this->addToMessage('../aff/res/'.$val['election'].'/animation_'.$id.'/logo.inc modifié');
            }
            //Ecris le fichier candidats.json et les photos des candidats dans le repertoire de l'affichage
            // Pour éviter des problèmes les photos ne sont pas copiée sur les candidats
            // des centaines. La récupération des infos des candidats doit donc être
            // faite à partir des infos de l'élection de référence pour les centaines
            $isCentaine = $this->f->boolean_string_to_boolean($election->getVal('is_centaine'));
            if ($isCentaine) {
                if ($this->envoi_infos_candidats_affichage(
                    $election->getVal('election_reference'),
                    $val['election']
                )) {
                    $this->addToMessage('Informations des candidats et photos envoyées');
                } else {
                    $this->addToMessage('Erreur : Informations des candidats et photos non envoyées');
                }
            } else {
                if ($this->envoi_infos_candidats_affichage($val['election'])) {
                    $this->addToMessage('Informations des candidats et photos envoyées');
                } else {
                    $this->addToMessage('Erreur : Informations des candidats et photos non envoyées');
                }
            }

            // Ecris le fichier contenant les infos des unites
            $electionUnite = $this->f->get_element_by_id('election_unite', ']');
            $envoiListeUnite = $electionUnite->ecris_fichier_info_unite_affichage(array(
                'election' => $val['election'],
                'unite' => 0, // Identifiant d'unité inexistant pour ne pas que l'unité soit considéré comme envoyée
                'envoi_aff' => false
            ));
            if ($envoiListeUnite) {
                $this->addToMessage('La liste des unités a été publiée');
            } else {
                $this->addToMessage('Erreur : Liste des unités non envoyées');
            }
        }
    }


    /**
     * TRIGGER - triggermodifier.
     *
     * @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
     */
    function triggermodifier($id, &$dnu1 = null, $val = array(), $dnu2 = null) {
        //Le paramétrage n'a besoin d'être envoyé à l'affichage que dans le contexte
        //d'une election
        if ($this->is_in_context_of_foreign_key('election', $this->retourformulaire)) {
            // Suppression du repertoire des paramétres de l'affichage et réecriture des fichiers
            // Ainsi si aucun logo n'est choisi cela supprimera le logo de l'affichage
            // si un nouveau logo est choisi il remplacera le précédent
            // si le logo ne change pas il sera mis à jour
            // et le paramétrage est mis à jour
            if (file_exists('../aff/res/'.$this->getVal('election').'/animation_'.$id)) {
                $this->f->rrmdir('../aff/res/'.$this->getVal('election').'/animation_'.$id);
            }
            if ($this->envoi_affichage_logo($val['logo'], $val['election'], $id)) {
                $this->addToMessage('logo modifié');
            }
            // Ecriture du fichier de parametrage de l'animation qui servira
            // à l'affichage
            $this->aff_set_param($val, $id);
            // Ecris le fichier candidats.json et les photos des candidats dans le repertoire de l'affichage
            // Pour éviter des problèmes les photos ne sont pas copiée sur les candidats
            // des centaines. La récupération des infos des candidats doit donc être
            // faite à partir des infos de l'élection de référence pour les centaines
            $election = $this->f->get_element_by_id('election', $val['election']);
            $isCentaine = $this->f->boolean_string_to_boolean($election->getVal('is_centaine'));
            if ($isCentaine) {
                if ($this->envoi_infos_candidats_affichage(
                    $election->getVal('election_reference'),
                    $val['election']
                )) {
                    $this->addToMessage('Informations des candidats et photos envoyées');
                } else {
                    $this->addToMessage('Erreur : Informations des candidats et photos non envoyées');
                }
            } else {
                if ($this->envoi_infos_candidats_affichage($val['election'])) {
                    $this->addToMessage('Informations des candidats et photos envoyées');
                } else {
                    $this->addToMessage('Erreur : Informations des candidats et photos non envoyées');
                }
            }

            // Ecris le fichier contenant les infos des unites
            $electionUnite = $this->f->get_element_by_id('election_unite', ']');
            $envoiListeUnite = $electionUnite->ecris_fichier_info_unite_affichage(array(
                'election' => $val['election'],
                'unite' => 0, // Identifiant d'unité inexistant pour ne pas que l'unité soit considéré comme envoyée
                'envoi_aff' => false
            ));
            if ($envoiListeUnite) {
                $this->addToMessage('La liste des unités a été publiée');
            } else {
                $this->addToMessage('Erreur : Liste des unités non envoyées');
            }
        }
    }

    /**
     * TRIGGER - triggersupprimer.
     *
     * @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
     */
    function triggersupprimer($id, &$dnu1 = null, $val = array(), $dnu2 = null) {
        if (file_exists('../aff/res/'.$this->getVal('election').'animation_'.$id)) {
            $this->f->rrmdir('../aff/res/'.$this->getVal('election').'animation_'.$id);
        }
    }

    /**
     * Ecris le fichier param.ini du dossier : "aff/res/".$election."/"
     *
     * @param integer $election identifiant de l'élection
     * @param integer $ext sortie choisie (affichage 1 ou 2)
     * @param integer $refresh temps de raffraichissement
     * @param integer $perimetre perimetre pour lequel l'animation est réalisée
     * @param integer $type type d'unité à afficher
     * @param string $titre titre de l'animation
     * @param string $couleur_titre couleur du bandeau où se situe le titre
     * @param string $affichage paramétrage de l'affichage des blocs/colonnes de
     * la page
     *
     * @return void
     */
    protected function aff_set_param($val, $idAnimation) {
        // Ecriture du contenu du fichier
        $contenu = sprintf(
            "[unites]\n".
            "perimetre=%d\n".
            "type=%d\n".
            "[entete]\n".
            "titre=\"%s\"\n".
            "sous_titre =\"%s\"\n".
            "couleur_titre =\"%s\"\n".
            "couleur_bandeau=\"%s\"\n".
            "[animation]\n".
            "refresh=%d\n".
            "script=\"%s\"\n".
            "feuille_style=\"%s\"\n".
            "[comparaison]\n".
            "election=\"%s\"",
            $val['perimetre_aff'],
            $val['type_aff'],
            $val['titre'],
            $val['sous_titre'],
            $val['couleur_titre'],
            $val['couleur_bandeau'],
            $val['refresh'],
            $val['script'],
            $val['feuille_style'],
            $val['election_comparaison']
        );
        // Ecriture du fichier
        $envoi_param = $this->f->write_file("../aff/res/".$val['election']."/animation_".$idAnimation."/param.ini", $contenu);
        $envoi_blocs = $this->f->write_file("../aff/res/".$val['election']."/animation_".$idAnimation."/blocs.ini", $val['affichage']);
        return $envoi_param && $envoi_blocs;
    }

    /**
     * Récupère l'instance du logo dont l'identifiant est passé
     * en paramètre. Renvoie l'uid du logo.
     *
     * @param integer $identifiant identifiant du logo
     * @return string uid
     */
    protected function get_logo_uid($identifiant) {
        //récupération du fichier depuis la table om_logo
        $res = $this->f->get_inst__om_dbform(array(
            'obj' => 'om_logo',
            'idx' => $identifiant
        ));
        //On retourne le nom du fichier
        return $res->getVal('fichier');
    }

    /**
     * Effectue une requete permettant de récupérer les libelles
     * des candidats, ainsi que leur numéro d'ordre, leur age et l'age
     * de la liste communautaire et la couleur qui leur est associée.
     * Ces informations sont stockées dans un tableau qui est ensuite
     * converti en json.
     * Puis ecris un fichier, contenant les informations des candidats,
     * dans le repertoire voulu pour l'animation.
     * POur chaque candidat envoie également sa photo à l'affichage
     *
     * @param integer identifiant de l'élection dont on souhaite envoyer les informations
     * @param integer identifiant du répertoire ou les informations doivent être envoyé
     * si aucun id n'est renseigné c'est celui de l'élection qui est utilisé
     * @return boolean Renvoie true si le traitement à marché, false sinon.
     */
    public function envoi_infos_candidats_affichage($idElection, $idRepertoire = null) {
        if (empty($idRepertoire)) {
            $idRepertoire = $idElection;
        }
        $infosCandidats = array();
        //Liste des infos recherchées qui serviront dans la requête et
        //pour le remplissage du tableau associatif
        $infosRecherche = array(
            'election_candidat',
            'libelle',
            'libelle_liste',
            'ordre',
            'age_moyen',
            'age_moyen_com',
            'couleur'
        );
        //Récupération des infos et stockage dans un tableau. Si la
        //récupération echoue renvoie un false
        $sql = sprintf(
            'SELECT
                %s
            FROM
                '.DB_PREFIXE.'election_candidat JOIN '.DB_PREFIXE.'candidat
                ON election_candidat.candidat = candidat.candidat
            WHERE
                election = %d
            ORDER BY
                election_candidat.ordre',
            implode(', ', $infosRecherche),
            $this->f->db->escapeSimple($idElection)
        );
        $res = $this->f->db->query($sql);
        if ($this->f->is_database_error(
            $sql,
            $res,
            'Erreur lors de la récupération des informations des candidats'
        )) {
            return false;
        }
        while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
            foreach ($infosRecherche as $info) {
                $infosCandidats[$row['ordre']][$info] = $row[$info];
            }
        }
        //Ecriture du fichier contenant les infos des candidats au format
        //json
        $contenu = json_encode($infosCandidats);
        $succes = $this->f->write_file(
            '../aff/res/'.$idRepertoire.'/candidats.json',
            $contenu
        );
        // Suppression des anciennes photos des candidats
        if (file_exists('../aff/res/'.$idRepertoire.'/photo')) {
            if (! $this->f->rrmdir('../aff/res/'.$idRepertoire.'/photo')) {
                $this->addToMessage('Attention les anciennes photos des candidats n\'ont pas été supprimées !');
            }
        }
        // Envoie des photos de chaque candidats à l'affichage
        foreach ($infosCandidats as $candidat) {
            $candidat = $this->f->get_inst__om_dbform(array(
                'obj' => 'election_candidat',
                'idx' => $candidat['election_candidat']
            ));
            if (! empty($candidat->getVal('photo'))) {
                //Si un seul des succes est faux alors la variables succes sera toujours
                //fausse. Pour être vrai tout les envoies doivent réussir
                $succes = $succes &&
                    $this->envoi_photo_candidat_affichage(
                        $candidat->getVal('photo'),
                        $idRepertoire,
                        $candidat->getVal('ordre')
                    );
            }
        }
        return $succes;
    }

    /**
     * Ecris dans le répertoire de l'affichage un fichier
     * contenant l'image. Le fichier écris porte le
     * numéro d'ordre du candidat et à la même extension
     * que l'image
     *
     * @param string uid de l'image permettant de récupérer ses infos
     * @param integer identifiant du répertoire ou envoyer les infos
     * @param integer numéro d'ordre du candidat qui servira à identifier la photo
     * @return boolean true si l'écriture du fichier a réussi
     */
    protected function envoi_photo_candidat_affichage($uid, $idRepertoire, $ordre) {
        $succes = false;
        if (! empty($uid)) {
            //Récupération des inofrmation de la photo (metadata et contenu)
            //à l'aide de son uid
            $infoPhoto = $this->f->storage->get($uid);
            if (! empty($infoPhoto)) {
                //Le type est donné sous la forme : ex: image/png. Pour récupérer l'extension
                //il faut donc couper la chaîne en 2 en utilisant le / comme délimiteur et
                //prendre la deuxième partie
                $extension = explode('/', $infoPhoto['metadata']['mimetype']);
                $extension = $extension[1];
                //Ecriture du fichier contenant la photo et ayant pour nom l'identifiant
                //du candidat pour l'election
                $succes = $this->f->write_file(
                    '../aff/res/'.$idRepertoire.
                    '/photo/'.$ordre.'.'.$extension,
                    $infoPhoto['file_content']
                );
            }
        }
        return $succes;
    }

    /**
     * Indique si l'animation est active ou pas.
     * @return boolean -> true : actif, false : pas actif
     */
    protected function is_actif() {
        return $this->f->boolean_string_to_boolean($this->getVal('actif'));
    }

    /**
     * Indique si l'animation n'est pas active.
     * @return boolean -> true : pas actif, false : actif
     */
    protected function is_not_actif() {
        return ! $this->is_actif();
    }

    /**
     * Indique si l'animation est un modele d'animation ou si il s'agit
     * d'une animation pour une élection
     *
     * @return boolean
     */
    protected function is_modele_animation() {
        return $this->f->boolean_string_to_boolean($this->getVal('is_modele'));
    }
    
    /**
     * Indique si l'animation n'est pas un modele d'animation
     *
     * @return boolean
     */
    protected function is_not_modele_animation() {
        return ! $this->is_modele_animation();
    }

    /**
     * Si l'animation est liée à une élection indique si l'élection n'est
     * pas archivée
     * @return boolean
     */
    protected function election_non_archivee() {
        $idElection = $this->getVal('election');
        $electionNonArchivee = true;

        if (! empty($idElection) &&
            $this->is_in_context_of_foreign_key('election', $this->retourformulaire)
        ) {
            $election = $this->f->get_element_by_id('election', $idElection);
            $electionNonArchivee = $election->non_archivee();
        }
        return $electionNonArchivee;
    }

    /**
     * Indique si l'animation n'est pas un élément de configuration.
     * @return boolean -> true : pas config, false : config
     */
    protected function is_not_from_configuration() {
        return ! $this->f->boolean_string_to_boolean($this->getVal('is_config'));
    }

    /**
     * TREATMENT - activer.
     * Met à 'true' l'attribut actif de l'animation dans la base de
     * donnée. Affiche un message et renvoie un booleen indiquant
     * si le traitement a fonctionné ou pas.
     *
     * @return boolean indique si le traitement a fonctionné
     */
    protected function activer($val = array(), $dnu1 = null, $dnu2 = null) {
        $this->begin_treatment(__METHOD__);

        $res = $this->f->db->autoExecute(
            DB_PREFIXE.'animation',
            array(
                'actif' => true,
            ),
            DB_AUTOQUERY_UPDATE,
            'animation = '.$this->getVal('animation')
        );
        if ($this->f->isDatabaseError($res, true)) {
            return $this->end_treatment(__METHOD__, false);
        }

        $this->addToMessage('L\'élément a été correctement activé.');

        return $this->end_treatment(__METHOD__, true);
    }

    /**
     * TREATMENT - desactiver.
     * Met à 'false' l'attribut actif de l'animation dans la base de
     * donnée. Affiche un message et renvoie un booleen indiquant
     * si le traitement a fonctionné ou pas.
     *
     * @return boolean indique si le traitement a fonctionné
     */
    protected function desactiver($val = array(), $dnu1 = null, $dnu2 = null) {
        $this->begin_treatment(__METHOD__);

        $res = $this->f->db->autoExecute(
            DB_PREFIXE.'animation',
            array(
                'actif' => false,
            ),
            DB_AUTOQUERY_UPDATE,
            'animation = '.$this->getVal('animation')
        );
        if ($this->f->isDatabaseError($res, true)) {
            return $this->end_treatment(__METHOD__, false);
        }

        $this->addToMessage('L\'élément a été correctement désactivé.');

        return $this->end_treatment(__METHOD__, true);
    }

    /**
     * Créer une nouvelle animation en tant que modèle en copiant les
     * valeur de l'animation que l'on souhaite garder comme modele
     *
     * @return boolean indique si le traitement a fonctionné
     */
    protected function creer_modele($val = array(), $dnu1 = null, $dnu2 = null) {
        // Préparation des valeurs du modele
        $valModele = array();
        // Valeur devant être null pour un modele
        $pasModele = array('election', 'type_aff', 'perimetre_aff', 'animation');
        foreach ($this->champs as $champs) {
            $valModele[$champs] = $this->getVal($champs);
            if (in_array($champs, $pasModele)) {
                $valModele[$champs] = null;
            }
        }
        $valModele['is_modele'] = true;
        $valModele['libelle'] = 'Modèle - '.$this->getVal('libelle');

        $ajout = $this->f->ajouter_element_BD('animation', $valModele);
        if (! $ajout) {
            $this->addToMessage('Erreur : le modèle n\'a pas été enregistré');
            return false;
        }

        $this->addToMessage('Modèle enregistré');
        return true;
    }
}
