Subversion Repositories eFlore/Applications.del

Rev

Blame | Last modification | View Log | RSS feed

<?php
// declare(encoding='UTF-8');
/**
 * Le web service image récupère toutes les données de la table del_obs_images
 * pour retourner une liste d'images associée à une observation
 *
 * @category   DEL
 * @package    Services
 * @subpackage Images
 * @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 VotesImage {

        private $conteneur;
        private $navigation;
        private $bdd;
        private $mapping = array();
        private $ressources;
        private $parametres;

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

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

        /**
         * Méthode principale de la classe.
         * Lance la récupération des images dans la base et les place dans un objet ResultatService
         * pour l'afficher.
         * @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2)
         * @param array $parametres les paramètres situés après le ? dans l'url
         * */
        public function consulter($ressources, $parametres) {
                $this->ressources = $ressources;
                $this->parametres = $parametres;

                // Lancement du service
                $votes = $this->chargerVotes();
                $total = $this->compterVotes();
                $this->navigation->setTotal($total);

                // 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() {
                $idImgP = $this->bdd->proteger($this->ressources[0]);
                $idProtocoleP = isset($this->parametres['protocole']) ? $this->bdd->proteger($this->parametres['protocole']) : null;
                $requete = 'SELECT * FROM del_image_vote '.
                        "WHERE ce_image = $idImgP ".
                        ($idProtocoleP != null ? "AND ce_protocole = $idProtocoleP " : '').
                        ' -- '.__FILE__.' : '.__LINE__;
                $resultats = $this->bdd->recupererTous($requete);
                return $this->formaterVotes($resultats);
        }

        private function compterVotes() {
                $requete = 'SELECT FOUND_ROWS() AS nbre -- '.__FILE__.' : '.__LINE__;
                $resultats = $this->bdd->recuperer($requete);
                return (int) $resultats['nbre'];
        }

        private function formaterVotes($votes) {
                $retour = array();
                foreach ($votes as $vote) {
                        foreach ($vote as $champ => $valeur) {
                                $attribut = $this->mapping[$champ];
                                $retour[$vote['id_vote']][$attribut] = $valeur;
                        }
                }
                return $retour;
        }

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

                $this->verifierParametresAjoutModif();
                $idVote = $this->ajouterVote();
                if ($idVote) {
                        self::updateStats($this->bdd, $this->ressources[0], $this->parametres['protocole']);

                        $resultat = new ResultatService();
                        $resultat->corps = array('id_vote' => $idVote);
                        return $resultat;
                }
                return false;
        }

        private function ajouterVote() {
                $idImgP = $this->bdd->proteger($this->ressources[0]);
                $idProtocoleP = $this->bdd->proteger($this->parametres['protocole']);
                $idUtilisateurP = $this->bdd->proteger($this->parametres['utilisateur']);
                $valeurP = $this->bdd->proteger($this->parametres['valeur']);
                
                $this->verifierAutorisationProtocoleIdentifie($this->parametres['protocole'], $this->parametres['utilisateur']);
                
                $requete = 'INSERT INTO del_image_vote (ce_image, ce_protocole, ce_utilisateur, valeur, date) '.
                        "VALUES ( $idImgP, $idProtocoleP, $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 : ".
                                "idImg -> $idImgP, id_protocole -> $idProtocoleP 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();
                return $idVote;
        }

        public function verifierParametresAjoutModif() {
                $erreurs = array();
                if (!is_numeric($this->ressources[0])) {
                        $erreurs[] = "Le paramètre indiquant l'identifiant de l'image doit être numérique.";
                }

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

                if (!isset($this->parametres['protocole'])) {
                        $erreurs[] = "Paramètre 'id_protocole' manquant.";
                } else {
                        if (!is_numeric($this->parametres['protocole'])) {
                                $erreurs[] = "Le paramètre 'protocole' doit être numérique.";
                        }
                }

                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.";
                        }
                }

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

        public function modifier($ressources, $parametres) {
                $this->ressources = $ressources;
                $this->parametres = $parametres;
                $this->verifierParametresAjoutModif();
                $resultat = $this->modifierVote();
                if ($resultat > 0) {
                        self::updateStats($this->bdd, $this->ressources[0],$this->parametres['protocole']);
                        return 'ok';
                }
        }

        public function modifierVote() {
                $valeurP = $this->bdd->proteger($this->parametres['valeur']);
                $idImgP = $this->bdd->proteger($this->ressources[0]);
                $idProtocoleP = $this->bdd->proteger($this->parametres['protocole']);
                $idUtilisateurP = $this->bdd->proteger($this->parametres['utilisateur']);

                $this->verifierAutorisationProtocoleIdentifie($this->parametres['protocole'], $this->parametres['utilisateur']);
                
                $requete = 'UPDATE del_image_vote '.
                        "SET valeur = $valeurP, date = NOW() ".
                        "WHERE ce_image = $idImgP AND ce_protocole = $idProtocoleP AND ce_utilisateur = $idUtilisateurP ".
                        ' -- '.__FILE__.' : '.__LINE__;

                $resultat = $this->bdd->executer($requete);
                if ($resultat === false) {
                        $msg = "Un erreur est survenu 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 : ".
                                "idImg -> $idImgP, id_protocole -> $idProtocoleP et id_utilisateur -> $idUtilisateurP.";
                        throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
                }
                return $resultat;
        }

        public function supprimer($ressources) {
                $this->ressources = $ressources;
                $this->verifierParametresSuppression();
                $idVoteP = $this->bdd->proteger($this->ressources[2]);

                $voteInfos = $this->recupererInfosVote($idVoteP);
                $this->verifierAutorisationSuppression($voteInfos);

                $resultat = $this->supprimerVote($idVoteP);
                if ($resultat > 0) {
                        $idImg = $this->ressources[0];
                        self::updateStats($this->bdd, $idImg, $voteInfos['id_protocole']);
                        return 'ok';
                }
        }

        public function verifierParametresSuppression() {
                $erreurs = array();
                if (!isset($this->ressources[0])) {
                        $erreurs[] = "Le paramètre indiquant l'identifiant de l'image est obligatoire.";
                } else {
                        if (!is_numeric($this->ressources[0])) {
                                $erreurs[] = "Le paramètre indiquant l'identifiant de l'image doit être numérique.";
                        }
                }
                if (!isset($this->ressources[2])) {
                        $erreurs[] = "Le paramètre indiquant l'identifiant du vote est obligatoire.";
                } else {
                        if (!is_numeric($this->ressources[2])) {
                                $erreurs[] = "Le paramètre indiquant l'identifiant du vote doit être numérique.";
                        }
                }

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

        private function recupererInfosVote($idVoteP) {
                $requete = 'SELECT id_vote, ce_protocole AS id_protocole, ce_utilisateur AS id_utilisateur '.
                        'FROM del_image_vote '.
                        "WHERE id_vote = $idVoteP ".
                        ' -- '.__FILE__.' : '.__LINE__;

                $infos = $this->bdd->recuperer($requete);
                if ($infos === false) {
                        $msg = "Aucun vote ne correspond à l'identifiant $idVoteP.";
                        throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
                }
                return $infos;
        }
        
        private function verifierAutorisationProtocoleIdentifie($idProtocole, $idUtilisateur) {
        
                $idProtocoleP = $this->bdd->proteger($idProtocole);
        
                $gestion_utilisateur = $this->conteneur->getUtilisateur();
                $utilisateur = $gestion_utilisateur->getUtilisateur();
                
                $utilisateurAComparer = $gestion_utilisateur->getIdAnonymeTemporaire();
                
                // Si l'utilisateur n'est pas identifié on vérifie que le protocole n'impose
                // pas d'être connecté pour voter, et le cas échéant, on refuse le vote
                if(!$utilisateur['connecte']) {
                        $requete_proto_identifie = 'SELECT identifie FROM del_image_protocole '.
                                        'WHERE id_protocole = '.$idProtocoleP;
                        $proto_identifie = $this->bdd->recuperer($requete_proto_identifie);
        
                        if($proto_identifie['identifie'] == 1) {
                                $msg = "Ce protocole nécéssite d'être identifié pour voter.";
                                throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
                        }                       
                } else {
                        $utilisateurAComparer = $utilisateur['id_utilisateur'];
                }
                
                // Sinon on vérifie tout de même que la personne identifiée est bien celle
                // associée aux votes dans les paramètres
                if($utilisateurAComparer != $idUtilisateur) {
                        $msg = "L'utilisateur identifié et l'utilisateur du vote ne correspondent pas.";
                        throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
                }
        }

        private function verifierAutorisationSuppression($voteInfos) {
                $gestion_utilisateur = $this->conteneur->getUtilisateur();
                $utilisateur = $gestion_utilisateur->getUtilisateur();
                // @SECURE vérifier que l'utilisateur qui modifie son vote est bien celui qui est connecté
                if (isset($utilisateur['id_utilisateur']) &&
                                $utilisateur['id_utilisateur'] != $voteInfos['id_utilisateur'] &&
                                $gestion_utilisateur->getIdAnonymeTemporaire() != $voteInfos['id_utilisateur']) {
                        $message = "Vous n'êtes pas autorisé à supprimer le vote : {$voteInfos['id_vote']}";
                        throw new Exception($message, RestServeur::HTTP_CODE_ACCES_NON_AUTORISE);
                }
        }

        private function supprimerVote($idVoteP) {
                $requete = "DELETE FROM del_image_vote WHERE id_vote = $idVoteP ".' -- '.__FILE__.' : '.__LINE__;
                $resultat = $this->bdd->executer($requete);
                if ($resultat === false) {
                        $msg = "Impossible de supprimer le vote $idVoteP.";
                        throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
                }
                return $resultat;
        }

        // intermédiaire pour la méthode contenue dans "Commun"
        static function updateStats($db, $id_image, $id_protocole) {
                return TelaBotanica\Del\Commun\Stats::updateStats($db, $id_image, $id_protocole);
        }
}