Subversion Repositories eFlore/Applications.del

Rev

Rev 2179 | Rev 2210 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

<?php
// declare(encoding='UTF-8');
/**
 * Web service permetant d'ajouter ou de modifier les votes associés aux propositions d'une observation.
 *
 * @category   DEL
 * @package    Services
 * @subpackage Observations
 * @version    0.1
 * @author     Mathias CHOUET <mathias@tela-botanica.org>
 * @author     Jean-Pascal MILCENT <jpm@tela-botanica.org>
 * @author     Aurelien PERONNET <aurelien@tela-botanica.org>
 * @license    GPL v3 <http://www.gnu.org/licenses/gpl.txt>
 * @license    CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
 * @copyright  1999-2014 Tela Botanica <accueil@tela-botanica.org>
 */

class VoteObservation {
        private $conteneur;
        private $bdd;
        private $navigation;
        private $mapping;
        private $ressources;
        private $parametres;

        public function __construct(Conteneur $conteneur = null) {
                $this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
                $this->bdd = $this->conteneur->getBdd();
                $this->navigation = $conteneur->getNavigation();

                $this->mapping = $this->conteneur->getParametreTableau('votes.mapping');
        }

        public function consulter($ressources, $parametres) {
                $this->ressources = $ressources;
                $this->parametres = $parametres;

                $votes = $this->chargerVotes();
                $this->conteneur->getNavigation()->setTotal(count($votes));
                // Mettre en forme le résultat et l'envoyer pour affichage
                $resultat = new ResultatService();
                $resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => $votes);
                return $resultat;
        }

        private function chargerVotes() {
                $idCommentaireP = $this->bdd->proteger($this->ressources[1]);
                $requete = 'SELECT * '.
                        'FROM del_commentaire_vote '.
                        "WHERE ce_proposition = $idCommentaireP ";
                        ' -- '.__FILE__.':'.__LINE__;
                $resultats = $this->bdd->recupererTous($requete);
                $votes = array();
                foreach ($resultats as $vote) {
                        $votes[$vote['id_vote']] = $this->formaterVotes($vote);
                        $utilisateur = $this->chercherUtilisateur($vote['ce_utilisateur']);
                        if ($utilisateur && count($utilisateur) > 0) {
                                $votes[$vote['id_vote']] = array_merge($votes[$vote['id_vote']], $utilisateur);
                        }
                }
                return $votes;
        }

        private function formaterVotes($vote) {
                $retour = array();
                foreach ($vote as $param => $valeur) {
                        $retour[$this->mapping[$param]] = $valeur;
                }
                return $retour;
        }

        /**
         * Recherche les coordonnées d'un utilisateur en fonction de son ID;
         * puisqu'il a un ID c'est qu'il est connecté, on suppose donc qu'il
         * a un tuple dans del_utilisateur_infos
         * 
         * @TODO vérifier cette hypothèse
         */
        private function chercherUtilisateur($id) {
                // par défaut, pas d'info
                $utilisateur = array();
                // Si l'id utilisateur est un hash de session, on ne cherche rien
                if (is_numeric($id)) {
                        $idUtilisateurP = $this->bdd->proteger($id);
                        $requete = "SELECT id_utilisateur AS 'auteur.id', nom AS 'auteur.nom', prenom AS 'auteur.prenom', ".
                                "courriel AS 'auteur.courriel' ".
                                'FROM del_utilisateur_infos '.
                                "WHERE id_utilisateur = $idUtilisateurP ".
                                ' -- '.__FILE__.':'.__LINE__;
                        $utilisateur = $this->bdd->recuperer($requete);
                }
                return $utilisateur;
        }

        public function ajouter($ressources, $parametres) {
                $this->ressources = $ressources;
                $this->parametres = $parametres;
                $this->verifierParametresAjoutModif();
                $idVote = $this->ajouterVote();
                if ($idVote) {
                        $resultat = new ResultatService();
                        $resultat->corps = array('id_vote' => $idVote);
                        return $resultat;
                }
                return false;
        }

        private function ajouterVote() {
                $idProposition = $this->creerPropositionDeterminationInitiale();

                $idObsP = $this->bdd->proteger($this->ressources[0]);
                $idPropositionP = $this->bdd->proteger($idProposition);
                $idUtilisateurP = $this->bdd->proteger($this->parametres['utilisateur']);
                $valeurP = $this->bdd->proteger($this->parametres['valeur']);
                $requete = 'INSERT INTO del_commentaire_vote (ce_proposition , ce_utilisateur , valeur , date) '.
                        "VALUES ($idPropositionP, $idUtilisateurP, $valeurP, NOW()) ".
                        ' -- '.__FILE__.' : '.__LINE__;

                $resultat = $this->bdd->executer($requete);
                if ($resultat === false) {
                        $msg = "Un problème est survenu lors de l'ajout d'un vote.";
                        throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
                } else if ($resultat === 0) {
                        $msg = "Aucun vote ne correspond au critères fournis : ".
                                "idObs -> $idObsP, idProposition -> $idPropositionP et id_utilisateur -> $idUtilisateurP.";
                        throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
                }
                // ATTENTION : idVote doit être récupéré avant toute nouvelle requete !
                $idVote = $this->bdd->recupererIdDernierAjout();
                
                $requete = "UPDATE tb_new_cel.`occurrence` join
        (SELECT ce_observation, id_commentaire, nom_sel_nn, `proposition_retenue` FROM `del_commentaire` WHERE id_commentaire = ".$idPropositionP.") c
        on id = ce_observation AND user_sci_name_id= `nom_sel_nn`
        SET `identiplante_score`= case
                when ".$this->parametres['valeur']." = 0 and ".$idUtilisateurP." REGEXP '^-?[0-9]+$' then ifnull(identiplante_score, 0) -3
                when ".$this->parametres['valeur']." = 0 then ifnull(identiplante_score, 0) -1
                when ".$this->parametres['valeur']." = 1 and ".$idUtilisateurP." REGEXP '^-?[0-9]+$' then ifnull(identiplante_score, 0) + 3
                when ".$this->parametres['valeur']." = 1 then ifnull(identiplante_score, 0) + 1 END;";
                
                $resultat = $this->bdd->executer($requete);
                return $idVote;
        }

        /** Si l'identifiant de proposition vaut 0, c'est un vote sur une proposition
         * fabriquée à partir de l'observation originale, dont on doit obtenir l'id
         * (cas où l'on vient de voter pour celle et cela a créé la proposition, puis
         * on revote pour celle ci en changeant d'avis sans recharger la page)
         */
        private function creerPropositionDeterminationInitiale() {
                $idProposition = $this->ressources[1];
                if ($idProposition == 0) {
                        $propositionExiste = $this->verifierExistencePropositionInitiale();
                        if ($propositionExiste === false) {
                                $idProposition = $this->creerPropositionInitiale();
                        } else {
                                $idProposition = $this->getIdPropositionInitiale();
                        }
                }
                return $idProposition;
        }

        private function verifierExistencePropositionInitiale() {
                $idObservationP = $this->bdd->proteger($this->ressources[0]);
                $requete = 'SELECT COUNT(*) >= 1 AS existe '.
                        'FROM del_commentaire '.
                        "WHERE ce_observation = $idObservationP ".
                        'AND proposition_initiale = 1 '.
                        ' -- '.__FILE__.' : '.__LINE__;
                $resultat = $this->bdd->recuperer($requete);
                return $resultat['existe'] == 1;
        }

        private function creerPropositionInitiale() {
                $idObservationP = $this->bdd->proteger($this->ressources[0]);
                $requete = 'INSERT IGNORE INTO del_commentaire '.
                        '(ce_observation, ce_utilisateur, utilisateur_prenom, utilisateur_nom, utilisateur_courriel, '.
                        'nom_sel, nom_sel_nn, nom_ret, nom_ret_nn, nt, famille, nom_referentiel, date, proposition_initiale) '.
                        'SELECT id_observation, ce_utilisateur, prenom_utilisateur, nom_utilisateur, '.
                        '               courriel_utilisateur, nom_sel, nom_sel_nn, nom_ret, nom_ret_nn, '.
                        "               nt, famille, nom_referentiel, NOW(), '1' ".
                        'FROM del_observation do '.
                        "WHERE id_observation = $idObservationP ".
                        ' -- '.__FILE__.' : '.__LINE__;

                $this->bdd->executer($requete);
                $id = $this->bdd->recupererIdDernierAjout();
                return $id;
        }

        private function getIdPropositionInitiale() {
                $idObservationP = $this->bdd->proteger($this->ressources[0]);
                $requete = 'SELECT id_commentaire '.
                        'FROM del_commentaire '.
                        "WHERE ce_observation = $idObservationP ".
                        'AND proposition_initiale = 1 '.
                        ' -- '.__FILE__.' : '.__LINE__;
                $resultat = $this->bdd->recuperer($requete);
                return $resultat['id_commentaire'];
        }

        public function modifier($ressources, $parametres) {
                $this->ressources = $ressources;
                $this->parametres = $parametres;
                $this->verifierParametresAjoutModif();
                $resultat = $this->modifierVote();
                if ($resultat > 0) {
                        return 'ok';
                }
        }

        private function modifierVote() {
                // protection anti-usurpateurs @TODO faudrait pt-être la faire !
                $idUtilisateur = $this->parametres['utilisateur'];
                /*$gestionUtilisateurs = $this->conteneur->getUtilisateur();
                $gestionUtilisateurs->controleUtilisateurIdentifie($idUtilisateur);*/

                $idObsP = $this->bdd->proteger($this->ressources[0]);
                $idPropositionP = $this->bdd->proteger($this->ressources[1]);
                $idUtilisateurP = $this->bdd->proteger($idUtilisateur);
                $valeurP = $this->bdd->proteger($this->parametres['valeur']);
                $requete = 'UPDATE del_commentaire_vote '.
                        "SET valeur = $valeurP, date = NOW() ".
                        "WHERE ce_proposition = $idPropositionP AND ce_utilisateur = $idUtilisateurP ".
                        ' -- '.__FILE__.' : '.__LINE__;

                $resultat = $this->bdd->executer($requete);
                if ($resultat === false) {
                        $msg = "Une erreur est survenue lors de la tentative de modification du vote.";
                        throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
                } else if ($resultat === 0) {
                        $msg = "Aucun vote ne correspond au critères fournis : ".
                                "idObs -> $idObsP, idProposition -> $idPropositionP et id_utilisateur -> $idUtilisateurP.";
                        throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
                }
                $requete = "UPDATE tb_new_cel.`occurrence` join
        (SELECT ce_observation, id_commentaire, nom_sel_nn, `proposition_retenue` FROM `del_commentaire` WHERE id_commentaire = ".$idPropositionP.") c
        on id = ce_observation AND user_sci_name_id= `nom_sel_nn`
        SET `identiplante_score`= case
                when ".$this->parametres['valeur']." = 0 and ".$idUtilisateurP." REGEXP '^-?[0-9]+$' then ifnull(identiplante_score, 0) -6
                when ".$this->parametres['valeur']." = 0 then ifnull(identiplante_score, 0) -2
                when ".$this->parametres['valeur']." = 1 and ".$idUtilisateurP." REGEXP '^-?[0-9]+$' then ifnull(identiplante_score, 0) + 6
                when ".$this->parametres['valeur']." = 1 then ifnull(identiplante_score, 0) + 2 END;";
                
                $resultat = $this->bdd->executer($requete);
                
                return $resultat;
        }

        private function verifierParametresAjoutModif() {
                $erreurs = array();

                if (!isset($this->parametres['utilisateur'])) {
                        $erreurs[] = 'Paramètre "utilisateur" manquant.';
                }

                if (!isset($this->parametres['valeur'])) {
                        $erreurs[] = 'Paramètre "valeur" manquant.';
                } else {
                        if (!is_numeric($this->parametres['valeur'])) {
                                $erreurs[] = 'Le paramètre "valeur" doit être numérique.';
                        } elseif($this->parametres['valeur'] != 0 && $this->parametres['valeur'] != 1) {
                                $erreurs[] = 'Le paramètre "valeur" ne peut prendre que la valeur 0 ou 1.';
                        }
                }

                if (!empty($erreurs)) {
                        $msg = "Erreur lors de la configuration : \n".implode("\n", $erreurs);
                        throw new Exception($msg, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
                }
        }
}