New file |
0,0 → 1,434 |
<?php |
// declare(encoding='UTF-8'); |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* 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 Cel { |
|
protected $suffixe = ''; |
protected $suffixe_table = null; |
protected $suffixe_champ = null; |
|
private function setChampsEtTablePourSuffixe($suffixe) { |
$this->suffixe = $suffixe; |
switch($suffixe) { |
case 'obs': |
$this->suffixe_table = '_obs'; |
$this->suffixe_champ = '_obs'; |
break; |
case 'images': |
$this->suffixe_table = '_images'; |
$this->suffixe_champ = '_image'; |
break; |
} |
} |
|
public function getElement($uid) { |
// Controle detournement utilisateur |
$id_utilisateur = $uid[1] ; |
$this->controleUtilisateur($uid[1]); |
|
$this->setChampsEtTablePourSuffixe($uid[0]); |
|
$requete = 'SELECT mot_cle, id_mot_cle'.$this->suffixe_champ.', ce_mot_cle'.$this->suffixe_champ.'_parent '. |
'FROM cel_mots_cles'.$this->suffixe_table.' '. |
'WHERE id_utilisateur = '.$this->proteger($id_utilisateur).' '. |
'ORDER BY niveau '; |
|
$resultats_mots_cles = $this->requeter($requete); |
|
if (is_array($resultats_mots_cles)) { |
$mots_cles = array(); |
foreach($resultats_mots_cles as $mot_cle) { |
$mots_cles[] = $mot_cle; |
} |
|
$this->envoyerJson($mots_cles); |
return true; |
} |
} |
|
public function updateElement($uid, $pairs) { |
$id_utilisateur = $uid[1]; |
$this->controleUtilisateur($uid[1]); |
|
$this->setChampsEtTablePourSuffixe($uid[0]); |
|
$id_mot_cle = $pairs['id']; |
$action = $pairs['action']; |
|
if ($action == 'modification') { |
$nouveau_nom = $pairs['motcle']; |
$nouvel_id_general = md5(mb_strtolower($nouveau_nom)); |
|
$requete = 'UPDATE cel_mots_cles'.$this->suffixe_table.' '. |
'SET mot_cle = '.$this->proteger($nouveau_nom).' , '. |
' md5 = '.$this->proteger($nouvel_id_general).' '. |
'WHERE id_mot_cle'.$this->suffixe_champ.' = '.$this->proteger($id_mot_cle).' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur) ; |
$reussite = $this->executer($requete); |
if ($reussite !== false) { |
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['bg']; |
$bd = $bornes['bd']; |
$niveau = $bornes['niveau']; |
|
// on inverse l'intervalle de l'élément déplacé et du sous arbre |
$transaction_reussie_2 = $this->exclureIntervalle($bg, $bd, $id_utilisateur); |
|
$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); |
|
$bornes_pere = $this->calculerBornesEtNiveau($id_pere, $id_utilisateur); |
$bg_pere = $bornes_pere['bg']; |
$bd_pere = $bornes_pere['bd']; |
|
$niveau_pere = $bornes_pere['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); |
|
$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); |
|
$transaction_reussie_6 = $this->changerPere($id_mot_cle, $id_pere, $id_utilisateur); |
|
if ($transaction_reussie_1 !== false && $transaction_reussie_2 !== false && |
$transaction_reussie_3 !== false && $transaction_reussie_4 !== false && |
$transaction_reussie_5 !== false && $transaction_reussie_6 !== false) { |
$this->completerTransaction(); |
} else { |
$this->annulerTransaction(); |
} |
|
} |
} |
|
public function createElement($pairs) { |
// Controle detournement utilisateur |
$this->controleUtilisateur($pairs['identifiant']); |
|
$this->setChampsEtTablePourSuffixe($pairs['mode']); |
$id_utilisateur = $pairs['identifiant']; |
$mot_cle = $pairs['motcle']; |
|
// TODO supprimer accents |
$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['bd']; |
$niveau = $bornes['niveau'] + 1; |
$bg = $bornes['bd']; |
$bd = $bg + 1; |
|
$transaction_reussie_1 = $this->decalerBornesPlusDeux($borne_pere,$id_utilisateur) ? true : false; |
|
$requete = 'INSERT INTO cel_mots_cles'.$this->suffixe_table.' '. |
'VALUES ( '. |
$this->proteger($id_mot_cle).', '. |
$this->proteger($id_utilisateur).', '. |
$this->proteger($mot_cle).', '. |
$this->proteger($id_mot_cle_general).', '. |
$this->proteger($bg).', '. |
$this->proteger($bd).', '. |
$this->proteger($niveau).', '. |
$this->proteger($id_parent).') ' ; |
|
$transaction_reussie_2 = $this->executer($requete); |
|
if ($transaction_reussie_1 && $transaction_reussie_2) { |
$this->completerTransaction(); |
} else { |
$this->annulerTransaction(); |
} |
} |
|
public function deleteElement($uid) { |
|
$this->setChampsEtTablePourSuffixe($uid[0]); |
$id_utilisateur = $uid[1]; |
$id_mot_cle = $uid[2]; |
|
$tableau_ids_mots_cles = array(); |
$tableau_ids_mots_cles[] = $id_mot_cle; |
|
$this->controleUtilisateur($id_utilisateur); |
$this->commencerTransaction(); |
|
$bornes = $this->calculerBornesEtNiveau($id_mot_cle, $id_utilisateur); |
if($bornes) { |
$bg = $bornes['bg']; |
$bd = $bornes['bd']; |
|
$requete_mots_cles_fils = 'SELECT id_mot_cle'.$this->suffixe_champ.' as id FROM cel_mots_cles'.$this->suffixe_table.' '. |
'WHERE bg >= '.$this->proteger($bg).' '. |
' AND bd <= '.$this->proteger($bd).' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
|
$mots_cles_fils = $this->requeter($requete_mots_cles_fils); |
foreach ($mots_cles_fils as $fils) { |
$tableau_ids_mots_cles[] = $fils['id']; |
} |
|
$requete = 'DELETE FROM cel_mots_cles'.$this->suffixe_table.' '. |
'WHERE bg >= '.$this->proteger($bg).' '. |
' AND bd <= '.$this->proteger($bd).' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
|
$transaction_reussie_1 = $this->executer($requete); |
$transaction_reussie_2 = $this->decalerBornesMoinsIntervalle($bg, $bd, $id_utilisateur) ? true : false; |
|
if ($transaction_reussie_1 !== false && $transaction_reussie_2 !== false) { |
$this->completerTransaction(); |
} else { |
$this->annulerTransaction(); |
} |
} |
// Suppression des liaisons associées à ce mot clé |
$gestion_liaisons = new LiaisonMotsCles($this->config, $this->suffixe); |
$gestion_liaisons->supprimerToutesLiaisonsPourIdMotCle($id_utilisateur, $tableau_ids_mots_cles); |
} |
|
private function ajouterMotCleRacine($id) { |
$requete = 'SELECT COUNT(*) as nb_mc '. |
'FROM cel_mots_cles'.$this->suffixe_table.' '. |
'WHERE id_utilisateur = '.$this->proteger($id).' '; |
$resultat = $this->requeter($requete); |
|
if (is_array($resultat) && count($resultat) > 0) { |
$valeurs = $resultat[0]['nb_mc']; |
|
switch ($this->suffixe) { |
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->suffixe; |
$id_racine = $this->suffixe; |
} |
|
$md5_racine = $this->proteger(md5($nom_racine)); |
$id_racine = $this->proteger($id_racine); |
$nom_racine = $this->proteger($nom_racine); |
$id_utilisateur = $this->proteger($id); |
|
if ($valeurs == 0) { |
$requete = "INSERT INTO cel_mots_cles{$this->suffixe_table} ". |
"VALUES ($id_racine, $id_utilisateur, $nom_racine, $md5_racine, ". |
"1, 2, 0, '') "; |
|
$this->executer($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->executer($requete); |
|
// Débute une nouvelle transaction |
$requete = 'BEGIN '; |
$reussite_begin = $this->executer($requete); |
} |
|
/** |
* Termine la transaction puis réactive l'auto-commit |
*/ |
private function completerTransaction() { |
// Complète la transaction |
$requete = 'COMMIT '; |
$reussite_commit = $this->executer($requete); |
|
// Réactive l'autocommit le temps de la manipulation de l'arbre |
$requete = 'SET AUTOCOMMIT = 1 '; |
$reussite_autocommit = $this->executer($requete); |
|
echo 'OK'; |
} |
|
/** |
* Annule la transaction et réactive l'auto-commit |
*/ |
private function annulerTransaction() { |
// Annule la transaction |
$requete = 'ROLLBACK '; |
$reussite_rollback = $this->executer($requete); |
|
// Réactive l'autocommit le temps de la manipulation de l'arbre |
$requete = 'SET AUTOCOMMIT = 1 '; |
$reussite_autocommit = $this->executer($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 bd, bg, niveau '. |
'FROM cel_mots_cles'.$this->suffixe_table.' '. |
'WHERE id_mot_cle'.$this->suffixe_champ.' = '.$this->proteger($id_mot_cle).' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
|
$resultat = $this->requeter($requete); |
|
$valeurs = null; |
if(is_array($resultat) && count($resultat) > 0) { |
$valeurs = $resultat[0]; |
} |
|
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->suffixe_table.' '. |
'SET bd = bd + 2 WHERE bd >= '.$valeur.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
$reussi_1 = $this->executer($requete); |
|
// Décalage borne gauche |
$requete = 'UPDATE cel_mots_cles'.$this->suffixe_table.' '. |
'SET bg = bg + 2 '. |
'WHERE bg >= '.$valeur.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
$reussi_2 = $this->executer($requete); |
|
return $reussi_1 !== false && $reussi_2 !== false; |
} |
|
/** |
* 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->suffixe_table.' '. |
'SET bd = bd - '.$decalage.' '. |
'WHERE bd >= '.$bg.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
$reussi_1 = $this->executer($requete); |
|
// Décalage borne gauche |
$requete = 'UPDATE cel_mots_cles'.$this->suffixe_table.' '. |
'SET bg = bg - '.$decalage.' '. |
'WHERE bg > '.$bg.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
$reussi_2 = $this->executer($requete); |
|
return $reussi_1 !== false && $reussi_2 !== false; |
} |
|
/** |
* 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->suffixe_table.' '. |
'SET bd = bd + '.$decalage.' '. |
'WHERE bd >= '.$valeur_bornes.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
$reussi_1 = $this->executer($requete); |
|
// decalage borne gauche |
$requete = 'UPDATE cel_mots_cles'.$this->suffixe_table.' '. |
'SET bg = bg + '.$decalage.' '. |
'WHERE bg >= '.$valeur_bornes.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
$reussi_2 = $this->executer($requete); |
|
return $reussi_1 !== false && $reussi_2 !== false; |
} |
|
/** |
* 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->suffixe_table.' '. |
'SET bd = bd - '.$bd.' - 1 , '. |
' bg = bg - '.$bd.' - 1 '. |
'WHERE bd <= '.$bd.' '. |
' AND bg >= '.$bg.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
|
return $this->executer($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->suffixe_table.' '. |
'SET bg = bg + '.$decalage.' , '. |
' bd = bd + '.$decalage.', '. |
' niveau = niveau + '.$modif_niveau.' '. |
' WHERE bg >= '.$bg.' '. |
' AND bd <= '.$bd.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
|
return $this->executer($requete); |
} |
|
private function changerPere($id_mot_cle, $id_pere, $id_utilisateur) { |
$requete = 'UPDATE cel_mots_cles'.$this->suffixe_table.' '. |
'SET ce_mot_cle'.$this->suffixe_champ.'_parent = '.$this->proteger($id_pere).' '. |
'WHERE id_mot_cle'.$this->suffixe_champ.' = '.$this->proteger($id_mot_cle).' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
|
return $this->executer($requete); |
} |
} |
?> |