Subversion Repositories eFlore/Applications.del

Rev

Rev 1305 | Blame | Compare with Previous | Last modification | View Log | RSS feed

<?php
// declare(encoding='UTF-8');
/**
 * Les web service permet d'ajouter ou de modifier les votes associés aux propositions d'une observation
 *
 * @category    php 5.2
 * @package     del
 * @subpackage images
 * @author              Jean-Pascal MILCENT <jpm@tela-botanica.org>
 * @copyright   Copyright (c) 2012, Tela Botanica (accueil@tela-botanica.org)
 * @license     http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
 * @license     http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
 * @version     $Id: Bdd.php 403 2012-02-22 14:35:20Z gduche $
 * @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=ApiIdentiplante01Images
 */

class VoteObservation extends RestService {
        protected $conteneur;
        protected $gestionBdd;
        protected $bdd;
        protected $navigation;


        public function __construct(Conteneur $conteneur = null) {
                $this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
                $this->gestionBdd = $conteneur->getGestionBdd();
                $this->bdd = $this->gestionBdd->getBdd();
                $this->navigation = $conteneur->getNavigation();
                $this->conteneur->chargerConfiguration('config_mapping_votes.ini');
        }

        /**
        * Configuration du service en fonction du fichier de config config_del.ini
        * */
        private function configurer() {
                $this->mappingVotes = $this->conteneur->getParametre('mapping_votes');
        }

