Subversion Repositories eFlore/Applications.cel

Rev

Rev 1841 | 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.' '.
1765 raphael 50
					'WHERE id_utilisateur = '.Cel::db()->proteger($id_utilisateur).' '.
856 aurelien 51
					'ORDER BY niveau ';
821 jpm 52
 
1765 raphael 53
		$resultats_mots_cles = Cel::db()->requeter($requete);
856 aurelien 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.' '.
1765 raphael 80
						'SET mot_cle = '.Cel::db()->proteger($nouveau_nom).' , '.
81
						'	md5 = '.Cel::db()->proteger($nouvel_id_general).' '.
82
						'WHERE id_mot_cle'.$this->suffixe_champ.' = '.Cel::db()->proteger($id_mot_cle).' '.
83
						'	AND id_utilisateur = '.Cel::db()->proteger($id_utilisateur) ;
84
			$reussite = Cel::db()->executer($requete);
1298 aurelien 85
			if ($reussite !== false) {
821 jpm 86
				echo 'OK';
1834 aurelien 87
				return true;
88
			} else {
89
				return false;
821 jpm 90
			}
91
		} else if ($action == 'deplacement') {
856 aurelien 92
 
821 jpm 93
			$this->commencerTransaction();
856 aurelien 94
 
821 jpm 95
			$transaction_reussie_1 = true;
96
			$id_pere = $pairs['parent'];
97
			$bornes = $this->calculerBornesEtNiveau($id_mot_cle, $id_utilisateur);
856 aurelien 98
			$bg = $bornes['bg'];
99
			$bd = $bornes['bd'];
100
			$niveau = $bornes['niveau'];
416 aurelien 101
 
821 jpm 102
			// on inverse l'intervalle de l'élément déplacé et du sous arbre
856 aurelien 103
			$transaction_reussie_2 = $this->exclureIntervalle($bg, $bd, $id_utilisateur);
416 aurelien 104
 
821 jpm 105
			$bg_negative = $bg - $bd - 1;
106
			$bd_negative = $bd - $bd - 1;
416 aurelien 107
 
821 jpm 108
			// on recalcule les intervalles de l'arbre privé de ce sous arbre
856 aurelien 109
			$transaction_reussie_3 = $this->decalerBornesMoinsIntervalle($bg, $bd, $id_utilisateur);
416 aurelien 110
 
821 jpm 111
			$bornes_pere = $this->calculerBornesEtNiveau($id_pere, $id_utilisateur);
856 aurelien 112
			$bg_pere = $bornes_pere['bg'];
113
			$bd_pere = $bornes_pere['bd'];
416 aurelien 114
 
856 aurelien 115
			$niveau_pere = $bornes_pere['niveau'];
416 aurelien 116
 
821 jpm 117
			$decalage = $bd - $bg + 1;
416 aurelien 118
 
821 jpm 119
			// on decale les bornes droite du pere pour préparer l'insertion
856 aurelien 120
			$transaction_reussie_4 = $this->decalerBornesPlusIntervalle($bd_pere, $decalage, $id_utilisateur);
821 jpm 121
 
122
			$nouvelle_bd = $bd_pere + $decalage;
123
			$modif_niveau = $niveau_pere - $niveau + 1;
416 aurelien 124
 
856 aurelien 125
			$transaction_reussie_5 = $this->inclureIntervalle($bg_negative, $bd_negative, $nouvelle_bd, $modif_niveau, $id_utilisateur);
126
 
127
			$transaction_reussie_6 = $this->changerPere($id_mot_cle, $id_pere, $id_utilisateur);
416 aurelien 128
 
1298 aurelien 129
			if ($transaction_reussie_1 !== false && $transaction_reussie_2 !== false &&
130
				$transaction_reussie_3 !== false && $transaction_reussie_4 !== false &&
131
				$transaction_reussie_5 !== false && $transaction_reussie_6 !== false) {
821 jpm 132
				$this->completerTransaction();
1834 aurelien 133
				return true;
821 jpm 134
			} else {
135
				$this->annulerTransaction();
1834 aurelien 136
				return false;
821 jpm 137
			}
138
		}
1841 raphael 139
		return true;
821 jpm 140
	}
416 aurelien 141
 
