<?php
//$Id$

require_once "../obj/instruction.class.php";

class instruction_modale extends instruction {

/**
*
*/
protected $_absolute_class_name = "instruction_modale";

    /**
     * Définition des actions disponibles sur la classe.
     *
     * @return void
     */
    function init_class_actions() {
        parent::init_class_actions();

        // ACTION - 115 - view_formulaire_selection_document_signe
        $this->class_actions[115] = array(
            "identifier" => "selection_document_signe",
            "view" => "view_formulaire_selection_document_signe",
            "permission_suffix" => "selection_document_signe",
        );
    }


    /**
     * VIEW - view_formulaire_selection_document_signe.
     *
     * Formulaire d'envoi d'un document signé dans une instruction:
     *  - Un message d'alerte doit indiquer du caractère irrémédiable de l'action 
     *    (écrasement du fichier existant)
     *  - L'utilisateur doit sélectionner un fichier à téléverser (champs obligatoire)
     *  - L'utilisateur peux saisir une date de retour d'avis.
     *  
     * A la validation de ce formulaire:
     *  - Une alerte de succès (verte) doit apparaitre et informer l'utilisateur du bon
     *    déroulement de la mise à jour du document de l'instruction.
     *  - le fichier visible dans l'action "Édition" doit être
     *    le document téléversé par l'utilisateur, 
     *
     * @return void
     */
    function view_formulaire_selection_document_signe() {
        // Vérification de l'accessibilité sur l'élément
        $this->checkAccessibility();

        // Non affichage du fil d'ariane. /!\ la surcharge se fait
        // depuis la méthode getSubFormTitle en renseignant le numéro de l'action
        // dans la méthode puis en appellant la méthode
        $this->getSubFormTitle('');

        //
        // Traitement des données du formulaire
        //
        $postValues = $this->f->get_submitted_post_value();

        // Paramétrage du formulaire
        // a. Tableau de champs
        $champs = array('document_signe', 'modale_date_retour_signature');
        // b. Instanciation du formulaire 
        $form = $this->f->get_inst__om_formulaire(array(
            "validation" => 0,
            "maj" => $this->getParameter("maj"),
            "champs" => $champs
        ));

        // Paramétrage du champs type 'file' pour téléverser le document signé
        $form->setLib('document_signe', __('Document signé'));
        $form->setType('document_signe', 'upload2');
        $form->setTaille('document_signe', 64);
        $form->setMax('document_signe', 30);
        $form->setVal('document_signe', '');

        // Paramétrage du champs type 'date' afin de sélectionner une date de retour signature
        $form->setLib('modale_date_retour_signature', __('Date de retour signature'));
        $form->setType('modale_date_retour_signature', 'date');
        $form->setTaille('modale_date_retour_signature', 10);
        $form->setMax('modale_date_retour_signature', 10);
        $form->setVal('modale_date_retour_signature', '');
        $form->setOnchange('modale_date_retour_signature', "fdate(this)");

        // Affichage message d'information :
        $this->f->displayMessage('info',
            __("Sélectionnez un document et cliquez sur Valider pour ajouter votre document d'instruction signé.
                Le dernier document généré de l'instruction sera conservé et disponible depuis l'onglet \"Pièces & documents\" > \"Docs. instruction\"")
        );

        if ($postValues != null && is_array($postValues) && $postValues != array()) {
            $error = false;
            $message = __("Le document a bien été mis à jour.");
            // On vérifie que le champs de fichier a bien été renseigné
            if ($postValues['document_signe'] === '') {
                $error = true;
                $message = __("Le champs 'Document signé' est obligatoire");
            } else {
                $res = $this->treatment_document_sign($postValues);
                if ($res['error'] === true) {
                    $error = $res['error'];
                    $message = $res['msg'];
                }
            };

            // On affiche le message d'erreur/de succès.
            $typeMessage = $error ? 'error' : 'valid';
            $add_message = "";
            if ($error === false) {
                $add_message = $res['msg'];
            }
            $message = $message.$add_message;
            $this->f->displayMessage($typeMessage, $message.$add_message);

            if ($error === true) {
                $log_msg = __('Erreur lors de la sélection du fichier signé - id instruction : %s - uid fichier : %s');
                $this->addToLog(__METHOD__."(): ".sprintf($log_msg, $this->getVal($this->clePrimaire), $this->getVal('om_fichier_instruction')), DEBUG_MODE);
            } 
        };

        // Affichage du formulaire
        $onsubmit = sprintf(
            "
            affichersform('instruction_modale', '%1\$s', this);
            form_container_refresh('sousform');
            return false;",
            $this->getDataSubmit()
        );
    
        $this->afficher_formulaire_modale($form, $champs, $onsubmit);
    }

