Subversion Repositories eFlore/Applications.cel

Rev

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