821 jpm 142
	public function createElement($pairs) {
143
		// Controle detournement utilisateur
1014 aurelien 144
		$this->controleUtilisateur($pairs['identifiant']);
416 aurelien 145
 
1298 aurelien 146
		$this->setChampsEtTablePourSuffixe($pairs['mode']);
1014 aurelien 147
		$id_utilisateur = $pairs['identifiant'];
821 jpm 148
		$mot_cle = $pairs['motcle'];
416 aurelien 149
 
856 aurelien 150
		// TODO supprimer accents
821 jpm 151
		$id_mot_cle_general = md5(mb_strtolower($mot_cle));
152
		$id_mot_cle = $pairs['id'];
153
		$id_parent = $pairs['parent'];
416 aurelien 154
 
821 jpm 155
		$this->ajouterMotCleRacine($id_utilisateur);
416 aurelien 156
 
821 jpm 157
		$this->commencerTransaction();
416 aurelien 158
 
821 jpm 159
		$bornes = $this->calculerBornesEtNiveau($id_parent, $id_utilisateur);
856 aurelien 160
		$borne_pere = $bornes['bd'];
161
		$niveau = $bornes['niveau'] + 1;
162
		$bg = $bornes['bd'];
821 jpm 163
		$bd = $bg + 1;
416 aurelien 164
 
821 jpm 165
		$transaction_reussie_1 = $this->decalerBornesPlusDeux($borne_pere,$id_utilisateur) ? true : false;
166
 
1298 aurelien 167
		$requete = 	'INSERT INTO  cel_mots_cles'.$this->suffixe_table.' '.
821 jpm 168
					'VALUES ( '.
1765 raphael 169
					Cel::db()->proteger($id_mot_cle).', '.
170
					Cel::db()->proteger($id_utilisateur).', '.
171
					Cel::db()->proteger($mot_cle).', '.
172
					Cel::db()->proteger($id_mot_cle_general).', '.
173
					Cel::db()->proteger($bg).', '.
174
					Cel::db()->proteger($bd).', '.
175
					Cel::db()->proteger($niveau).', '.
176
					Cel::db()->proteger($id_parent).') ' ;
856 aurelien 177
 
1765 raphael 178
		$transaction_reussie_2 = Cel::db()->executer($requete);
416 aurelien 179
 
821 jpm 180
		if ($transaction_reussie_1 && $transaction_reussie_2) {
181
			$this->completerTransaction();
1834 aurelien 182
			return true;
821 jpm 183
		} else {
184
			$this->annulerTransaction();
1834 aurelien 185
			return false;
416 aurelien 186
		}
1841 raphael 187
		return true;
416 aurelien 188
	}
189
 
821 jpm 190
	public function deleteElement($uid) {
191
 
1298 aurelien 192
		$this->setChampsEtTablePourSuffixe($uid[0]);
821 jpm 193
		$id_utilisateur = $uid[1];
194
		$id_mot_cle = $uid[2];
1300 aurelien 195
 
196
		$tableau_ids_mots_cles = array();
197
		$tableau_ids_mots_cles[] = $id_mot_cle;
416 aurelien 198
 
821 jpm 199
		$this->controleUtilisateur($id_utilisateur);
200
		$this->commencerTransaction();
416 aurelien 201
 
821 jpm 202
		$bornes  = $this->calculerBornesEtNiveau($id_mot_cle, $id_utilisateur);
1300 aurelien 203
		if($bornes) {
204
			$bg = $bornes['bg'];
205
			$bd = $bornes['bd'];
206
 
207
			$requete_mots_cles_fils = 'SELECT id_mot_cle'.$this->suffixe_champ.' as id FROM cel_mots_cles'.$this->suffixe_table.' '.
1765 raphael 208
						'WHERE bg >= '.Cel::db()->proteger($bg).' '.
209
						'	AND bd <= '.Cel::db()->proteger($bd).' '.
210
						'	AND id_utilisateur = '.Cel::db()->proteger($id_utilisateur).' ';
416 aurelien 211
 
1765 raphael 212
			$mots_cles_fils = Cel::db()->requeter($requete_mots_cles_fils);
1300 aurelien 213
			foreach ($mots_cles_fils as $fils) {
214
				$tableau_ids_mots_cles[] = $fils['id'];
215
			}
216
 
217
			$requete = 	'DELETE FROM cel_mots_cles'.$this->suffixe_table.' '.
1765 raphael 218
						'WHERE bg >= '.Cel::db()->proteger($bg).' '.
219
						'	AND bd <= '.Cel::db()->proteger($bd).' '.
220
						'	AND id_utilisateur = '.Cel::db()->proteger($id_utilisateur).' ';
1300 aurelien 221
 
1765 raphael 222
			$transaction_reussie_1 = Cel::db()->executer($requete);
1300 aurelien 223
			$transaction_reussie_2 = $this->decalerBornesMoinsIntervalle($bg, $bd, $id_utilisateur) ? true : false;
224
 
225
			if ($transaction_reussie_1 !== false && $transaction_reussie_2 !== false) {
226
				$this->completerTransaction();
227
			} else {
228
				$this->annulerTransaction();
229
			}
416 aurelien 230
		}
1300 aurelien 231
		// Suppression des liaisons associées à ce mot clé
232
		$gestion_liaisons = new LiaisonMotsCles($this->config, $this->suffixe);
233
		$gestion_liaisons->supprimerToutesLiaisonsPourIdMotCle($id_utilisateur, $tableau_ids_mots_cles);
1834 aurelien 234
 
235
		return true;
416 aurelien 236
	}