        /**
         * Méthode seulement présente pour interdire proprement l'accès à la consultation
         * */
        public function consulter($ressources, $parametres) {

                $this->configurer();

                //TODO: faut il vérifier quelque chose, si on n'a pas renseigné les valeurs correctement
                // dans ressource, le service n'est même pas appelé
                $votes = $this->chargerVotes($ressources[1]);
                $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->conteneur->getEntete(), 'resultats' => $votes);
                return $resultat;
        }

        private function chargerVotes($id_commentaire) {
                $requeteVotes = 'SELECT * FROM '.
                $this->gestionBdd->formaterTable('del_commentaire_vote').
                                'WHERE ce_proposition = '.$this->proteger($id_commentaire);
                $resultatsVotes = $this->bdd->recupererTous($requeteVotes);
                $votes = array();
                foreach ($resultatsVotes as $vote) {
                        $votes[$vote['id_vote']] = $this->formaterVotes($vote);
                        $utilisateur = $this->chercherUtilisateur($vote['ce_utilisateur']);
                        if($utilisateur) {
                                $votes[$vote['id_vote']] = array_merge($votes[$vote['id_vote']], $utilisateur);
                        }
                }
                return $votes;
        }

        /**
        * Trouver l'utilisateur en fonction des paramètres ou de la base de données si le nom, prénom et courriel ne sont pas donnés
        * @return le tableau utilisateur
        * */
        private function chercherUtilisateur($id) {
                $utilisateur = array();
                $requete = "SELECT id_utilisateur as 'auteur.id', nom as 'auteur.nom', prenom as 'auteur.prenom', courriel as 'auteur.courriel' ".
                                                           'FROM '.$this->gestionBdd->formaterTable('del_utilisateur').
                                                                   'WHERE id_utilisateur = '.$this->bdd->proteger($id);
                $utilisateur = $this->bdd->recuperer($requete);

                return $utilisateur;
        }

        /**
        *  Formater un vote en fonction du fichier de configuration config_votes.ini
        *  @param $votes array()
        * */
        private function formaterVotes($vote) {
                $retour = array();
                foreach ($vote as $param => $valeur) {
                        $retour[$this->mappingVotes[$param]] = $valeur;
                }
                return $retour;
        }

        /**
        * Ajoute un vote à une proposition grâce aux informations passées en paramètres
        * @param array $ressources tableau des informations contenues dans l'url après le nom du service
        * @param array $parametres contenu du post
        *
        * @return void
        *
        * */
        public function ajouter($ressources, $parametres) {

                $this->verifierParametresAjoutModif($ressources, $parametres);

                // Vérifie si la proposition existe, et la crée sinon
                // (cas du vote sur la proposition fabriquée à partir de l'observation originale)
                if($ressources[1] == 0) {
                        $ressources[1] = $this->renvoyerIdOuCreerPropositionDeterminationInitiale($ressources[0]);
                }

                $insertion = 'INSERT INTO del_commentaire_vote '.
                                                        '(ce_proposition , ce_utilisateur , valeur , date) '.
                                                        'VALUES ('.$this->proteger($ressources[1]).','.$this->proteger($parametres['utilisateur']).','.
                                                        $this->proteger($parametres['valeur']).', NOW());';
                $resultatsVotes = $this->bdd->requeter($insertion);
                if ($resultatsVotes == false) {
                        RestServeur::envoyerEnteteStatutHttp(RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
                } else {
                        RestServeur::envoyerEnteteStatutHttp(RestServeur::HTTP_CODE_CREATION_OK);
                }
        }

        private function renvoyerIdPropositionObservation($id_observation) {

                $id_commentaire = null;
                // Récupération de l'utilisateur + nom sel de l'observation originale
                $requete_selection_obs = 'SELECT ce_utilisateur, nom_sel '.
                                           'FROM del_observation '.
                                           'WHERE id_observation ='.$this->proteger($id_observation);

                $obs = $this->bdd->recuperer($requete_selection_obs);

                if(is_array($obs) && isset($obs['ce_utilisateur'])) {
                        // On considère que la proposition faite par le même utilisateur et ayant le même
                        // nom sélectionné est bien la proposition composée à partir de l'obs originale
                        $requete_selection_comm = 'SELECT id_commentaire FROM del_commentaire '.
                                   'WHERE ce_observation = '.$this->proteger($id_observation).' '.
                                   ' AND nom_sel = '.$this->proteger($obs['nom_sel']).' AND '.
                                           ' ce_utilisateur = '.$this->proteger($obs['ce_utilisateur']);

                        $commentaire = $this->bdd->recuperer($requete_selection_comm);
                        $id_commentaire = (is_array($commentaire) && $commentaire['id_commentaire'] != null) ? $commentaire['id_commentaire'] : null;
                }

                return $id_commentaire;
        }

        private function renvoyerIdOuCreerPropositionDeterminationInitiale($id_observation) {
                $proposition_existe = $this->propositionInitialeExiste($id_observation);
                if(!$proposition_existe) {
                        $id_proposition = $this->creerPropositionAPartirObservation($id_observation);
                } else {
                        $requete = "SELECT id_commentaire FROM del_commentaire WHERE ce_observation = ".$id_observation." ".
                                           "AND proposition_initiale = 1";
                        $resultat = $this->bdd->recuperer($requete);
                        $id_proposition = $resultat['id_commentaire'];
                }
                return $id_proposition;
        }

        private function propositionInitialeExiste($id_observation) {

                $requete = "SELECT COUNT(*) >= 1 as existe FROM del_commentaire WHERE ce_observation = ".$id_observation." ".
                                                                                                "AND proposition_initiale = 1";
                $resultat = $this->bdd->recuperer($requete);
                return $resultat['existe'] == 1;
        }

        private function creerPropositionAPartirObservation($id_observation) {

                $insertion = '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, nom, '.
                        '               courriel, nom_sel, nom_sel_nn, nom_ret, nom_ret_nn, '.
                        "               nt, famille, 'bdtfx_v1', NOW(), '1' ".
                        'FROM del_observation do '.
                                ' LEFT JOIN del_utilisateur du ON '.
                                'do.ce_utilisateur = du.id_utilisateur '.
                        'WHERE id_observation = '.$this->proteger($id_observation);

                $resultat = $this->bdd->requeter($insertion);
                // Attention à l'abstraction utilisée, récupérer le dernier id en mysql ou msqli ça marche bien, mais pour d'autres moins
                $id = $this->bdd->recupererIdDernierAjout();

                return $id;
        }

        /**
        * Modifie un vote associé à une proposition grâce aux informations passées en paramètres
        * @param array $ressources tableau des informations contenues dans l'url après le nom du service
        * @param array $parametres contenu du post
        *
        * @return void
        *
        * */
        public function modifier($ressources, $parametres) {

                $this->verifierParametresAjoutModif($ressources, $parametres);

                // 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)
                if($ressources[1] == 0) {
                        $id_proposition = $this->renvoyerIdOuCreerPropositionDeterminationInitiale($ressources[0]);
                        if($id_proposition == null) {
                                $this->envoyerMessageErreurIdProposition();
                                exit;
                        } else {
                                $ressources[1] = $id_proposition;
                        }
                }

                $modification = 'UPDATE del_commentaire_vote '.
                                                'SET valeur ='.$this->proteger($parametres['valeur']).', '.
                                                'date = NOW() '.
                                                'WHERE '.
                                                        'ce_proposition = '.$this->proteger($ressources[1]).' AND '.
                                                        'ce_utilisateur = '.$this->proteger($parametres['utilisateur']);

                $resultatsVotes = $this->bdd->requeter($modification);
                if ($resultatsVotes == false) {
                        RestServeur::envoyerEnteteStatutHttp(RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
                } else {
                        RestServeur::envoyerEnteteStatutHttp(RestServeur::HTTP_CODE_OK);
                }
        }

        public function verifierParametresAjoutModif($ressources, $parametres) {
                $erreurs = array();
                if (!is_numeric($ressources[1])) {
                        $erreurs[] = '- le paramètre indiquant l\'identifiant de la proposition doit être numérique ;';
                }

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

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

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

        protected function envoyerMessageErreurIdProposition() {
                $erreurs = array('Aucun identifiant de proposition n\'est lié à cette observation');
                $e = 'Erreur lors de la configuration : '."\n";
                $e .= implode("\n", $erreurs);
                RestServeur::ajouterMessage($e);
                throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
        }

        protected function proteger($valeur) {
                if (is_array($valeur)) {
                        return $this->bdd->protegerTableau($valeur);
                } else {
                        return $this->bdd->proteger($valeur);
                }
        }
}
?>