Subversion Repositories eFlore/Applications.cel

Rev

Rev 2197 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2025 aurelien 1
<?php
2
/**
3
* @package   jrest
4
* @author    Aurélien Peronnet <aurelien@tela-botania.org>
5
* @copyright 2010, 2013 Tela-Botanica
6
* @license   http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
7
*
8
* Librairie de liaison d'images et d'observation à des mots clés en utilisant la méthode
9
* path enumeration
10
*/
11
 
12
class GestionMotsClesChemin {
2101 jpm 13
 
2025 aurelien 14
	private $config;
15
	private $mode;
2101 jpm 16
 
2025 aurelien 17
	private $table_liaison;
18
	private $table_mots_cles;
2101 jpm 19
 
2032 aurelien 20
	//TODO: trigger pour les tables liaisons
2101 jpm 21
 
2026 aurelien 22
	public function GestionMotsClesChemin($config, $mode = 'obs') {
2025 aurelien 23
		$this->config = $config;
24
		//TODO: switch suivant mode
2027 aurelien 25
		$this->mode = $mode;
2101 jpm 26
 
2060 aurelien 27
		list($this->table_liaison, $this->table_mots_cles) = self::getTablesMotsClesEtLiaisons($mode);
2059 aurelien 28
	}
2101 jpm 29
 
30
	public function obtenirArbre($id_utilisateur, $chemin = '/') {
31
		$idUtilisateurP = Cel::db()->proteger($id_utilisateur);
32
		$cheminP = Cel::db()->proteger($chemin.'%');
33
 
34
		$requete = 'SELECT * '.
35
			"FROM {$this->table_mots_cles} ".
36
			"WHERE id_utilisateur = $idUtilisateurP ".
37
			"AND chemin LIKE $cheminP ".
38
			'ORDER BY chemin '.
39
			' -- '.__FILE__.':'.__LINE__;
40
 
41
		$arbre = Cel::db()->requeter($requete);
2186 mathias 42
		foreach ($arbre as &$noeud) {
43
			$noeud['chemin'] = strtolower($noeud['chemin']);
44
		}
2026 aurelien 45
		usort($arbre, array('GestionMotsClesChemin', 'comparerProfNoeuds'));
2025 aurelien 46
		return $arbre;
47
	}
2101 jpm 48
 
2042 aurelien 49
	public function obtenirIdsMotsClesParIdParent($id_utilisateur, $id_mot_cle) {
2101 jpm 50
		$idMotCleP = Cel::db()->proteger($id_mot_cle);
2111 aurelien 51
		$idUtilisateurP = Cel::db()->proteger($id_utilisateur);
2042 aurelien 52
 
2101 jpm 53
		$sousRequete = "SELECT chemin FROM {$this->table_mots_cles} WHERE id_mot_cle = $idMotCleP ";
54
		$requete = 'SELECT id_mot_cle '.
55
			"FROM {$this->table_mots_cles} ".
56
			"WHERE chemin LIKE CONCAT(($sousRequete), '%') ".
2111 aurelien 57
			"AND id_utilisateur = ".$idUtilisateurP." ".
2101 jpm 58
			' -- '.__FILE__.':'.__LINE__;
59
 
2143 jpm 60
		$ids_enfants = Cel::db()->requeter($requete);
2101 jpm 61
 
2042 aurelien 62
		return $ids_enfants;
63
	}
2101 jpm 64
 
2056 aurelien 65
	public function insererParCheminSiInexistant($mot_cle, $chemin_parent, $id_utilisateur) {
2198 mathias 66
		$mot_cle = self::simplifier($mot_cle);
2101 jpm 67
		$cheminMotCle = self::getCheminHarmonise($chemin_parent, $mot_cle);
68
		$cheminMotCleP = Cel::db()->proteger($cheminMotCle);
69
		$idUtilisateurP = Cel::db()->proteger($id_utilisateur);
2056 aurelien 70
 
2101 jpm 71
		$requete = 'SELECT id_mot_cle '.
72
			"FROM {$this->table_mots_cles} ".
73
			"WHERE chemin = $cheminMotCleP ".
74
			"AND id_utilisateur = $idUtilisateurP ".
75
			' -- '.__FILE__.':'.__LINE__;
76
 
2143 jpm 77
		$infosMotCle = Cel::db()->requeter($requete);
2101 jpm 78
 
79
		if (!empty($infosMotCle)) {
80
			$idMotCle = $infosMotCle[0]['id_mot_cle'];
2056 aurelien 81
		} else {
2101 jpm 82
			$idMotCle = $this->insererParChemin($mot_cle, $chemin_parent, $id_utilisateur);
2056 aurelien 83
		}
2101 jpm 84
		return $idMotCle;
2056 aurelien 85
	}
2101 jpm 86
 
87
	public function insererParChemin($mot_cle, $chemin_parent, $id_utilisateur) {
2198 mathias 88
		$mot_cle = self::simplifier($mot_cle);
2101 jpm 89
		$cheminMotCle = self::getCheminHarmonise($chemin_parent, $mot_cle);
90
		$cheminMotCleP = Cel::db()->proteger($cheminMotCle);
91
		$idUtilisateurP = Cel::db()->proteger($id_utilisateur);
92
		$motCleP = Cel::db()->proteger($mot_cle);
93
 
94
		$requete = "INSERT INTO {$this->table_mots_cles} ".
95
			'(chemin, id_utilisateur, mot_cle) '.
96
			"VALUES ($cheminMotCleP, $idUtilisateurP, $motCleP ) ".
97
			' -- '.__FILE__.':'.__LINE__;
98
 
99
		$insertion = Cel::db()->executer($requete);
2042 aurelien 100
		$resultat = false;
2101 jpm 101
		if ($insertion !== false) {
2042 aurelien 102
			$resultat = Cel::db()->obtenirDernierId();
103
		}
104
		return $resultat;
2025 aurelien 105
	}
2101 jpm 106
 
107
	public function insererParIdParent($mot_cle, $id_parent, $id_utilisateur) {
108
		$motCleSimple = self::simplifier($mot_cle);
2197 mathias 109
		$motCleSimpleP = Cel::db()->proteger(strtolower(self::supprimerAccents($mot_cle)));
2101 jpm 110
		$idParentP = Cel::db()->proteger($id_parent);
111
		$racineP = Cel::db()->proteger('/');
112
		$idUtilisateurP = Cel::db()->proteger($id_utilisateur);
113
		$motCleP = Cel::db()->proteger($mot_cle);
114
 
115
		$sousRequete = $racineP;
116
		if ($id_parent != '') {
117
			$sousRequete = '(SELECT chemin '.
118
				"FROM {$this->table_mots_cles} AS ctp ".
119
				"WHERE ctp.id_mot_cle = $idParentP) ";
2042 aurelien 120
		}
2045 aurelien 121
 
2101 jpm 122
		$requete = "INSERT INTO {$this->table_mots_cles} (chemin, id_utilisateur, mot_cle) ".
123
			"VALUES (CONCAT($sousRequete, $motCleSimpleP, '/'), $idUtilisateurP, $motCleP ) ".
124
			' -- '.__FILE__.':'.__LINE__;
125
 
126
		$insertion = Cel::db()->executer($requete);
127
		if ($insertion !== false) {
2042 aurelien 128
			$resultat = Cel::db()->obtenirDernierId();
129
		}
130
		return $resultat;
2025 aurelien 131
	}
2101 jpm 132
 
2032 aurelien 133
	public function lierParId($id_mot_cle, $id_element_lie) {
2101 jpm 134
		$idElementLieP = Cel::db()->proteger($id_element_lie);
135
		$idMotCleP = Cel::db()->proteger($id_mot_cle);
2143 jpm 136
 
2101 jpm 137
		$requete = "INSERT INTO {$this->table_liaison} (id_element_lie, id_mot_cle) ".
138
			"VALUES ($idElementLieP, $idMotCleP) ".
139
			'ON DUPLICATE KEY UPDATE id_element_lie = id_element_lie '.
140
			' -- '.__FILE__.':'.__LINE__;
141
 
142
		$liaison = Cel::db()->executer($requete);
2025 aurelien 143
		return $liaison;
144
	}
2101 jpm 145
 
2032 aurelien 146
	public function lierParChemin($chemin, $id_element_lie, $id_utilisateur) {
2101 jpm 147
		$cheminP = Cel::db()->proteger(self::harmoniserChemin($chemin));
148
		$idElementLieP = Cel::db()->proteger($id_element_lie);
149
		$idUtilisateurP = Cel::db()->proteger($id_utilisateur);
2143 jpm 150
 
2101 jpm 151
		$sousRequete = '(SELECT id_mot_cle '.
152
			"FROM {$this->table_mots_cles} ".
153
			"WHERE chemin = $cheminP ".
154
			"AND id_utilisateur = $idUtilisateurP ".
155
			')';
156
		$requete = "INSERT INTO {$this->table_liaison} (id_element_lie, id_mot_cle) ".
157
			"VALUES ($idElementLieP, $sousRequete) ".
158
			'ON DUPLICATE KEY UPDATE id_element_lie = id_element_lie '.
159
			' -- '.__FILE__.':'.__LINE__;
2032 aurelien 160
 
2101 jpm 161
		$liaison = Cel::db()->executer($requete);
2025 aurelien 162
		return $liaison;
163
	}
2101 jpm 164
 
2042 aurelien 165
	public function lierParTableaux($ids_mots_cles, $ids_elements_lies, $id_utilisateur) {
2101 jpm 166
		$combinaisons = array();
167
		foreach ($ids_mots_cles as $id_mot_cle) {
168
			$idMotCleP = Cel::db()->proteger($id_mot_cle);
169
			foreach ($ids_elements_lies as $id_element_lie) {
170
				$idElementLieP = Cel::db()->proteger($id_element_lie);
171
				$combinaisons[] = "($idElementLieP, $idMotCleP)";
2042 aurelien 172
			}
2101 jpm 173
		}
174
 
175
		$valeursGroupees = implode(', ', $combinaisons);
176
		$requete = "INSERT INTO {$this->table_liaison} (id_element_lie, id_mot_cle) ".
177
			"VALUES $valeursGroupees ".
178
			"ON DUPLICATE KEY UPDATE id_element_lie = id_element_lie ".
179
			' -- '.__FILE__.':'.__LINE__;
180
		$liaison = Cel::db()->executer($requete);
181
 
2042 aurelien 182
		return $liaison;
183
	}
2101 jpm 184
 
2042 aurelien 185
	public function supprimerLiaisonsMotsCles($ids_mots_cles, $ids_elements_lies, $id_utilisateur) {
186
		$combinaisons = array();
2101 jpm 187
		foreach ($ids_mots_cles as $id_mot_cle) {
188
			$idMotCleP = Cel::db()->proteger($id_mot_cle);
189
			foreach ($ids_elements_lies as $id_element_lie) {
190
				$idElementLieP = Cel::db()->proteger($id_element_lie);
191
				$combinaisons[] = "(id_element_lie = $idElementLieP AND id_mot_cle = $idMotCleP)";
2042 aurelien 192
			}
2101 jpm 193
		}
194
		$clauseWhere = implode(' OR ', $combinaisons);
2143 jpm 195
 
2101 jpm 196
		$requete = "DELETE FROM {$this->table_liaison} ".
197
			"WHERE $clauseWhere ".
198
			' -- '.__FILE__.':'.__LINE__;
2143 jpm 199
 
2101 jpm 200
		$suppression = Cel::db()->executer($requete);
2042 aurelien 201
		return $suppression;
202
	}
2101 jpm 203
 
2058 aurelien 204
	public function supprimerToutesLiaisonsPourIdsElementsLies($ids_elements_lies) {
2143 jpm 205
		$idsElementsLiesP = Cel::db()->proteger($ids_elements_lies);
2101 jpm 206
		$listeIds = implode(',', $idsElementsLiesP);
2143 jpm 207
 
2101 jpm 208
		$requete = "DELETE FROM {$this->table_liaison} ".
209
			"WHERE id_element_lie IN ($listeIds) ".
210
			' -- '.__FILE__.':'.__LINE__;
211
 
212
		$suppression = Cel::db()->executer($requete);
213
		$suppression = ($suppression !== false) ? true : false;
2042 aurelien 214
		return $suppression;
215
	}
2101 jpm 216
 
2042 aurelien 217
	public function supprimerToutesLiaisonsIdsMotsCles($ids_mots_cles, $id_utilisateur) {
2101 jpm 218
		$suppression = true;
219
		if (!empty($ids_mots_cles)) {
2143 jpm 220
			$idsMotsClesP = Cel::db()->proteger($ids_mots_cles);
2101 jpm 221
			$listeIds = implode(',', $idsMotsClesP);
2143 jpm 222
 
2101 jpm 223
			$requete = "DELETE FROM {$this->table_liaison} ".
224
				"WHERE id_mot_cle IN ($listeIds) ".
225
				' -- '.__FILE__.':'.__LINE__;
226
 
2143 jpm 227
			$suppression = Cel::db()->executer($requete);
2101 jpm 228
			$suppression = ($suppression !== false) ? true : false;
2042 aurelien 229
		}
230
		return $suppression;
231
	}
2101 jpm 232
 
233
	/**
234
	 * Supprime toutes les laisons pour un utilisateur et un mot clé (au sens textuel) donnés.
2143 jpm 235
	 *
2101 jpm 236
	 */
2046 aurelien 237
	public function supprimerLiaisonPourMotCleEtIdElementLie($mot_cle, $id_element_lie, $id_utilisateur) {
2198 mathias 238
		$mot_cle = self::simplifier($mot_cle);
2101 jpm 239
		$idElementLieP = Cel::db()->proteger($id_element_lie);
240
		$motCleP = Cel::db()->proteger($mot_cle);
241
		$idUtilisateurP = Cel::db()->proteger($id_utilisateur);
2143 jpm 242
 
2101 jpm 243
		$sousRequete = "SELECT id_mot_cle FROM {$this->table_mots_cles} ".
244
			"WHERE mot_cle = $motCleP ".
245
			"AND id_utilisateur = $idUtilisateurP ";
246
		$requete = "DELETE FROM {$this->table_liaison} ".
247
			"WHERE id_element_lie = $idElementLieP ".
248
			"AND id_mot_cle IN ($sousRequete) ".
249
			' -- '.__FILE__.':'.__LINE__;
2046 aurelien 250
 
2143 jpm 251
		$suppression_liaison = Cel::db()->executer($requete);
2046 aurelien 252
		$suppression_liaison = ($suppression_liaison !== false);
253
 
254
		return $suppression_liaison;
255
	}
2101 jpm 256
 
2042 aurelien 257
	public function renommerMotCle($id_mot_cle, $nouveau_nom) {
2101 jpm 258
		$nouveauNomSimple = self::simplifier($nouveau_nom);
259
		$nouveauNomSimpleP = Cel::db()->proteger($nouveauNomSimple);
260
		$idMotCleP = Cel::db()->proteger($id_mot_cle);
261
 
262
		$requete = 'SELECT chemin, id_utilisateur '.
263
			"FROM {$this->table_mots_cles} ".
264
			"WHERE id_mot_cle = $idMotCleP ".
265
			' -- '.__FILE__.':'.__LINE__;
266
		$ancienCheminInfos = Cel::db()->requeter($requete);
267
 
268
		$ancienChemin = $ancienCheminInfos[0]['chemin'];
269
		$id_utilisateur = $ancienCheminInfos[0]['id_utilisateur'];
270
 
271
		$cheminDecompo = explode('/', $ancienChemin);
2042 aurelien 272
		// le dernier élément du tableau est vide (à cause du / terminal)
273
		// c'est également le cas pour le premier (à cause du / qui commence le chemin)
2101 jpm 274
		$cheminDecompo[count($cheminDecompo) - 2] = $nouveauNomSimple;
275
		$nouveauChemin = implode('/', $cheminDecompo);
276
 
277
		$requete = "UPDATE {$this->table_mots_cles} ".
278
			"SET mot_cle = $nouveauNomSimpleP ".
279
			"WHERE id_mot_cle = $idMotCleP ".
280
			' -- '.__FILE__.':'.__LINE__;
281
 
282
		$renommage = Cel::db()->executer($requete);
283
		$this->renommerChemin($ancienChemin, $nouveauChemin, $id_utilisateur);
284
 
285
		$idsElementsLies = $this->obtenirIdElementsLiesPourIds(array($id_mot_cle));
286
		foreach ($idsElementsLies as $idElementLie) {
287
			self::regenererIndexTexteMotCle($idElementLie['id_element_lie'], $this->mode);
2045 aurelien 288
		}
2101 jpm 289
 
2042 aurelien 290
		return $renommage;
291
	}
292
 
2143 jpm 293
	/**
2101 jpm 294
	 * Si aucun id_père n'est mentionné, c'est un déplacement vers la racine de l'arbre (qui n'existe pas).
295
	 */
296
	public function deplacerMotCle($id_mot_cle, $id_pere, $id_utilisateur) {
297
		$idMotCleP = Cel::db()->proteger($id_mot_cle);
298
		$idPereP = Cel::db()->proteger($id_pere);
299
		$cheminPere = '';
300
 
301
		if ($id_pere != '') {
302
			$requete = 'SELECT chemin '.
303
				"FROM {$this->table_mots_cles} ".
304
				"WHERE id_mot_cle = $idPereP ".
305
				' -- '.__FILE__.':'.__LINE__;
306
 
307
			$cheminPereInfos = Cel::db()->requeter($requete);
308
			if (!empty($cheminPereInfos)) {
309
				$cheminPere = $cheminPereInfos[0]['chemin'];
2061 aurelien 310
			}
311
		}
2101 jpm 312
 
313
		$requete = 'SELECT chemin, mot_cle '.
314
			"FROM {$this->table_mots_cles} ".
315
			"WHERE id_mot_cle = $idMotCleP ".
316
			' -- '.__FILE__.':'.__LINE__;
317
		$infosMotCle = Cel::db()->requeter($requete);
318
		$ancienChemin = $infosMotCle[0]['chemin'];
319
		$ancienMotCle = $infosMotCle[0]['mot_cle'];
320
 
321
		$nouveauChemin = $cheminPere.'/'.$ancienMotCle;
322
 
323
		return $this->renommerChemin($ancienChemin, $nouveauChemin, $id_utilisateur);
2042 aurelien 324
	}
2101 jpm 325
 
2025 aurelien 326
	public function renommerChemin($ancien_chemin, $nouveau_chemin, $id_utilisateur) {
2101 jpm 327
		$ancienCheminHarmonise = self::harmoniserChemin($ancien_chemin);
328
		$nouveauCheminHarmonise = self::harmoniserChemin($nouveau_chemin);
329
 
330
		$idUtilisateurP = Cel::db()->proteger($id_utilisateur);
331
		$ancienCheminP = Cel::db()->proteger($ancienCheminHarmonise);
332
		$nouveauCheminP = Cel::db()->proteger($nouveauCheminHarmonise);
333
		$conditionCheminP = Cel::db()->proteger($ancienCheminHarmonise.'%');
334
 
335
		$requete = "UPDATE {$this->table_mots_cles} ".
336
			"SET chemin = REPLACE(chemin, $ancienCheminP, $nouveauCheminP) ".
337
			"WHERE chemin LIKE $conditionCheminP ".
338
			"AND id_utilisateur = $idUtilisateurP ".
339
			' -- '.__FILE__.':'.__LINE__;
340
 
341
		return Cel::db()->executer($requete);
2025 aurelien 342
	}
2101 jpm 343
 
2025 aurelien 344
	public function supprimerChemin($chemin, $id_utilisateur) {
2101 jpm 345
		$idUtilisateurP = Cel::db()->proteger($id_utilisateur);
346
		$cheminP = Cel::db()->proteger($chemin.'%');
2025 aurelien 347
		// TODO : triggers pour les tables liées ?
2101 jpm 348
		$requete = "DELETE FROM {$this->$table_mots_cles} ".
349
			"WHERE chemin LIKE $cheminP ".
350
			"AND id_utilisateur = $idUtilisateurP ".
351
			' -- '.__FILE__.':'.__LINE__;
2025 aurelien 352
 
2101 jpm 353
		return Cel::db()->executer($requete);
2042 aurelien 354
	}
2101 jpm 355
 
356
	/**
357
	 * suppression des associations du mots clé aux images ou obs, mais aussi des associations de ses enfants
358
	 * (car ceux-ci seront supprimés aussi dans le processus)
359
	 * même s'il n'a pas d'enfants, le tableau contient au moins l'id du mot clé lui même
360
	 */
2043 aurelien 361
	public function supprimerMotCleParId($id_mot_cle, $id_utilisateur) {
362
		//TODO: simplifier cette fonction
363
		$ids_mot_cle_et_enfants = $this->obtenirIdsMotsClesParIdParent($id_utilisateur, $id_mot_cle);
2101 jpm 364
 
2043 aurelien 365
		// obtention des ids des éléments liés au mot clé ainsi qu'à ces enfants (afin de pouvoir
2060 aurelien 366
		// régénérer les index texte de mots clés sur les éléments liés)
2043 aurelien 367
		$ids_a_delier = array();
2101 jpm 368
		foreach ($ids_mot_cle_et_enfants as $id) {
2043 aurelien 369
			$ids_a_delier[] = $id['id_mot_cle'];
370
		}
2101 jpm 371
 
2043 aurelien 372
		$ids_elements_lies = $this->obtenirIdElementsLiesPourIds($ids_a_delier);
373
		$suppression_liaison = $this->supprimerToutesLiaisonsIdsMotsCles($ids_a_delier, $id_utilisateur);
374
 
2101 jpm 375
		foreach ($ids_elements_lies as $id_element_lie) {
2043 aurelien 376
			self::regenererIndexTexteMotCle($id_element_lie['id_element_lie'], $this->mode);
377
		}
2101 jpm 378
 
2043 aurelien 379
		// suppression du mot clé proprement dit ainsi que de ses enfants
380
		$suppression = $this->supprimerMotCleEtEnfantsParId($id_mot_cle, $id_utilisateur);
2101 jpm 381
 
2043 aurelien 382
		return $suppression && $suppression_liaison;
383
	}
2101 jpm 384
 
2042 aurelien 385
	public function supprimerMotCleEtEnfantsParId($id_mot_cle, $id_utilisateur) {
2101 jpm 386
		$idMotCleP = Cel::db()->proteger($id_mot_cle);
2116 jpm 387
		$requete = 'SELECT chemin '.
2101 jpm 388
			"FROM {$this->table_mots_cles} ".
389
			"WHERE id_mot_cle = $idMotCleP ".
390
			' -- '.__FILE__.':'.__LINE__;
2116 jpm 391
		$chemin = Cel::db()->requeter($requete);
2101 jpm 392
 
2043 aurelien 393
		$suppression = true;
2101 jpm 394
		// vérification pour empecher la suppression accidentelle de tout l'arbre,
2060 aurelien 395
		// cas qui ne devrait jamais arriver normalement
2101 jpm 396
		if (!empty($chemin) && $chemin != '/') {
397
			$chemin = $chemin[0]['chemin'];
398
			$cheminP = Cel::db()->proteger($chemin.'%');
399
			$idUtilisateurP = Cel::db()->proteger($id_utilisateur);
2143 jpm 400
 
2101 jpm 401
			$requete = "DELETE FROM {$this->table_mots_cles} ".
402
				"WHERE chemin LIKE $cheminP ".
403
				"AND id_utilisateur = $idUtilisateurP ".
404
				' -- '.__FILE__.':'.__LINE__;;
405
 
406
			$suppression = Cel::db()->executer($requete);
2043 aurelien 407
		}
2042 aurelien 408
 
2043 aurelien 409
		return ($suppression !== false);
2101 jpm 410
 
2025 aurelien 411
	}
2101 jpm 412
 
2056 aurelien 413
	public function obtenirIdsMotClesPourMotsCles($mots_cles, $id_utilisateur) {
2198 mathias 414
		$motsClesP = array();
415
		foreach ($mots_cles as $mot_cle) {
416
			$motsClesP[] = Cel::db()->proteger(self::simplifier($mot_cle));
417
		}
2101 jpm 418
		$listeMotsClesP = implode(',', $motsClesP);
419
		$idUtilisateurP = Cel::db()->proteger($id_utilisateur);
2056 aurelien 420
 
2101 jpm 421
		$requete = 'SELECT id_mot_cle, mot_cle '.
422
			"FROM {$this->table_mots_cles} ".
423
			"WHERE mot_cle IN ($listeMotsClesP) ".
424
			"AND id_utilisateur = $idUtilisateurP ".
425
			' -- '.__FILE__.':'.__LINE__;
2143 jpm 426
 
2101 jpm 427
		$resultat = Cel::db()->executer($requete);
428
		return $resultat;
2056 aurelien 429
	}
2101 jpm 430
 
2046 aurelien 431
	public function obtenirIdElementsLiesPourChemins($chemins, $id_utilisateur) {
2101 jpm 432
		foreach ($chemins as &$chemin) {
2042 aurelien 433
			$chemin = Cel::db()->proteger(self::harmoniserChemin($chemin));
434
		}
2101 jpm 435
		$listeChemins = implode(',', $chemin);
436
		$idUtilisateurP = Cel::db()->proteger($id_utilisateur);
2143 jpm 437
 
2101 jpm 438
		$requete = 'SELECT id_element_lie '.
439
			"FROM {$this->table_liaison} AS cl INNER JOIN {$this->table_mots_cles} AS cm ".
440
			"ON (".
441
				"cm.id_mot_cle = cl.id_mot_cle ".
442
				"AND chemin IN ($listeChemins) ".
443
				"AND cm.id_utilisateur = $idUtilisateurP ".
444
			") ".
445
			' -- '.__FILE__.':'.__LINE__;
446
 
447
		$idsPourChemin = Cel::db()->executer($requete);
448
 
449
		return $idsPourChemin;
2042 aurelien 450
	}
2101 jpm 451
 
2042 aurelien 452
	public function obtenirIdElementsLiesPourIds($ids_mots_cles) {
2101 jpm 453
		$idsElementsLies = array();
454
		if (!empty($ids_mots_cles)) {
2143 jpm 455
			$idsMotsClesP = Cel::db()->proteger($ids_mots_cles);
2101 jpm 456
			$listeIdsMotsCles = implode(',', $idsMotsClesP);
2143 jpm 457
 
2101 jpm 458
			$requete = 'SELECT id_element_lie '.
459
				"FROM {$this->table_liaison} ".
460
				"WHERE id_mot_cle IN ($listeIdsMotsCles) ".
461
				' -- '.__FILE__.':'.__LINE__;
462
 
2143 jpm 463
 
464
			$idsElementsLies = Cel::db()->requeter($requete);
2042 aurelien 465
		}
2101 jpm 466
		return $idsElementsLies;
467
	}
2042 aurelien 468
 
2101 jpm 469
	/**
470
	 *
2060 aurelien 471
	 * Fonctions statiques utilitaires
2101 jpm 472
	 * (Dans l'idéal toute la classe pourrait être statique car elle n'a
2060 aurelien 473
	 * pas d'état (mais il faudrait passer $mode à toutes les fonctions)
2101 jpm 474
	 *
2060 aurelien 475
	 */
476
	public static function getTablesMotsClesEtLiaisons($mode) {
2101 jpm 477
		if ($mode == 'obs') {
2060 aurelien 478
			$table_liaison = 'cel_mots_cles_obs_liaison';
479
			$table_mots_cles = 'cel_arbre_mots_cles_obs';
480
		} else {
481
			$table_liaison = 'cel_mots_cles_images_liaison';
482
			$table_mots_cles = 'cel_arbre_mots_cles_images';
483
		}
484
		return array($table_liaison, $table_mots_cles);
485
	}
2101 jpm 486
 
2043 aurelien 487
	public static function regenererIndexTexteMotCle($id_element_lie, $mode) {
2101 jpm 488
		$idElementLieP = Cel::db()->proteger($id_element_lie);
489
		$sqlTpl = self::obtenirTemplateRequeteMotsClesTexte($mode);
490
		$sousRequete = sprintf($sqlTpl, $idElementLieP);
2060 aurelien 491
 
2101 jpm 492
		list($table, $champId) = self::getNomTablesEtChampsElementsLies($mode);
493
		$requete = "UPDATE $table ".
494
			"SET mots_cles_texte = ($sousRequete) ".
495
			"WHERE $champId = $idElementLieP ".
496
			' -- '.__FILE__.':'.__LINE__;
497
 
498
		return Cel::db()->executer($requete);
2043 aurelien 499
	}
2101 jpm 500
 
2043 aurelien 501
	private static function getNomTablesEtChampsElementsLies($mode) {
502
		$tables = array();
2101 jpm 503
		if ($mode == 'obs') {
504
			$tables = array('cel_obs', 'id_observation');
2043 aurelien 505
		} else {
2101 jpm 506
			$tables = array('cel_images', 'id_image');
2043 aurelien 507
		}
508
		return $tables;
509
	}
2101 jpm 510
 
511
	/**
2143 jpm 512
	 * Renvoie un template de requete pour selectionner la concatenation de mots clé
2101 jpm 513
	 * pour un element donné (utilisable avec sprintf)
514
	 */
2060 aurelien 515
	public static function obtenirTemplateRequeteMotsClesTexte($mode) {
516
		list($table_liaison, $table_mots_cles) = self::getTablesMotsClesEtLiaisons($mode);
2143 jpm 517
 
2101 jpm 518
		$requeteTpl = 'SELECT GROUP_CONCAT(mot_cle) '.
519
			"FROM $table_mots_cles AS cm ".
520
			"INNER JOIN $table_liaison AS cml ON cml.id_mot_cle = cm.id_mot_cle ".
521
			'AND cml.id_element_lie = %s ';
2143 jpm 522
 
2101 jpm 523
		return $requeteTpl;
2042 aurelien 524
	}
2101 jpm 525
	/**
526
	* Renvoie un template de recherche sur les ids de mots clés utilisables avec sprintf.
527
	*/
2060 aurelien 528
	public static function obtenirTemplateRequeteMotsClesIds($mode) {
529
		list($table_liaison, $table_mots_cles) = self::getTablesMotsClesEtLiaisons($mode);
2101 jpm 530
		$requeteTpl = "SELECT id_element_lie FROM $table_liaison WHERE id_mot_cle IN (%s) ";
531
		return $requeteTpl;
2059 aurelien 532
	}
2101 jpm 533
 
534
	// Fonctions utilitaires
2143 jpm 535
 
2101 jpm 536
	/**
537
	 * La profondeur d'un noeud est déterminée par le nombre de slashs
538
	 * qu'il contient (étant donné que ceux ci sont interdits dans le texte du mot clé.
539
	 */
2025 aurelien 540
	static public function comparerProfNoeuds($a, $b) {
541
		$nb_slashs_a = substr_count($a['chemin'], '/');
542
		$nb_slashs_b = substr_count($a['chemin'], '/');
543
		$cmp = 0;
2101 jpm 544
 
545
		if ($nb_slashs_a == $nb_slashs_b) {
2185 mathias 546
			$cmp = strcasecmp($a['chemin'], $b['chemin']);
2025 aurelien 547
		} else {
548
			$cmp = ($a['chemin'] > $b['chemin']) ? +1 : -1;
549
		}
550
		return $cmp;
551
	}
2101 jpm 552
 
2026 aurelien 553
	static public function getCheminHarmonise($chemin_parent, $mot_cle) {
554
		return self::harmoniserChemin($chemin_parent.'/'.self::simplifier($mot_cle).'/');
555
	}
2101 jpm 556
 
2026 aurelien 557
	static public function harmoniserChemin($chemin) {
558
		$chemin = self::startsWith($chemin,'/') ? $chemin : '/'.$chemin;
559
		$chemin = self::endsWith($chemin,'/') ? $chemin : $chemin.'/';
2101 jpm 560
		$chemin = str_replace('//', '/', $chemin);
2149 aurelien 561
		// mise en minuscule du chemin afin d'éviter des cas où l'on aurait
562
		// des même mots clés avec minuscule et majuscule
563
		$chemin = strtolower($chemin);
2197 mathias 564
		$chemin = self::supprimerAccents($chemin);
2101 jpm 565
		return $chemin;
2026 aurelien 566
	}
2197 mathias 567
 
568
	function supprimerAccents($str, $charset='utf-8')
569
	{
570
		$str = htmlentities($str, ENT_NOQUOTES, $charset);
571
 
572
		$str = preg_replace('#&([A-za-z])(?:acute|cedil|circ|grave|orn|ring|slash|th|tilde|uml);#', '\1', $str);
573
		$str = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $str); // pour les ligatures e.g. '&oelig;'
574
		$str = preg_replace('#&[^;]+;#', '', $str); // supprime les autres caractères
575
 
576
		return $str;
577
	}