821 jpm 237
 
238
	private function ajouterMotCleRacine($id) {
856 aurelien 239
		$requete = 	'SELECT COUNT(*) as nb_mc '.
1298 aurelien 240
					'FROM cel_mots_cles'.$this->suffixe_table.' '.
1765 raphael 241
					'WHERE id_utilisateur = '.Cel::db()->proteger($id).' ';
242
		$resultat = Cel::db()->requeter($requete);
416 aurelien 243
 
856 aurelien 244
		if (is_array($resultat) && count($resultat) > 0) {
245
			$valeurs = $resultat[0]['nb_mc'];
416 aurelien 246
 
1298 aurelien 247
			switch ($this->suffixe) {
248
				case 'obs' :
821 jpm 249
					$nom_racine = 'Projets';
250
					$id_racine = 'racine_obs';
251
					break;
1298 aurelien 252
				case 'images' :
821 jpm 253
					$nom_racine = 'Mots clés';
254
					$id_racine = 'racine';
255
					break;
256
				default:
1298 aurelien 257
					$nom_racine = $this->suffixe;
258
					$id_racine = $this->suffixe;
821 jpm 259
			}
1425 aurelien 260
 
1765 raphael 261
			$md5_racine = Cel::db()->proteger(md5($nom_racine));
262
			$id_racine = Cel::db()->proteger($id_racine);
263
			$nom_racine = Cel::db()->proteger($nom_racine);
264
			$id_utilisateur = Cel::db()->proteger($id);
416 aurelien 265
 
1425 aurelien 266
			if ($valeurs == 0) {
267
				$requete = "INSERT INTO cel_mots_cles{$this->suffixe_table} ".
268
						   "VALUES ($id_racine, $id_utilisateur, $nom_racine, $md5_racine, ".
269
						   "1, 2, 0, '') ";
270
 
1765 raphael 271
				Cel::db()->executer($requete);
821 jpm 272
			}
416 aurelien 273
		}
821 jpm 274
	}
416 aurelien 275
 
821 jpm 276
	/**
277
	 * Désactive l'auto-commit puis débute la transaction
278
	 */
279
	private function commencerTransaction() {
280
		// Désactive l'autocommit le temps de la manipulation de l'arbre
281
		$requete = 'SET AUTOCOMMIT = 0 ';
1765 raphael 282
		$reussite_autocommit = Cel::db()->executer($requete);
416 aurelien 283
 
821 jpm 284
		// Débute une nouvelle transaction
285
		$requete = 'BEGIN ';
1765 raphael 286
		$reussite_begin = Cel::db()->executer($requete);
416 aurelien 287
	}
288
 
821 jpm 289
	/**
290
	 * Termine la transaction puis réactive l'auto-commit
291
	 */
