Subversion Repositories eFlore/Applications.cel

Rev

Rev 1268 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
416 aurelien 1
<?php
821 jpm 2
// declare(encoding='UTF-8');
856 aurelien 3
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel //
416 aurelien 4
/**
821 jpm 5
 * Service de recherche et modification de l'arbre des mots clés associés à un id.
6
 * 1: Le service recoit un mot clé à ajouter à l'arbre
7
 * 2: Le service recherche l'arbre ou sous arbre correspondant au critères demandé
8
 * 3: Le service renvoie l'arbre au format json
9
 *
10
 * Encodage en entrée : utf8
11
 * Encodage en sortie : utf8
416 aurelien 12
 *
13
 * Cas d'utilisation :
14
 *
821 jpm 15
 * @author Aurélien PERONNET <aurelien@tela-botanica.org>
16
 * @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
17
 * @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
18
 * @version $Id$
19
 * @copyright © 2011, Tela-Botanica
416 aurelien 20
 */
856 aurelien 21
class InventoryKeyWordList extends Cel {
22
 
1298 aurelien 23
	protected $suffixe = '';
24
	protected $suffixe_table = null;
25
	protected $suffixe_champ = null;
26
 
27
	private function setChampsEtTablePourSuffixe($suffixe) {
28
		$this->suffixe = $suffixe;
29
		switch($suffixe) {
30
			case 'obs':
31
				$this->suffixe_table = '_obs';
32
				$this->suffixe_champ = '_obs';
33
			break;
34
			case 'images':
35
				$this->suffixe_table = '_images';
36
				$this->suffixe_champ = '_image';
37
			break;
38
		}
39
	}
416 aurelien 40
 
821 jpm 41
	public function getElement($uid) {
42
		// Controle detournement utilisateur
43
		$id_utilisateur = $uid[1] ;
44
		$this->controleUtilisateur($uid[1]);
45
 
1298 aurelien 46
		$this->setChampsEtTablePourSuffixe($uid[0]);
47
 
48
		$requete = 	'SELECT mot_cle, id_mot_cle'.$this->suffixe_champ.', ce_mot_cle'.$this->suffixe_champ.'_parent '.
49
					'FROM cel_mots_cles'.$this->suffixe_table.' '.
856 aurelien 50
					'WHERE ce_utilisateur = '.$this->proteger($id_utilisateur).' '.
51
					'ORDER BY niveau ';
821 jpm 52
 
856 aurelien 53
		$resultats_mots_cles = $this->requeter($requete);
54
 
55
		if (is_array($resultats_mots_cles)) {
821 jpm 56
			$mots_cles = array();
856 aurelien 57
			foreach($resultats_mots_cles as $mot_cle) {
821 jpm 58
				$mots_cles[] = $mot_cle;
416 aurelien 59
			}
1014 aurelien 60
 
61
			$this->envoyerJson($mots_cles);
62
			return true;
416 aurelien 63
		}
64
	}
65
 
821 jpm 66
	public function updateElement($uid, $pairs) {
67
		$id_utilisateur = $uid[1];
68
		$this->controleUtilisateur($uid[1]);
1298 aurelien 69
 
70
		$this->setChampsEtTablePourSuffixe($uid[0]);
416 aurelien 71
 
821 jpm 72
		$id_mot_cle = $pairs['id'];
73
		$action = $pairs['action'];
416 aurelien 74
 
821 jpm 75
		if ($action == 'modification') {
76
			$nouveau_nom = $pairs['motcle'];
1268 aurelien 77
			$nouvel_id_general = md5(mb_strtolower($nouveau_nom));
416 aurelien 78
 
1298 aurelien 79
			$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
856 aurelien 80
						'SET mot_cle = '.$this->proteger($nouveau_nom).' , '.
81
						'	md5 = '.$this->proteger($nouvel_id_general).' '.
1298 aurelien 82
						'WHERE id_mot_cle'.$this->suffixe_champ.' = '.$this->proteger($id_mot_cle).' '.
856 aurelien 83
						'	AND ce_utilisateur = '.$this->proteger($id_utilisateur) ;
84
			$reussite = $this->executer($requete);
1298 aurelien 85
			if ($reussite !== false) {
821 jpm 86
				echo 'OK';
87
			}
88
		} else if ($action == 'deplacement') {
856 aurelien 89
 
821 jpm 90
			$this->commencerTransaction();
856 aurelien 91
 
821 jpm 92
			$transaction_reussie_1 = true;
93
			$id_pere = $pairs['parent'];
94
			$bornes = $this->calculerBornesEtNiveau($id_mot_cle, $id_utilisateur);
856 aurelien 95
			$bg = $bornes['bg'];
96
			$bd = $bornes['bd'];
97
			$niveau = $bornes['niveau'];
416 aurelien 98
 
821 jpm 99
			// on inverse l'intervalle de l'élément déplacé et du sous arbre
856 aurelien 100
			$transaction_reussie_2 = $this->exclureIntervalle($bg, $bd, $id_utilisateur);
416 aurelien 101
 
821 jpm 102
			$bg_negative = $bg - $bd - 1;
103
			$bd_negative = $bd - $bd - 1;
416 aurelien 104
 
821 jpm 105
			// on recalcule les intervalles de l'arbre privé de ce sous arbre
856 aurelien 106
			$transaction_reussie_3 = $this->decalerBornesMoinsIntervalle($bg, $bd, $id_utilisateur);
416 aurelien 107
 
821 jpm 108
			$bornes_pere = $this->calculerBornesEtNiveau($id_pere, $id_utilisateur);
856 aurelien 109
			$bg_pere = $bornes_pere['bg'];
110
			$bd_pere = $bornes_pere['bd'];
416 aurelien 111
 
856 aurelien 112
			$niveau_pere = $bornes_pere['niveau'];
416 aurelien 113
 
821 jpm 114
			$decalage = $bd - $bg + 1;
416 aurelien 115
 
821 jpm 116
			// on decale les bornes droite du pere pour préparer l'insertion
856 aurelien 117
			$transaction_reussie_4 = $this->decalerBornesPlusIntervalle($bd_pere, $decalage, $id_utilisateur);
821 jpm 118
 
119
			$nouvelle_bd = $bd_pere + $decalage;
120
			$modif_niveau = $niveau_pere - $niveau + 1;
416 aurelien 121
 
856 aurelien 122
			$transaction_reussie_5 = $this->inclureIntervalle($bg_negative, $bd_negative, $nouvelle_bd, $modif_niveau, $id_utilisateur);
123
 
124
			$transaction_reussie_6 = $this->changerPere($id_mot_cle, $id_pere, $id_utilisateur);
416 aurelien 125
 
1298 aurelien 126
			if ($transaction_reussie_1 !== false && $transaction_reussie_2 !== false &&
127
				$transaction_reussie_3 !== false && $transaction_reussie_4 !== false &&
128
				$transaction_reussie_5 !== false && $transaction_reussie_6 !== false) {
821 jpm 129
				$this->completerTransaction();
130
			} else {
131
				$this->annulerTransaction();
132
			}
416 aurelien 133
 
821 jpm 134
		}
135
	}
416 aurelien 136
 
821 jpm 137
	public function createElement($pairs) {
138
		// Controle detournement utilisateur
1014 aurelien 139
		$this->controleUtilisateur($pairs['identifiant']);
416 aurelien 140
 
1298 aurelien 141
		$this->setChampsEtTablePourSuffixe($pairs['mode']);
1014 aurelien 142
		$id_utilisateur = $pairs['identifiant'];
821 jpm 143
		$mot_cle = $pairs['motcle'];
416 aurelien 144
 
856 aurelien 145
		// TODO supprimer accents
821 jpm 146
		$id_mot_cle_general = md5(mb_strtolower($mot_cle));
147
		$id_mot_cle = $pairs['id'];
148
		$id_parent = $pairs['parent'];
416 aurelien 149
 
821 jpm 150
		$this->ajouterMotCleRacine($id_utilisateur);
416 aurelien 151
 
821 jpm 152
		$this->commencerTransaction();
416 aurelien 153
 
821 jpm 154
		$bornes = $this->calculerBornesEtNiveau($id_parent, $id_utilisateur);
856 aurelien 155
		$borne_pere = $bornes['bd'];
156
		$niveau = $bornes['niveau'] + 1;
157
		$bg = $bornes['bd'];
821 jpm 158
		$bd = $bg + 1;
416 aurelien 159
 
821 jpm 160
		$transaction_reussie_1 = $this->decalerBornesPlusDeux($borne_pere,$id_utilisateur) ? true : false;
161
 
1298 aurelien 162
		$requete = 	'INSERT INTO  cel_mots_cles'.$this->suffixe_table.' '.
821 jpm 163
					'VALUES ( '.
856 aurelien 164
					$this->proteger($id_mot_cle).', '.
165
					$this->proteger($id_utilisateur).', '.
166
					$this->proteger($mot_cle).', '.
167
					$this->proteger($id_mot_cle_general).', '.
168
					$this->proteger($bg).', '.
169
					$this->proteger($bd).', '.
170
					$this->proteger($niveau).', '.
171
					$this->proteger($id_parent).') ' ;
172
 
173
		$transaction_reussie_2 = $this->executer($requete);
416 aurelien 174
 
821 jpm 175
		if ($transaction_reussie_1 && $transaction_reussie_2) {
176
			$this->completerTransaction();
177
		} else {
178
			$this->annulerTransaction();
416 aurelien 179
		}
180
	}
181
 
821 jpm 182
	public function deleteElement($uid) {
183
 
1298 aurelien 184
		$this->setChampsEtTablePourSuffixe($uid[0]);
821 jpm 185
		$id_utilisateur = $uid[1];
186
		$id_mot_cle = $uid[2];
416 aurelien 187
 
821 jpm 188
		$this->controleUtilisateur($id_utilisateur);
189
		$this->commencerTransaction();
416 aurelien 190
 
821 jpm 191
		$bornes  = $this->calculerBornesEtNiveau($id_mot_cle, $id_utilisateur);
856 aurelien 192
		$bg = $bornes['bg'];
193
		$bd = $bornes['bd'];
416 aurelien 194
 
1298 aurelien 195
		$requete = 	'DELETE FROM cel_mots_cles'.$this->suffixe_table.' '.
856 aurelien 196
					'WHERE bg >= '.$this->proteger($bg).' '.
197
					'	AND bd <= '.$this->proteger($bd).' '.
198
					'	AND ce_utilisateur = '.$this->proteger($id_utilisateur).' ';
199
 
200
		$transaction_reussie_1 = $this->executer($requete);
821 jpm 201
		$transaction_reussie_2 = $this->decalerBornesMoinsIntervalle($bg, $bd, $id_utilisateur) ? true : false;
416 aurelien 202
 
1298 aurelien 203
		if ($transaction_reussie_1 !== false && $transaction_reussie_2 !== false) {
821 jpm 204
			$this->completerTransaction();
205
		} else {
206
			$this->annulerTransaction();
416 aurelien 207
		}
208
	}
821 jpm 209
 
210
	private function ajouterMotCleRacine($id) {
856 aurelien 211
		$requete = 	'SELECT COUNT(*) as nb_mc '.
1298 aurelien 212
					'FROM cel_mots_cles'.$this->suffixe_table.' '.
856 aurelien 213
					'WHERE ce_utilisateur = '.$this->proteger($id).' ';
214
		$resultat = $this->requeter($requete);
416 aurelien 215
 
856 aurelien 216
		if (is_array($resultat) && count($resultat) > 0) {
217
			$valeurs = $resultat[0]['nb_mc'];
416 aurelien 218
 
1298 aurelien 219
			switch ($this->suffixe) {
220
				case 'obs' :
821 jpm 221
					$nom_racine = 'Projets';
222
					$id_racine = 'racine_obs';
223
					break;
1298 aurelien 224
				case 'images' :
821 jpm 225
					$nom_racine = 'Mots clés';
226
					$id_racine = 'racine';
227
					break;
228
				default:
1298 aurelien 229
					$nom_racine = $this->suffixe;
230
					$id_racine = $this->suffixe;
821 jpm 231
			}
416 aurelien 232
 
856 aurelien 233
			if ($valeurs == 0) {
1298 aurelien 234
				$requete = 	'INSERT INTO cel_mots_cles'.$this->suffixe_table.' '.
856 aurelien 235
							'VALUES ("'.$nom_racine.'", 1, 2, "'.$id_racine.'", "'.$id_racine.'", '.$this->proteger($id).', "", 0) ';
236
				$this->executer($requete);
821 jpm 237
			}
416 aurelien 238
		}
821 jpm 239
	}
416 aurelien 240
 
821 jpm 241
	/**
242
	 * Désactive l'auto-commit puis débute la transaction
243
	 */
244
	private function commencerTransaction() {
245
		// Désactive l'autocommit le temps de la manipulation de l'arbre
246
		$requete = 'SET AUTOCOMMIT = 0 ';
856 aurelien 247
		$reussite_autocommit = $this->executer($requete);
416 aurelien 248
 
821 jpm 249
		// Débute une nouvelle transaction
250
		$requete = 'BEGIN ';
856 aurelien 251
		$reussite_begin = $this->executer($requete);
416 aurelien 252
	}
253
 
821 jpm 254
	/**
255
	 * Termine la transaction puis réactive l'auto-commit
256
	 */
257
	private function completerTransaction() {
258
		// Complète la transaction
259
		$requete = 'COMMIT ';
856 aurelien 260
		$reussite_commit = $this->executer($requete);
416 aurelien 261
 
821 jpm 262
		// Réactive l'autocommit le temps de la manipulation de l'arbre
263
		$requete = 'SET AUTOCOMMIT = 1 ';
856 aurelien 264
		$reussite_autocommit = $this->executer($requete);
416 aurelien 265
 
821 jpm 266
		echo 'OK';
416 aurelien 267
	}
821 jpm 268
 
269
	/**
270
	 * Annule la transaction et réactive l'auto-commit
271
	 */
272
	private function annulerTransaction() {
273
		// Annule la transaction
274
		$requete = 'ROLLBACK ';
856 aurelien 275
		$reussite_rollback = $this->executer($requete);
416 aurelien 276
 
821 jpm 277
		// Réactive l'autocommit le temps de la manipulation de l'arbre
278
		$requete = 'SET AUTOCOMMIT = 1 ';
856 aurelien 279
		$reussite_autocommit = $this->executer($requete);
416 aurelien 280
 
821 jpm 281
		echo 'ERROR';
282
	}
416 aurelien 283
 
821 jpm 284
	/**
285
	 * Renvoie les bornes d'un noeud de l'arbre des mots clés
286
	 */
287
	private function calculerBornesEtNiveau($id_mot_cle,$id_utilisateur) {
856 aurelien 288
		$requete = 	'SELECT bd, bg, niveau '.
1298 aurelien 289
					'FROM cel_mots_cles'.$this->suffixe_table.' '.
290
					'WHERE id_mot_cle'.$this->suffixe_champ.' = '.$this->proteger($id_mot_cle).' '.
856 aurelien 291
					'	AND ce_utilisateur = '.$this->proteger($id_utilisateur).' ';
292
		$resultat = $this->requeter($requete);
293
 
294
		if(is_array($resultat) && count($resultat) > 0) {
295
			$valeurs = $resultat[0];
296
		}
297
 
821 jpm 298
		return $valeurs;
299
	}
416 aurelien 300
 
821 jpm 301
	/**
302
	 * Décale les bornes de deux pour insérer un nouvel élément
303
	 */
304
	private function decalerBornesPlusDeux($valeur, $id_utilisateur) {
305
		// Décalage borne droite
1298 aurelien 306
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
307
					'SET bd = bd + 2 WHERE bd >= '.$valeur.' '.
856 aurelien 308
					'	AND ce_utilisateur = '.$this->proteger($id_utilisateur).' ';
309
		$reussi_1 = $this->executer($requete);
821 jpm 310
 
311
		// Décalage borne gauche
1298 aurelien 312
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
856 aurelien 313
					'SET bg = bg + 2 '.
1298 aurelien 314
					'WHERE bg >= '.$valeur.' '.
856 aurelien 315
					'	AND ce_utilisateur = '.$this->proteger($id_utilisateur).' ';
316
		$reussi_2 = $this->executer($requete);
821 jpm 317
 
1298 aurelien 318
		return $reussi_1 !== false && $reussi_2 !== false;
416 aurelien 319
	}
320
 
821 jpm 321
	/**
322
	 * Décale les bornes d'un intervalle negatif donne (pour la suppression d'un sous arbre).
323
	 */
324
	private function decalerBornesMoinsIntervalle($bg, $bd, $id_utilisateur) {
325
		$decalage = $bd - $bg + 1;
416 aurelien 326
 
821 jpm 327
		// Décalage borne droite
1298 aurelien 328
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
329
					'SET bd = bd - '.$decalage.' '.
330
					'WHERE bd >=  '.$bg.' '.
856 aurelien 331
					'	AND ce_utilisateur = '.$this->proteger($id_utilisateur).' ';
332
		$reussi_1 = $this->executer($requete);
416 aurelien 333
 
821 jpm 334
		// Décalage borne gauche
1298 aurelien 335
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
336
					'SET bg = bg - '.$decalage.' '.
337
					'WHERE bg >  '.$bg.' '.
856 aurelien 338
					'	AND ce_utilisateur = '.$this->proteger($id_utilisateur).' ';
339
		$reussi_2 = $this->executer($requete);
821 jpm 340
 
1298 aurelien 341
		return $reussi_1 !== false && $reussi_2 !== false;
416 aurelien 342
	}
343
 
821 jpm 344
	/**
345
	 * Décale à droite des bornes donées d'un intervalle positif donne (pour l'ajout d'un sous arbre).
346
	 */
347
	private function decalerBornesPlusIntervalle($valeur_bornes, $largeur, $id_utilisateur) {
348
		$decalage = $largeur;
416 aurelien 349
 
821 jpm 350
		// decalage borne droite
1298 aurelien 351
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
352
					'SET bd = bd + '.$decalage.' '.
353
					'WHERE bd >=  '.$valeur_bornes.' '.
856 aurelien 354
					'	AND ce_utilisateur = '.$this->proteger($id_utilisateur).' ';
355
		$reussi_1 = $this->executer($requete);
416 aurelien 356
 
821 jpm 357
		// decalage borne gauche
1298 aurelien 358
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
359
					'SET bg = bg + '.$decalage.' '.
360
					'WHERE bg >=  '.$valeur_bornes.' '.
856 aurelien 361
					'	AND ce_utilisateur = '.$this->proteger($id_utilisateur).' ';
362
		$reussi_2 = $this->executer($requete);
416 aurelien 363
 
1298 aurelien 364
		return $reussi_1 !== false && $reussi_2 !== false;
821 jpm 365
	}
416 aurelien 366
 
821 jpm 367
	/**
368
	 * Inverse les bornes d'un intervalle pour l'exclure des modifications sur l'arbre sans changer la hiérarchie.
369
	 */
370
	private function exclureIntervalle($bg, $bd, $id_utilisateur) {
1298 aurelien 371
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
372
					'SET bd = bd - '.$bd.' - 1 , '.
373
					'	bg =  bg -  '.$bd.' - 1 '.
374
					'WHERE bd <=  '.$bd.' '.
375
					'	AND bg >=  '.$bg.' '.
856 aurelien 376
					'	AND ce_utilisateur = '.$this->proteger($id_utilisateur).' ';
416 aurelien 377
 
856 aurelien 378
		return $this->executer($requete);
416 aurelien 379
	}
380
 
821 jpm 381
	/**
382
	 * Recale les bornes dun intervalle pour l'inclure dans l'arbre à la bonne place.
383
	 * Décalage borne droite
384
	 */
385
	private function inclureIntervalle($bg, $bd, $decalage,$modif_niveau, $id_utilisateur) {
416 aurelien 386
 
1298 aurelien 387
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
388
					'SET bg =  bg + '.$decalage.' , '.
389
					'	bd = bd + '.$decalage.', '.
856 aurelien 390
					'	niveau = niveau + '.$modif_niveau.' '.
1298 aurelien 391
					' WHERE bg >=  '.$bg.' '.
392
					'	AND bd <=  '.$bd.' '.
856 aurelien 393
					'	AND ce_utilisateur = '.$this->proteger($id_utilisateur).' ';
416 aurelien 394
 
856 aurelien 395
		return $this->executer($requete);
821 jpm 396
	}
416 aurelien 397
 
821 jpm 398
	private function changerPere($id_mot_cle, $id_pere, $id_utilisateur) {
1298 aurelien 399
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
400
					'SET ce_mot_cle_'.$this->suffixe_champ.'_parent = '.$this->proteger($id_pere).' '.
401
					'WHERE id_mot_cle'.$this->suffixe_champ.' = '.$this->proteger($id_mot_cle).' '.
856 aurelien 402
					'	AND ce_utilisateur = '.$this->proteger($id_utilisateur).' ';
821 jpm 403
 
856 aurelien 404
		return $this->executer($requete);
821 jpm 405
	}
416 aurelien 406
 }
407
?>