2101 jpm 578
 
2143 jpm 579
	/**
2101 jpm 580
	 * Fonction de slugification du mot clé
2143 jpm 581
	 *
2101 jpm 582
	 * Ni slashes ou antislashes ou virgules (ce qui fausserait l'arbre ou bien les mots
583
	 * clés texte dans les tables obs ou image)
584
	 */
585
	static public function simplifier($text) {
586
		$caracteresASupprimer = array('\\','/', ',');
587
		$text = str_replace($caracteresASupprimer, '', $text);
2167 aurelien 588
		$text = trim($text);
2101 jpm 589
		return $text;
2025 aurelien 590
	}
2101 jpm 591
 
2143 jpm 592
	/**
2101 jpm 593
	 * Gardée pour compatibilité ancienne version (mais devrait être supprimée
594
	 * dans le futur
595
	 */
2060 aurelien 596
	static function nettoyerMotsClesAvantSuppression($chaine) {
597
		$valeur = str_replace('null', '', $chaine);
598
		$valeur = trim($valeur, ';;');
599
		return $valeur;
600
	}
2101 jpm 601
 
2026 aurelien 602
	static public function startsWith($haystack, $needle) {
2101 jpm 603
		return $needle === '' || strpos($haystack, $needle) === 0;
2026 aurelien 604
	}