    /**
     * Traitement d'un document signé.
     *
     * @param  array  $post_values Valeurs POST du formulaire
     * @return array               Tableau contenant un message et un booléen
     *                             d'erreur
     */
    protected function treatment_document_sign($post_values = array()) {
        // Récupération et sauvegarde du fichier précédemment géneré
        // Get du fichier depuis la table instruction
        $old_file = $this->f->storage->get($this->getVal('om_fichier_instruction'));
        // Si un fichier précédent existe dans instruction
        if ($old_file !== null) {
             // On recupère le nom normalisé en base
            $new_file = $this->getVal('fichier_instruction_name');
             // On traite la config des extension acceptées par openads et on supprime la derniere "|" de la liste pour eviter un doublon
            $extensions = str_replace(';', '|', $this->f->config['upload_extension']); // Recupère tous les types de fichier acceptés par openADS
            $extensions = rtrim($extensions, '|');
             // Rename du fichier
            $old_file['metadata']['filename'] = preg_replace(
                '/(' . $extensions . ')$/', // Cherche une des extensions autorisées à la fin du nom de fichier
                "_remplace_le_" . date('YmdHis') . "$1", // Construit le nouveau nom
                $new_file
            );
            // Création du fichier dans le storage 
            $uid = $this->f->storage->create(
                $old_file['file_content'], 
                $old_file['metadata'],
                "from_content",
                "storage.uid"
            );
             // Si le fichier est bien sauvegarder
            if ($uid  == OP_FAILURE) {
                return array('error' => true, 'msg' => __("Une erreur est survenue, veuillez réessayer ultérieurement"));
            }
            $dossier = $this->getVal('dossier');
            $collectivite_di = $this->get_dossier_instruction_om_collectivite($dossier);
             // Ajouter le fichier stocker à la table storage
            if( $this->ajouter_histo_ri_table_storage($uid,  $old_file['metadata'], 1, $collectivite_di) === false) {
                // Supprimer le fichier du storage en cas d'erreur, pour conserver une stockage propre.
                $res_delete = $this->f->storage->delete($uid);
                return array('error' => true, 'msg' => __("Une erreur est survenue, veuillez réessayer ultérieurement"));
            }
        }
        // Update du fichier généré par l'instruction
        // On enlève le 'tmp|' du nom du fichier téleversé dans le champs "document_signe"
        $postValues = $this->f->get_submitted_post_value();
        $docSigne = $this->f->storage->get_temporary(str_replace('tmp|', '', $postValues['document_signe']));
        // Gestion des métadonnées
        $spe_metadata = $this->calculate_metadata();
        if ($spe_metadata === false) {
            return array('error' => true, 'msg' => __("Une erreur est survenue, veuillez réessayer ultérieurement"));
        }
        $docSigne['metadata'] = array_merge($docSigne['metadata'], $spe_metadata);
        $docSigne['metadata']['filename'] = $this->getVal('fichier_instruction_name');
        $docUpdate = $this->f->storage->update($this->getVal('om_fichier_instruction'), $docSigne['file_content'], $docSigne['metadata']);
        if ($docUpdate !== $this->getVal('om_fichier_instruction')) {
            return array('error' => true, 'msg' => __("Une erreur est survenue, veuillez réessayer ultérieurement"));
        }
        // Update de la date de retour signature
        // Le champs "Date" n'est pas obligatoire;
        // si la date est indiquée, on modifie les valeurs du formulaire de l'instruction
        // et on ajoute un message indiquant l'ajout de date de retour signature
        if($postValues["modale_date_retour_signature"] !== '') {
            $instData = array_combine($this->champs, $this->val);
            $instData['date_retour_signature'] = $postValues["modale_date_retour_signature"];
            $res = $this->modifier($instData);
            if ($res === false) {
                return array('error' => true, 'msg' => __("Une erreur est survenue, veuillez réessayer ultérieurement"));
            }
        }
        return array('error' => false, 'msg' => __("<br />La date de retour signature a bien été mise à jour."));
    }
    