292
	private function completerTransaction() {
293
		// Complète la transaction
294
		$requete = 'COMMIT ';
1765 raphael 295
		$reussite_commit = Cel::db()->executer($requete);
416 aurelien 296
 
821 jpm 297
		// Réactive l'autocommit le temps de la manipulation de l'arbre
298
		$requete = 'SET AUTOCOMMIT = 1 ';
1765 raphael 299
		$reussite_autocommit = Cel::db()->executer($requete);
416 aurelien 300
 
821 jpm 301
		echo 'OK';
1869 raphael 302
		// on sort de self::(create|update)Element ==> JRest::(get|post) ==> JRest->created() qui fait header().
303
		// TODO: si updateElement(): die();
416 aurelien 304
	}
821 jpm 305
 
306
	/**
307
	 * Annule la transaction et réactive l'auto-commit
308
	 */
309
	private function annulerTransaction() {
310
		// Annule la transaction
311
		$requete = 'ROLLBACK ';
1765 raphael 312
		$reussite_rollback = Cel::db()->executer($requete);
416 aurelien 313
 
821 jpm 314
		// Réactive l'autocommit le temps de la manipulation de l'arbre
315
		$requete = 'SET AUTOCOMMIT = 1 ';
1765 raphael 316
		$reussite_autocommit = Cel::db()->executer($requete);
416 aurelien 317
 
821 jpm 318
		echo 'ERROR';
319
	}
416 aurelien 320
 
821 jpm 321
	/**
322
	 * Renvoie les bornes d'un noeud de l'arbre des mots clés
323
	 */
324
	private function calculerBornesEtNiveau($id_mot_cle,$id_utilisateur) {
856 aurelien 325
		$requete = 	'SELECT bd, bg, niveau '.
1298 aurelien 326
					'FROM cel_mots_cles'.$this->suffixe_table.' '.
1765 raphael 327
					'WHERE id_mot_cle'.$this->suffixe_champ.' = '.Cel::db()->proteger($id_mot_cle).' '.
328
					'	AND id_utilisateur = '.Cel::db()->proteger($id_utilisateur).' ';
1300 aurelien 329
 
1765 raphael 330
		$resultat = Cel::db()->requeter($requete);
856 aurelien 331
 
1300 aurelien 332
		$valeurs = null;
856 aurelien 333
		if(is_array($resultat) && count($resultat) > 0) {
334
			$valeurs = $resultat[0];
335
		}
336
 
821 jpm 337
		return $valeurs;
338
	}
416 aurelien 339
 
821 jpm 340
	/**
341
	 * Décale les bornes de deux pour insérer un nouvel élément
342
	 */
343
	private function decalerBornesPlusDeux($valeur, $id_utilisateur) {
344
		// Décalage borne droite
1298 aurelien 345
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
346
					'SET bd = bd + 2 WHERE bd >= '.$valeur.' '.
1765 raphael 347
					'	AND id_utilisateur = '.Cel::db()->proteger($id_utilisateur).' ';
348
		$reussi_1 = Cel::db()->executer($requete);
821 jpm 349
 
350
		// Décalage borne gauche
1298 aurelien 351
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
856 aurelien 352
					'SET bg = bg + 2 '.
1298 aurelien 353
					'WHERE bg >= '.$valeur.' '.
1765 raphael 354
					'	AND id_utilisateur = '.Cel::db()->proteger($id_utilisateur).' ';
355
		$reussi_2 = Cel::db()->executer($requete);
821 jpm 356
 
1298 aurelien 357
		return $reussi_1 !== false && $reussi_2 !== false;
416 aurelien 358
	}
359
 
821 jpm 360
	/**
361
	 * Décale les bornes d'un intervalle negatif donne (pour la suppression d'un sous arbre).
362
	 */
363
	private function decalerBornesMoinsIntervalle($bg, $bd, $id_utilisateur) {
364
		$decalage = $bd - $bg + 1;
416 aurelien 365
 
821 jpm 366
		// Décalage borne droite
1298 aurelien 367
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
368
					'SET bd = bd - '.$decalage.' '.
369
					'WHERE bd >=  '.$bg.' '.
1765 raphael 370
					'	AND id_utilisateur = '.Cel::db()->proteger($id_utilisateur).' ';
371
		$reussi_1 = Cel::db()->executer($requete);
416 aurelien 372
 
821 jpm 373
		// Décalage borne gauche
1298 aurelien 374
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
375
					'SET bg = bg - '.$decalage.' '.
376
					'WHERE bg >  '.$bg.' '.
1765 raphael 377
					'	AND id_utilisateur = '.Cel::db()->proteger($id_utilisateur).' ';
378
		$reussi_2 = Cel::db()->executer($requete);
821 jpm 379
 
1298 aurelien 380
		return $reussi_1 !== false && $reussi_2 !== false;
416 aurelien 381
	}