2101 jpm 605
 
2026 aurelien 606
	static public function endsWith($haystack, $needle) {
2101 jpm 607
		return $needle === '' || substr($haystack, -strlen($needle)) === $needle;
2026 aurelien 608
	}
2101 jpm 609
 
2060 aurelien 610
	/**
611
	* Fonction utilisée pour importer les anciens mots clés saisis dans les widget dans un compte identifié
612
	* Dans ce cas là, le widget remplit la case id_utilisateur par le mail indiqué lors de la saisie
613
	* @param string $mail_utilisateur
614
	* @param string $id_utilisateur
615
	*/
616
	public static function migrerMotsClesMailVersId($mail_utilisateur, $infos_utilisateur) {
617
		return self::migrerLiaisonEtMotsCles($mail_utilisateur, $infos_utilisateur, 'obs') &&
618
				self::migrerLiaisonEtMotsCles($mail_utilisateur, $infos_utilisateur, 'images');
619
	}
2101 jpm 620
 
621
	/**
622
	 * ATTENTION : cette fonction suppose que l'utilisateur n'ai pas déjà de mots clés dans le CEL
623
	 * avec l'identifiant $id_utilisateur ce qui est normalement le cas
624
	 * ça devrait normalement marcher correctement même s'il en a déjà mais ça n'a pas été testé
625
	 */
626
	private static function migrerLiaisonEtMotsCles($email_utilisateur, $infos_utilisateur, $mode) {
2060 aurelien 627
		list($table_liaisons, $table_mots_cles) = self::getTablesMotsClesEtLiaisons($mode);
2101 jpm 628
		$idUtilisateurP = Cel::db()->proteger($infos_utilisateur['id_utilisateur']);
629
		$emailUtilisateurP = Cel::db()->proteger($email_utilisateur);
2143 jpm 630
 
2101 jpm 631
		$requete_migration_mc = "UPDATE {$table_mots_cles} ".
632
			"SET id_utilisateur = $idUtilisateurP ".
633
			"WHERE id_utilisateur = $emailUtilisateurP ";
634
 
2143 jpm 635
		$migration = Cel::db()->executer($requete_migration_mc);
2101 jpm 636
		$migration = ($migration !== false) ? true : false;
637
		return $migration;
2060 aurelien 638
	}
2025 aurelien 639
}
2101 jpm 640
?>