Rev 768 | Blame | Last modification | View Log | RSS feed
<?php// declare(encoding='UTF-8');/*** Service de recherche et modification de l'arbre des mots clés associés à un id.* 1: Le service recoit un mot clé à ajouter à l'arbre* 2: Le service recherche l'arbre ou sous arbre correspondant au critères demandé* 3: Le service renvoie l'arbre au format json** Encodage en entrée : utf8* Encodage en sortie : utf8** Cas d'utilisation :** @author Aurélien 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>* @version $Id$* @copyright © 2011, Tela-Botanica*/class InventoryKeyWordList extends DBAccessor {public $config ;protected $suffix = '';public function InventoryKeyWordList($config) {$this->config = $config;}public function getElement($uid) {// Controle detournement utilisateursession_start();$this->suffix = '_'.$uid[0];$id_utilisateur = $uid[1] ;$this->controleUtilisateur($uid[1]);$requete = 'SELECT cmc_mot_cle, cmc_id_mot_cle_utilisateur, cmc_id_parent '.'FROM cel_mots_cles'.$this->suffix.' '.'WHERE cmc_id_proprietaire = "'.$DB->escapeSimple($id_utilisateur).'" '.'ORDER BY cmc_niveau ';$resultat = $this->recupererResultat($requete);if ($resultat) {$mots_cles = array();while($mot_cle = $resultat->fetchrow(DB_FETCHMODE_ASSOC)) {$mots_cles[] = $mot_cle;}$infos = json_encode($mots_cles);header('content-type: text/json');print $infos;exit();}}public function updateElement($uid, $pairs) {session_start();$this->suffix = '_'.$uid[0];$id_utilisateur = $uid[1];$this->controleUtilisateur($uid[1]);$id_mot_cle = $pairs['id'];$action = $pairs['action'];if ($action == 'modification') {$nouveau_nom = $pairs['motcle'];$nouvel_id_general = md5(strtolower($nouveau_nom));$requete = 'UPDATE cel_mots_cles'.$this->suffix.' '.'SET cmc_mot_cle = "'.$DB->escapeSimple($nouveau_nom).'" , '.' cmc_id_mot_cle_general = "'.$DB->escapeSimple($nouvel_id_general).'" '.'WHERE cmc_id_mot_cle_utilisateur = "'.$DB->escapeSimple($id_mot_cle).'" '.' AND cmc_id_proprietaire = "'.$DB->escapeSimple($id_utilisateur).'"' ;$reussite = $this->executerRequete($requete);if ($reussite) {echo 'OK';}} else if ($action == 'deplacement') {$this->commencerTransaction();$transaction_reussie_1 = true;$id_pere = $pairs['parent'];$bornes = $this->calculerBornesEtNiveau($id_mot_cle, $id_utilisateur);$bg = $bornes['cmc_bg'];$bd = $bornes['cmc_bd'];$niveau = $bornes['cmc_niveau'];// on inverse l'intervalle de l'élément déplacé et du sous arbre$transaction_reussie_2 = $this->exclureIntervalle($bg, $bd, $id_utilisateur) ? true : false;$bg_negative = $bg - $bd - 1;$bd_negative = $bd - $bd - 1;// on recalcule les intervalles de l'arbre privé de ce sous arbre$transaction_reussie_3 = $this->decalerBornesMoinsIntervalle($bg, $bd, $id_utilisateur) ? true : false;$bornes_pere = $this->calculerBornesEtNiveau($id_pere, $id_utilisateur);$bg_pere = $bornes_pere['cmc_bg'];$bd_pere = $bornes_pere['cmc_bd'];$niveau_pere = $bornes_pere['cmc_niveau'];$decalage = $bd - $bg + 1;// on decale les bornes droite du pere pour préparer l'insertion$transaction_reussie_4 = $this->decalerBornesPlusIntervalle($bd_pere, $decalage, $id_utilisateur) ? true : false;$nouvelle_bd = $bd_pere + $decalage;$modif_niveau = $niveau_pere - $niveau + 1;$transaction_reussie_5 = $this->inclureIntervalle($bg_negative, $bd_negative, $nouvelle_bd, $modif_niveau, $id_utilisateur) ? true : false;$transaction_reussie_6 = $this->changerPere($id_mot_cle, $id_pere, $id_utilisateur) ? true : false;if ($transaction_reussie_1 && $transaction_reussie_2 && $transaction_reussie_3 && $transaction_reussie_4 && $transaction_reussie_5 && $transaction_reussie_6) {$this->completerTransaction();} else {$this->annulerTransaction();}}}public function createElement($pairs) {// Controle detournement utilisateursession_start();$this->controleUtilisateur($pairs['identifiant']);$this->suffix = '_'.$pairs['mode'];$id_utilisateur = $pairs['identifiant'];$mot_cle = $pairs['motcle'];// TODO supprimer accents et majuscules$id_mot_cle_general = md5(mb_strtolower($mot_cle));$id_mot_cle = $pairs['id'];$id_parent = $pairs['parent'];$this->ajouterMotCleRacine($id_utilisateur);$this->commencerTransaction();$bornes = $this->calculerBornesEtNiveau($id_parent, $id_utilisateur);$borne_pere = $bornes['cmc_bd'];$niveau = $bornes['cmc_niveau'] + 1;$bg = $bornes['cmc_bd'];$bd = $bg + 1;$transaction_reussie_1 = $this->decalerBornesPlusDeux($borne_pere,$id_utilisateur) ? true : false;$requete = 'INSERT INTO cel_mots_cles'.$this->suffix.' '.'VALUES ( '.'"'.$DB->escapeSimple($mot_cle).'", '.'"'.$DB->escapeSimple($bg).'", '.'"'.$DB->escapeSimple($bd).'", '.'"'.$DB->escapeSimple($id_mot_cle_general).'", '.'"'.$DB->escapeSimple($id_mot_cle).'", '.'"'.$DB->escapeSimple($id_utilisateur).'", '.'"'.$DB->escapeSimple($id_parent).'", '.'"'.$DB->escapeSimple($niveau).'" )' ;$transaction_reussie_2 = $this->executerRequete($requete);if ($transaction_reussie_1 && $transaction_reussie_2) {$this->completerTransaction();echo 'OK';} else {$this->annulerTransaction();}}public function deleteElement($uid) {session_start();$this->suffix = '_'.$uid[0];$id_utilisateur = $uid[1];$id_mot_cle = $uid[2];$this->controleUtilisateur($id_utilisateur);$this->commencerTransaction();$bornes = $this->calculerBornesEtNiveau($id_mot_cle, $id_utilisateur);$bg = $bornes['cmc_bg'];$bd = $bornes['cmc_bd'];$requete = 'DELETE FROM cel_mots_cles'.$this->suffix.' '.'WHERE cmc_bg >= "'.$DB->escapeSimple($bg).'" '.' AND cmc_bd <= "'.$DB->escapeSimple($bd).'" '.' AND cmc_id_proprietaire = "'.$DB->escapeSimple($id_utilisateur).'" ';$transaction_reussie_1 = $this->verifierLignesAffectees($requete);$transaction_reussie_2 = $this->decalerBornesMoinsIntervalle($bg, $bd, $id_utilisateur) ? true : false;if ($transaction_reussie_1 && $transaction_reussie_2) {$this->completerTransaction();} else {$this->annulerTransaction();}}private function ajouterMotCleRacine($id) {$requete = 'SELECT COUNT(*) '.'FROM cel_mots_cles'.$this->suffix.' '.'WHERE cmc_id_proprietaire = "'.$DB->escapeSimple($id).'" ';$resultat = $this->recupererResultat($requete);if ($resultat) {$valeurs = $resultat->fetchrow(DB_FETCHMODE_ORDERED);switch ($this->suffix) {case '_obs' :$nom_racine = 'Projets';$id_racine = 'racine_obs';break;case '_images' :$nom_racine = 'Mots clés';$id_racine = 'racine';break;default:$nom_racine = $this->suffix;$id_racine = $this->suffix;}if ($valeurs[0] == 0) {$requete = 'INSERT INTO cel_mots_cles'.$this->suffix.' '.'VALUES ("'.$nom_racine.'", 1, 2, "'.$id_racine.'", "'.$id_racine.'", "'.$DB->escapeSimple($id).'", "", 0) ';$this->executerRequete($requete);}}}/*** Désactive l'auto-commit puis débute la transaction*/private function commencerTransaction() {// Désactive l'autocommit le temps de la manipulation de l'arbre$requete = 'SET AUTOCOMMIT = 0 ';$reussite_autocommit = $this->executerRequete($requete);// Débute une nouvelle transaction$requete = 'BEGIN ';$reussite_begin = $this->executerRequete($requete);}/*** Termine la transaction puis réactive l'auto-commit*/private function completerTransaction() {// Complète la transaction$requete = 'COMMIT ';$reussite_commit = $this->executerRequete($requete);// Réactive l'autocommit le temps de la manipulation de l'arbre$requete = 'SET AUTOCOMMIT = 1 ';$reussite_autocommit = $this->executerRequete($requete);echo 'OK';}/*** Annule la transaction et réactive l'auto-commit*/private function annulerTransaction() {// Annule la transaction$requete = 'ROLLBACK ';$reussite_rollback = $this->executerRequete($requete);// Réactive l'autocommit le temps de la manipulation de l'arbre$requete = 'SET AUTOCOMMIT = 1 ';$reussite_autocommit = $this->executerRequete($requete);echo 'ERROR';}/*** Renvoie les bornes d'un noeud de l'arbre des mots clés*/private function calculerBornesEtNiveau($id_mot_cle,$id_utilisateur) {$requete = 'SELECT cmc_bd, cmc_bg, cmc_niveau '.'FROM cel_mots_cles'.$this->suffix.' '.'WHERE cmc_id_mot_cle_utilisateur = "'.$DB->escapeSimple($id_mot_cle).'" '.' AND cmc_id_proprietaire = "'.$DB->escapeSimple($id_utilisateur).'" ';$resultat = $this->recupererResultat($requete);$valeurs = $resultat->fetchrow(DB_FETCHMODE_ASSOC);return $valeurs;}/*** Décale les bornes de deux pour insérer un nouvel élément*/private function decalerBornesPlusDeux($valeur, $id_utilisateur) {// Décalage borne droite$requete = 'UPDATE cel_mots_cles'.$this->suffix.' '.'SET cmc_bd = cmc_bd + 2 WHERE cmc_bd >= "'.$DB->escapeSimple($valeur).'" '.' AND cmc_id_proprietaire = "'.$DB->escapeSimple($id_utilisateur).'" ';$reussi_1 = $this->executerRequete($requete);// Décalage borne gauche$requete = 'UPDATE cel_mots_cles'.$this->suffix.' '.'SET cmc_bg = cmc_bg + 2 '.'WHERE cmc_bg >= "'.$DB->escapeSimple($valeur).'" '.' AND cmc_id_proprietaire = "'.$DB->escapeSimple($id_utilisateur).'" ';$reussi_2 = $this->executerRequete($requete);return $reussi_1 && $reussi_2;}/*** Décale les bornes d'un intervalle negatif donne (pour la suppression d'un sous arbre).*/private function decalerBornesMoinsIntervalle($bg, $bd, $id_utilisateur) {$decalage = $bd - $bg + 1;// Décalage borne droite$requete = 'UPDATE cel_mots_cles'.$this->suffix.' '.'SET cmc_bd = cmc_bd - "'.$DB->escapeSimple($decalage).'" '.'WHERE cmc_bd >= "'.$DB->escapeSimple($bg).'" '.' AND cmc_id_proprietaire = "'.$DB->escapeSimple($id_utilisateur).'" ';$reussi_1 = $this->executerRequete($requete);// Décalage borne gauche$requete = 'UPDATE cel_mots_cles'.$this->suffix.' '.'SET cmc_bg = cmc_bg - "'.$DB->escapeSimple($decalage).'" '.'WHERE cmc_bg > "'.$DB->escapeSimple($bg).'" '.' AND cmc_id_proprietaire = "'.$DB->escapeSimple($id_utilisateur).'" ';$reussi_2 = $this->executerRequete($requete);return $reussi_1 && $reussi_2;}/*** Décale à droite des bornes donées d'un intervalle positif donne (pour l'ajout d'un sous arbre).*/private function decalerBornesPlusIntervalle($valeur_bornes, $largeur, $id_utilisateur) {$decalage = $largeur;// decalage borne droite$requete = 'UPDATE cel_mots_cles'.$this->suffix.' '.'SET cmc_bd = cmc_bd + "'.$DB->escapeSimple($decalage).'" '.'WHERE cmc_bd >= "'.$DB->escapeSimple($valeur_bornes).'" '.' AND cmc_id_proprietaire = "'.$DB->escapeSimple($id_utilisateur).'" ';$reussi_1 = $this->executerRequete($requete);// decalage borne gauche$requete = 'UPDATE cel_mots_cles'.$this->suffix.' '.'SET cmc_bg = cmc_bg + "'.$DB->escapeSimple($decalage).'" '.'WHERE cmc_bg >= "'.$DB->escapeSimple($valeur_bornes).'" '.' AND cmc_id_proprietaire = "'.$DB->escapeSimple($id_utilisateur).'" ';$reussi_2 = $this->executerRequete($requete);return $reussi_1 && $reussi_2;}/*** Inverse les bornes d'un intervalle pour l'exclure des modifications sur l'arbre sans changer la hiérarchie.*/private function exclureIntervalle($bg, $bd, $id_utilisateur) {$requete = 'UPDATE cel_mots_cles'.$this->suffix.' '.'SET cmc_bd = cmc_bd - "'.$DB->escapeSimple($bd).'" - 1 , '.' cmc_bg = cmc_bg - "'.$DB->escapeSimple($bd).'" - 1 '.'WHERE cmc_bd <= "'.$DB->escapeSimple($bd).'" '.' AND cmc_bg >= "'.$DB->escapeSimple($bg).'" '.' AND cmc_id_proprietaire = "'.$DB->escapeSimple($id_utilisateur).'" ';return $this->executerRequete($requete);}/*** Recale les bornes dun intervalle pour l'inclure dans l'arbre à la bonne place.* Décalage borne droite*/private function inclureIntervalle($bg, $bd, $decalage,$modif_niveau, $id_utilisateur) {$requete = 'UPDATE cel_mots_cles'.$this->suffix.' '.'SET cmc_bg = cmc_bg + "'.$DB->escapeSimple($decalage).'" , '.' cmc_bd = cmc_bd + "'.$DB->escapeSimple($decalage).'", '.' cmc_niveau = cmc_niveau + "'.$modif_niveau.'" '.'WHERE cmc_bg >= "'.$DB->escapeSimple($bg).'" '.' AND cmc_bd <= "'.$DB->escapeSimple($bd).'" '.' AND cmc_id_proprietaire = "'.$DB->escapeSimple($id_utilisateur).'" ';return $this->executerRequete($requete);}private function changerPere($id_mot_cle, $id_pere, $id_utilisateur) {$requete = 'UPDATE cel_mots_cles'.$this->suffix.' '.'SET cmc_id_parent = "'.$DB->escapeSimple($id_pere).'" '.'WHERE cmc_id_mot_cle_utilisateur = "'.$DB->escapeSimple($id_mot_cle).'" '.' AND cmc_id_proprietaire = "'.$DB->escapeSimple($id_utilisateur).'" ';return $this->executerRequete($requete);}private function executerRequete($requete) {$DB = $this->connectDB($this->config, 'cel_db');$resultat =& $DB->query($requete);$execution = true;if (PEAR::isError($resultat)) {die($res->getMessage());$execution = false;}return $execution;}private function recupererResultat($requete) {$DB = $this->connectDB($this->config, 'cel_db');$resultat =& $DB->query($requete);if (PEAR::isError($resultat)) {die($res->getMessage());$resultat = false;}return $resultat;}private function verifierLignesAffectees($requete) {$DB = $this->connectDB($this->config, 'cel_db');$resultat =& $DB->query($requete);$execution = true;if (PEAR::isError($resultat)) {die($res->getMessage());$execution = false;} else {if ($DB->affectedRows() <= 0) {$execution = false;}}return $execution;}}?>