382
 
821 jpm 383
	/**
384
	 * Décale à droite des bornes donées d'un intervalle positif donne (pour l'ajout d'un sous arbre).
385
	 */
386
	private function decalerBornesPlusIntervalle($valeur_bornes, $largeur, $id_utilisateur) {
387
		$decalage = $largeur;
416 aurelien 388
 
821 jpm 389
		// decalage borne droite
1298 aurelien 390
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
391
					'SET bd = bd + '.$decalage.' '.
392
					'WHERE bd >=  '.$valeur_bornes.' '.
1765 raphael 393
					'	AND id_utilisateur = '.Cel::db()->proteger($id_utilisateur).' ';
394
		$reussi_1 = Cel::db()->executer($requete);
416 aurelien 395
 
821 jpm 396
		// decalage borne gauche
1298 aurelien 397
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
398
					'SET bg = bg + '.$decalage.' '.
399
					'WHERE bg >=  '.$valeur_bornes.' '.
1765 raphael 400
					'	AND id_utilisateur = '.Cel::db()->proteger($id_utilisateur).' ';
401
		$reussi_2 = Cel::db()->executer($requete);
416 aurelien 402
 
1298 aurelien 403
		return $reussi_1 !== false && $reussi_2 !== false;
821 jpm 404
	}
416 aurelien 405
 
821 jpm 406
	/**
407
	 * Inverse les bornes d'un intervalle pour l'exclure des modifications sur l'arbre sans changer la hiérarchie.
408
	 */
409
	private function exclureIntervalle($bg, $bd, $id_utilisateur) {
1298 aurelien 410
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
411
					'SET bd = bd - '.$bd.' - 1 , '.
412
					'	bg =  bg -  '.$bd.' - 1 '.
413
					'WHERE bd <=  '.$bd.' '.
414
					'	AND bg >=  '.$bg.' '.
1765 raphael 415
					'	AND id_utilisateur = '.Cel::db()->proteger($id_utilisateur).' ';
416 aurelien 416
 
1765 raphael 417
		return Cel::db()->executer($requete);
416 aurelien 418
	}
419
 
821 jpm 420
	/**
421
	 * Recale les bornes dun intervalle pour l'inclure dans l'arbre à la bonne place.
422
	 * Décalage borne droite
423
	 */
424
	private function inclureIntervalle($bg, $bd, $decalage,$modif_niveau, $id_utilisateur) {
416 aurelien 425
 
1298 aurelien 426
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
427
					'SET bg =  bg + '.$decalage.' , '.
428
					'	bd = bd + '.$decalage.', '.
856 aurelien 429
					'	niveau = niveau + '.$modif_niveau.' '.
1298 aurelien 430
					' WHERE bg >=  '.$bg.' '.
431
					'	AND bd <=  '.$bd.' '.
1765 raphael 432
					'	AND id_utilisateur = '.Cel::db()->proteger($id_utilisateur).' ';
416 aurelien 433
 
1765 raphael 434
		return Cel::db()->executer($requete);
821 jpm 435
	}
416 aurelien 436
 
821 jpm 437
	private function changerPere($id_mot_cle, $id_pere, $id_utilisateur) {
1298 aurelien 438
		$requete = 	'UPDATE cel_mots_cles'.$this->suffixe_table.' '.
1765 raphael 439
					'SET ce_mot_cle'.$this->suffixe_champ.'_parent = '.Cel::db()->proteger($id_pere).' '.
440
					'WHERE id_mot_cle'.$this->suffixe_champ.' = '.Cel::db()->proteger($id_mot_cle).' '.
441
					'	AND id_utilisateur = '.Cel::db()->proteger($id_utilisateur).' ';
1300 aurelien 442
 
1765 raphael 443
		return Cel::db()->executer($requete);
821 jpm 444
	}
416 aurelien 445
 }
446
?>