    /**
     * Récupère les informations nécessaire au stockage de l'édition de l'instruction
     * et le stocke dans la table storage.
     */
    protected function ajouter_histo_ri_table_storage($uid, $metadata, $version, $dossier_instruction_om_collectivite) {
        // Prepare vals
        $lettretype = $this->getVal('lettretype');

        $om_edition = $this->f->get_inst__om_edition();
        $edition = $om_edition->get_edition_from_collectivite('om_lettretype', $lettretype, $dossier_instruction_om_collectivite);
        $om_lettretype = $this->f->get_inst__om_dbform(array(
            "obj" => "om_lettretype",
            "idx" => isset($edition['om_lettretype']) === true ? $edition['om_lettretype'] : 0,
        ));
        if ($om_lettretype->exists() !== true) {
            return false;
        }

        $document_type = $this->f->get_inst__om_dbform(array(
            "obj" => "document_type",
            "idx" => $this->getVal('document_type_instruction'),
        ));

        // Préparation du json contenant les données manquantes du tableau
        $jsonInfo = json_encode(array(
            'version' => $version,
            'createur' => $this->f->get_connected_user_login_name(),
            'instruction' => $this->getVal('instruction'),
            'dossier' => $this->getVal('dossier'),
            'evenement' => $this->getVal('evenement'),
            'lettretype' => $lettretype,
            'document_type' => $this->getVal('document_type_instruction'),
            'document_type_libelle' => $document_type->getVal("libelle"),
            'lettretype_libelle' => $om_lettretype->getVal('libelle'),
            'date_finalisation_courrier' => $this->getVal('date_finalisation_courrier'),
            'date_retour_rar' => $this->getVal('date_retour_rar'),
            'date_evenement' => $this->getVal('date_evenement'),
            'can_be_document_instruction' => 'true',
            'can_be_dossier_final' => 'false',
            'can_be_telechargement' => 'false'
        ));

        // Préparation du tableau contenant les valeurs à transmettre à la BD 
        $storage_id = $this->f->get_next_id_from_db_sequence(DB_PREFIXE.'storage', array("origin" => __METHOD__));
        $valF = array(
            'storage' => $storage_id["result"],
            'creation_date' => date('Y-m-d'),
            'creation_time' => date('H:i:s'),
            'uid' => $uid,
            'filename' => $metadata['filename'],
            'size' => $metadata['size'],
            'mimetype' => $metadata['mimetype'],
            'type' => 'document_instruction_generer',
            'info' => "$jsonInfo",
            'om_collectivite' => $dossier_instruction_om_collectivite
        );
        // Remplissage de la table storage en y ajoutant le document finalisé
        $qres = $this->f->execute_auto_db_query(
            'insert',
            DB_PREFIXE.'storage',
            $valF,
            null,
            array(
                'origin' => __METHOD__,
                'force_return' => true,
            )
        );

        if ($qres['code'] !== 'OK') {
            return false;
        }

        return true;
    }

    protected function afficher_formulaire_modale(
        $form,
        $champs,
        $formOnsubmit = '',
        $valueBoutonValidation = 'Valider',
        $formAction = '',
        $formName = 'f2',
        $nameBoutonValidation = "submit-directory",
        $classBoutonValidation = "boutonFormulaire"
    ) {
        // Ouverture du formulaire
        $this->f->layout->display__form_container__begin(array(
            "action" => $formAction,
            "onsubmit" => $formOnsubmit,
            "name" => $formName,
        ));
        // Ouverture du conteneur de formulaire
        $form->entete();
        // Affichage des champs
        $form->afficher($champs, 0, false, false);
        // Fermeture du conteneur de formulaire
        $form->enpied();
        // Ouverture de la zone contenant le bouton de validation
        $this->f->layout->display__form_controls_container__begin(array(
            "controls" => "bottom",
        ));
        // Affichage du bouton valider
        $this->f->layout->display__form_input_submit(array(
            "name" => $nameBoutonValidation,
            "value" => $valueBoutonValidation,
            "class" => $classBoutonValidation,
        ));
        // Fermeture de la zone contenant le bouton de validation
        $this->f->layout->display__form_controls_container__end();
        // Fermeture du formulaire
        $this->f->layout->display__form_container__end();
    }
}
