Subversion Repositories eFlore/Applications.cel

Rev

Rev 3504 | Rev 3523 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3504 Rev 3506
1
<?php
1
<?php
2
// declare(encoding='UTF-8');
2
// declare(encoding='UTF-8');
3
/**
3
/**
4
 * Classe de liaison d'images et d'observation à des mots clés en utilisant la méthode path enumeration.
4
 * Classe de liaison d'images et d'observation à des mots clés en utilisant la méthode path enumeration.
5
 *
5
 *
6
 * @internal   Mininum PHP version : 5.2
6
 * @internal   Mininum PHP version : 5.2
7
 * @category   CEL
7
 * @category   CEL
8
 * @package    Services
8
 * @package    Services
9
 * @subpackage Bibliothèques
9
 * @subpackage Bibliothèques
10
 * @version    0.1
10
 * @version    0.1
11
 * @author     Mathias CHOUET <mathias@tela-botanica.org>
11
 * @author     Mathias CHOUET <mathias@tela-botanica.org>
12
 * @author     Jean-Pascal MILCENT <jpm@tela-botanica.org>
12
 * @author     Jean-Pascal MILCENT <jpm@tela-botanica.org>
13
 * @author     Aurelien PERONNET <aurelien@tela-botanica.org>
13
 * @author     Aurelien PERONNET <aurelien@tela-botanica.org>
14
 * @license    GPL v3 <http://www.gnu.org/licenses/gpl.txt>
14
 * @license    GPL v3 <http://www.gnu.org/licenses/gpl.txt>
15
 * @license    CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
15
 * @license    CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
16
 * @copyright  1999-2014 Tela Botanica <accueil@tela-botanica.org>
16
 * @copyright  1999-2014 Tela Botanica <accueil@tela-botanica.org>
17
 */
17
 */
18
class GestionMotsClesChemin {
18
class GestionMotsClesChemin {
19
 
19
 
20
	private $config;
20
	private $config;
21
	private $mode;
21
	private $mode;
22
 
22
 
23
	private $table_liaison;
23
	private $table_liaison;
24
	private $table_mots_cles;
24
	private $table_mots_cles;
25
	private $id_mot_cle;
25
	private $id_mot_cle;
26
	private $id_element_lie;
26
	private $id_element_lie;
27
 
27
 
28
	//TODO: trigger pour les tables liaisons
28
	//TODO: trigger pour les tables liaisons
29
 
29
 
30
	public function __construct($config, $mode = 'obs') {
30
	public function __construct($config, $mode = 'obs') {
31
		$this->config = $config;
31
		$this->config = $config;
32
		//TODO: switch suivant mode
32
		//TODO: switch suivant mode
33
		$this->mode = $mode;
33
		$this->mode = $mode;
34
 
34
 
35
		list($this->table_liaison, $this->table_mots_cles, $this->id_mot_cle, $this->id_element_lie) = self::getTablesMotsClesEtLiaisons($mode);
35
		list($this->table_liaison, $this->table_mots_cles, $this->id_mot_cle, $this->id_element_lie) = self::getTablesMotsClesEtLiaisons($mode);
36
	}
36
	}
37
 
37
 
38
 
38
 
39
 
39
 
40
	public function obtenirIdsMotsClesParIdParent($user_id, $id_mot_cle) {
40
	public function obtenirIdsMotsClesParIdParent($user_id, $id_mot_cle) {
41
		$idMotCleP = Cel::db()->proteger($id_mot_cle);
41
		$idMotCleP = Cel::db()->proteger($id_mot_cle);
42
		$idUtilisateurP = Cel::db()->proteger($user_id);
42
		$idUtilisateurP = Cel::db()->proteger($user_id);
43
 
43
 
44
		$sousRequete = "SELECT path FROM {$this->table_mots_cles} WHERE $this->id_mot_cle = $idMotCleP ";
44
		$sousRequete = "SELECT path FROM {$this->table_mots_cles} WHERE $this->id_mot_cle = $idMotCleP ";
45
		$requete = "SELECT {$this->id_mot_cle} ".
45
		$requete = "SELECT {$this->id_mot_cle} ".
46
			"FROM {$this->table_mots_cles} ".
46
			"FROM {$this->table_mots_cles} ".
47
			"WHERE path LIKE CONCAT(($sousRequete), '%') ".
47
			"WHERE path LIKE CONCAT(($sousRequete), '%') ".
48
			"AND user_id = $idUtilisateurP ".
48
			"AND user_id = $idUtilisateurP ".
49
			' -- '.__FILE__.':'.__LINE__;
49
			' -- '.__FILE__.':'.__LINE__;
50
		return Cel::db()->requeter($requete);
50
		return Cel::db()->requeter($requete);
51
	}
51
	}
52
 
52
 
53
	/**
53
	/**
54
	 * Retourne la liste des mots clés pour l'élément lié fourni. Ne tient pas compte de l'utilisateur
54
	 * Retourne la liste des mots clés pour l'élément lié fourni. Ne tient pas compte de l'utilisateur
55
	 * car seul le propriétaire d'un élément lié peut y lier des mots clés
55
	 * car seul le propriétaire d'un élément lié peut y lier des mots clés
56
	 */
56
	 */
57
	public function obtenirIdsMotsClesParIdElementLie($id_element_lie) {
57
	public function obtenirIdsMotsClesParIdElementLie($id_element_lie) {
58
		$idElementLieP = Cel::db()->proteger($id_element_lie);
58
		$idElementLieP = Cel::db()->proteger($id_element_lie);
59
 
59
 
60
		$requete = "SELECT {$this->id_mot_cle} FROM {$this->table_liaison} ".
60
		$requete = "SELECT {$this->id_mot_cle} FROM {$this->table_liaison} ".
61
			"WHERE {$this->id_element_lie} = $idElementLieP ".
61
			"WHERE {$this->id_element_lie} = $idElementLieP ".
62
			' -- '.__FILE__.':'.__LINE__;
62
			' -- '.__FILE__.':'.__LINE__;
63
		return Cel::db()->requeter($requete);
63
		return Cel::db()->requeter($requete);
64
	}
64
	}
65
 
65
 
66
	public function insererParCheminSiInexistant($mot_cle, $chemin_parent, $user_id) {
66
	public function insererParCheminSiInexistant($mot_cle, $chemin_parent, $user_id) {
67
		$mot_cle = self::simplifier($mot_cle);
67
		$mot_cle = self::simplifier($mot_cle);
68
		$cheminMotCle = self::getCheminHarmonise($chemin_parent, $mot_cle);
68
		$cheminMotCle = self::getCheminHarmonise($chemin_parent, $mot_cle);
69
		$cheminMotCleP = Cel::db()->proteger($cheminMotCle);
69
		$cheminMotCleP = Cel::db()->proteger($cheminMotCle);
70
		$idUtilisateurP = Cel::db()->proteger($user_id);
70
		$idUtilisateurP = Cel::db()->proteger($user_id);
71
 
71
 
72
		$requete = "SELECT {$this->id_mot_cle} ".
72
		$requete = "SELECT {$this->id_mot_cle} ".
73
			"FROM {$this->table_mots_cles} ".
73
			"FROM {$this->table_mots_cles} ".
74
			"WHERE path = $cheminMotCleP ".
74
			"WHERE path = $cheminMotCleP ".
75
			"AND user_id = $idUtilisateurP ".
75
			"AND user_id = $idUtilisateurP ".
76
			' -- '.__FILE__.':'.__LINE__;
76
			' -- '.__FILE__.':'.__LINE__;
77
		$infosMotCle = Cel::db()->requeter($requete);
77
		$infosMotCle = Cel::db()->requeter($requete);
78
 
78
 
79
		if (!empty($infosMotCle)) {
79
		if (!empty($infosMotCle)) {
80
			$idMotCle = $infosMotCle[0]['id_mot_cle'];
80
			$idMotCle = $infosMotCle[0]['id_mot_cle'];
81
		} else {
81
		} else {
82
			$idMotCle = $this->insererParChemin($mot_cle, $chemin_parent, $user_id);
82
			$idMotCle = $this->insererParChemin($mot_cle, $chemin_parent, $user_id);
83
		}
83
		}
84
		return $idMotCle;
84
		return $idMotCle;
85
	}
85
	}
86
 
86
 
87
	public function insererParChemin($mot_cle, $chemin_parent, $user_id) {
87
	public function insererParChemin($mot_cle, $chemin_parent, $user_id) {
88
		$mot_cle = self::simplifier($mot_cle);
88
		$mot_cle = self::simplifier($mot_cle);
89
		$cheminMotCle = self::getCheminHarmonise($chemin_parent, $mot_cle);
89
		$cheminMotCle = self::getCheminHarmonise($chemin_parent, $mot_cle);
90
		$cheminMotCleP = Cel::db()->proteger($cheminMotCle);
90
		$cheminMotCleP = Cel::db()->proteger($cheminMotCle);
91
		$idUtilisateurP = Cel::db()->proteger($user_id);
91
		$idUtilisateurP = Cel::db()->proteger($user_id);
92
		$motCleP = Cel::db()->proteger($mot_cle);
92
		$motCleP = Cel::db()->proteger($mot_cle);
93
 
93
 
94
		$requete = "INSERT INTO {$this->table_mots_cles} ".
94
		$requete = "INSERT INTO {$this->table_mots_cles} ".
95
			'(path, user_id, name) '.
95
			'(path, user_id, name) '.
96
			"VALUES ($cheminMotCleP, $idUtilisateurP, $motCleP ) ".
96
			"VALUES ($cheminMotCleP, $idUtilisateurP, $motCleP ) ".
97
			' -- '.__FILE__.':'.__LINE__;
97
			' -- '.__FILE__.':'.__LINE__;
98
		$insertion = Cel::db()->executer($requete);
98
		$insertion = Cel::db()->executer($requete);
99
 
99
 
100
		$resultat = false;
100
		$resultat = false;
101
		if ($insertion !== false) {
101
		if ($insertion !== false) {
102
			$resultat = Cel::db()->obtenirDernierId();
102
			$resultat = Cel::db()->obtenirDernierId();
103
		}
103
		}
104
		return $resultat;
104
		return $resultat;
105
	}
105
	}
106
 
106
 
107
	public function insererParIdParent($mot_cle, $id_parent, $user_id) {
107
	public function insererParIdParent($mot_cle, $id_parent, $user_id) {
108
		$motCleSimple = self::simplifier($mot_cle);
108
		$motCleSimple = self::simplifier($mot_cle);
109
		$motCleSimpleP = Cel::db()->proteger(strtolower(self::supprimerAccents($mot_cle)));
109
		$motCleSimpleP = Cel::db()->proteger(strtolower(self::supprimerAccents($mot_cle)));
110
		$idParentP = Cel::db()->proteger($id_parent);
110
		$idParentP = Cel::db()->proteger($id_parent);
111
		$racineP = Cel::db()->proteger('/');
111
		$racineP = Cel::db()->proteger('/');
112
		$idUtilisateurP = Cel::db()->proteger($user_id);
112
		$idUtilisateurP = Cel::db()->proteger($user_id);
113
		$motCleP = Cel::db()->proteger($mot_cle);
113
		$motCleP = Cel::db()->proteger($mot_cle);
114
 
114
 
115
		$sousRequete = $racineP;
115
		$sousRequete = $racineP;
116
		if ($id_parent != '') {
116
		if ($id_parent != '') {
117
			$sousRequete = '(SELECT path '.
117
			$sousRequete = '(SELECT path '.
118
				"FROM {$this->table_mots_cles} AS ctp ".
118
				"FROM {$this->table_mots_cles} AS ctp ".
119
				"WHERE ctp.id = $idParentP) ";
119
				"WHERE ctp.id = $idParentP) ";
120
		}
120
		}
121
 
121
 
122
		$requete = "INSERT INTO {$this->table_mots_cles} (path, user_id, name) ".
122
		$requete = "INSERT INTO {$this->table_mots_cles} (path, user_id, name) ".
123
			"VALUES (CONCAT($sousRequete, $motCleSimpleP, '/'), $idUtilisateurP, $motCleP ) ".
123
			"VALUES (CONCAT($sousRequete, $motCleSimpleP, '/'), $idUtilisateurP, $motCleP ) ".
124
			' -- '.__FILE__.':'.__LINE__;
124
			' -- '.__FILE__.':'.__LINE__;
125
		$insertion = Cel::db()->executer($requete);
125
		$insertion = Cel::db()->executer($requete);
126
 
126
 
127
		if ($insertion !== false) {
127
		if ($insertion !== false) {
128
			$resultat = Cel::db()->obtenirDernierId();
128
			$resultat = Cel::db()->obtenirDernierId();
129
		}
129
		}
130
		return $resultat;
130
		return $resultat;
131
	}
131
	}
132
 
132
 
133
 
133
 
134
	public function lierParTableaux($ids_mots_cles, $ids_elements_lies) {
134
	public function lierParTableaux($ids_mots_cles, $ids_elements_lies) {
135
		$combinaisons = array();
135
		$combinaisons = array();
136
		foreach ($ids_mots_cles as $id_mot_cle) {
136
		foreach ($ids_mots_cles as $id_mot_cle) {
137
			$idMotCleP = Cel::db()->proteger($id_mot_cle);
137
			$idMotCleP = Cel::db()->proteger($id_mot_cle);
138
			foreach ($ids_elements_lies as $id_element_lie) {
138
			foreach ($ids_elements_lies as $id_element_lie) {
139
				$idElementLieP = Cel::db()->proteger($id_element_lie);
139
				$idElementLieP = Cel::db()->proteger($id_element_lie);
140
				$combinaisons[] = "($idElementLieP, $idMotCleP)";
140
				$combinaisons[] = "($idElementLieP, $idMotCleP)";
141
			}
141
			}
142
		}
142
		}
143
 
143
 
144
		$valeursGroupees = implode(', ', $combinaisons);
144
		$valeursGroupees = implode(', ', $combinaisons);
145
		$requete = "INSERT INTO {$this->table_liaison} ({$this->id_element_lie}, {$this->id_mot_cle}) ".
145
		$requete = "INSERT INTO {$this->table_liaison} ({$this->id_element_lie}, {$this->id_mot_cle}) ".
146
			"VALUES $valeursGroupees ".
146
			"VALUES $valeursGroupees ".
147
			"ON DUPLICATE KEY UPDATE {$this->id_element_lie}=VALUES(`id_element_lie`), {$this->id_mot_cle}=VALUES(`id_mot_cle`) ".
147
			"ON DUPLICATE KEY UPDATE {$this->id_element_lie}=VALUES(`id_element_lie`), {$this->id_mot_cle}=VALUES(`id_mot_cle`) ".
148
			' -- '.__FILE__.':'.__LINE__;
148
			' -- '.__FILE__.':'.__LINE__;
149
		return Cel::db()->executer($requete);
149
		return Cel::db()->executer($requete);
150
	}
150
	}
151
 
151
 
152
 
152
 
153
 
153
 
154
	public function supprimerLiaisonsMotsCles($ids_mots_cles, $ids_elements_lies, $user_id) {
154
	public function supprimerLiaisonsMotsCles($ids_mots_cles, $ids_elements_lies, $user_id) {
155
		$combinaisons = array();
155
		$combinaisons = array();
156
		foreach ($ids_mots_cles as $id_mot_cle) {
156
		foreach ($ids_mots_cles as $id_mot_cle) {
157
			$idMotCleP = Cel::db()->proteger($id_mot_cle);
157
			$idMotCleP = Cel::db()->proteger($id_mot_cle);
158
			foreach ($ids_elements_lies as $id_element_lie) {
158
			foreach ($ids_elements_lies as $id_element_lie) {
159
				$idElementLieP = Cel::db()->proteger($id_element_lie);
159
				$idElementLieP = Cel::db()->proteger($id_element_lie);
160
				$combinaisons[] = "({$this->id_element_lie} = $idElementLieP AND {$this->id_mot_cle} = $idMotCleP)";
160
				$combinaisons[] = "({$this->id_element_lie} = $idElementLieP AND {$this->id_mot_cle} = $idMotCleP)";
161
			}
161
			}
162
		}
162
		}
163
		$clauseWhere = implode(' OR ', $combinaisons);
163
		$clauseWhere = implode(' OR ', $combinaisons);
164
 
164
 
165
		$requete = "DELETE FROM {$this->table_liaison} ".
165
		$requete = "DELETE FROM {$this->table_liaison} ".
166
			"WHERE $clauseWhere ".
166
			"WHERE $clauseWhere ".
167
			' -- '.__FILE__.':'.__LINE__;
167
			' -- '.__FILE__.':'.__LINE__;
168
		return Cel::db()->executer($requete);
168
		return Cel::db()->executer($requete);
169
	}
169
	}
170
 
170
 
171
	public function supprimerToutesLiaisonsPourIdsElementsLies($ids_elements_lies) {
171
	public function supprimerToutesLiaisonsPourIdsElementsLies($ids_elements_lies) {
172
		$idsElementsLiesP = Cel::db()->proteger($ids_elements_lies);
172
		$idsElementsLiesP = Cel::db()->proteger($ids_elements_lies);
173
		$listeIds = implode(',', $idsElementsLiesP);
173
		$listeIds = implode(',', $idsElementsLiesP);
174
 
174
 
175
		$requete = "DELETE FROM {$this->table_liaison} ".
175
		$requete = "DELETE FROM {$this->table_liaison} ".
176
			"WHERE {$this->id_element_lie} IN ($listeIds) ".
176
			"WHERE {$this->id_element_lie} IN ($listeIds) ".
177
			' -- '.__FILE__.':'.__LINE__;
177
			' -- '.__FILE__.':'.__LINE__;
178
 
178
 
179
		$suppression = Cel::db()->executer($requete);
179
		$suppression = Cel::db()->executer($requete);
180
		$suppression = ($suppression !== false) ? true : false;
180
		$suppression = ($suppression !== false) ? true : false;
181
		return $suppression;
181
		return $suppression;
182
	}
182
	}
183
 
183
 
184
	public function supprimerToutesLiaisonsIdsMotsCles($ids_mots_cles, $user_id) {
184
	public function supprimerToutesLiaisonsIdsMotsCles($ids_mots_cles, $user_id) {
185
		$suppression = true;
185
		$suppression = true;
186
		if (!empty($ids_mots_cles)) {
186
		if (!empty($ids_mots_cles)) {
187
			$idsMotsClesP = Cel::db()->proteger($ids_mots_cles);
187
			$idsMotsClesP = Cel::db()->proteger($ids_mots_cles);
188
			$listeIds = implode(',', $idsMotsClesP);
188
			$listeIds = implode(',', $idsMotsClesP);
189
 
189
 
190
			$requete = "DELETE FROM {$this->table_liaison} ".
190
			$requete = "DELETE FROM {$this->table_liaison} ".
191
				"WHERE {$this->id_mot_cle} IN ($listeIds) ".
191
				"WHERE {$this->id_mot_cle} IN ($listeIds) ".
192
				' -- '.__FILE__.':'.__LINE__;
192
				' -- '.__FILE__.':'.__LINE__;
193
 
193
 
194
			$suppression = Cel::db()->executer($requete);
194
			$suppression = Cel::db()->executer($requete);
195
			$suppression = ($suppression !== false) ? true : false;
195
			$suppression = ($suppression !== false) ? true : false;
196
		}
196
		}
197
		return $suppression;
197
		return $suppression;
198
	}
198
	}
199
 
199
 
200
	/**
200
	/**
201
	 * Supprime toutes les laisons pour un utilisateur et un mot clé (au sens textuel) donnés.
201
	 * Supprime toutes les laisons pour un utilisateur et un mot clé (au sens textuel) donnés.
202
	 *
202
	 *
203
	 */
203
	 */
204
	public function supprimerLiaisonPourMotCleEtIdElementLie($mot_cle, $id_element_lie, $user_id) {
204
	public function supprimerLiaisonPourMotCleEtIdElementLie($mot_cle, $id_element_lie, $user_id) {
205
		$mot_cle = self::simplifier($mot_cle);
205
		$mot_cle = self::simplifier($mot_cle);
206
		$idElementLieP = Cel::db()->proteger($id_element_lie);
206
		$idElementLieP = Cel::db()->proteger($id_element_lie);
207
		$motCleP = Cel::db()->proteger($mot_cle);
207
		$motCleP = Cel::db()->proteger($mot_cle);
208
		$idUtilisateurP = Cel::db()->proteger($user_id);
208
		$idUtilisateurP = Cel::db()->proteger($user_id);
209
 
209
 
210
		$sousRequete = "SELECT id FROM {$this->table_mots_cles} ".
210
		$sousRequete = "SELECT id FROM {$this->table_mots_cles} ".
211
			"WHERE name = $motCleP ".
211
			"WHERE name = $motCleP ".
212
			"AND userId = $idUtilisateurP ";
212
			"AND user_id = $idUtilisateurP ";
213
		$requete = "DELETE FROM {$this->table_liaison} ".
213
		$requete = "DELETE FROM {$this->table_liaison} ".
214
			"WHERE {$this->id_element_lie} = $idElementLieP ".
214
			"WHERE {$this->id_element_lie} = $idElementLieP ".
215
			"AND {$this->id_mot_cle} IN ($sousRequete) ".
215
			"AND {$this->id_mot_cle} IN ($sousRequete) ".
216
			' -- '.__FILE__.':'.__LINE__;
216
			' -- '.__FILE__.':'.__LINE__;
217
 
217
 
218
		$suppression_liaison = Cel::db()->executer($requete);
218
		$suppression_liaison = Cel::db()->executer($requete);
219
		$suppression_liaison = ($suppression_liaison !== false);
219
		$suppression_liaison = ($suppression_liaison !== false);
220
 
220
 
221
		return $suppression_liaison;
221
		return $suppression_liaison;
222
	}
222
	}
223
 
223
 
224
 
224
 
225
	public function supprimerChemin($chemin, $user_id) {
225
	public function supprimerChemin($chemin, $user_id) {
226
		$idUtilisateurP = Cel::db()->proteger($user_id);
226
		$idUtilisateurP = Cel::db()->proteger($user_id);
227
		$cheminP = Cel::db()->proteger($chemin.'%');
227
		$cheminP = Cel::db()->proteger($chemin.'%');
228
		// TODO : triggers pour les tables liées ?
228
		// TODO : triggers pour les tables liées ?
229
		$requete = "DELETE FROM {$this->$table_mots_cles} ".
229
		$requete = "DELETE FROM {$this->$table_mots_cles} ".
230
			"WHERE path LIKE $cheminP ".
230
			"WHERE path LIKE $cheminP ".
231
			"AND user_id = $idUtilisateurP ".
231
			"AND user_id = $idUtilisateurP ".
232
			' -- '.__FILE__.':'.__LINE__;
232
			' -- '.__FILE__.':'.__LINE__;
233
 
233
 
234
		return Cel::db()->executer($requete);
234
		return Cel::db()->executer($requete);
235
	}
235
	}
236
 
236
 
237
	/**
237
	/**
238
	 * suppression des associations du mots clé aux images ou obs, mais aussi des associations de ses enfants
238
	 * suppression des associations du mots clé aux images ou obs, mais aussi des associations de ses enfants
239
	 * (car ceux-ci seront supprimés aussi dans le processus)
239
	 * (car ceux-ci seront supprimés aussi dans le processus)
240
	 * même s'il n'a pas d'enfants, le tableau contient au moins l'id du mot clé lui même
240
	 * même s'il n'a pas d'enfants, le tableau contient au moins l'id du mot clé lui même
241
	 */
241
	 */
242
	public function supprimerMotCleParId($id_mot_cle, $user_id) {
242
	public function supprimerMotCleParId($id_mot_cle, $user_id) {
243
		//TODO: simplifier cette fonction
243
		//TODO: simplifier cette fonction
244
		$ids_mot_cle_et_enfants = $this->obtenirIdsMotsClesParIdParent($user_id, $id_mot_cle);
244
		$ids_mot_cle_et_enfants = $this->obtenirIdsMotsClesParIdParent($user_id, $id_mot_cle);
245
 
245
 
246
		// obtention des ids des éléments liés au mot clé ainsi qu'à ces enfants (afin de pouvoir
246
		// obtention des ids des éléments liés au mot clé ainsi qu'à ces enfants (afin de pouvoir
247
		// régénérer les index texte de mots clés sur les éléments liés)
247
		// régénérer les index texte de mots clés sur les éléments liés)
248
		$ids_a_delier = array();
248
		$ids_a_delier = array();
249
		foreach ($ids_mot_cle_et_enfants as $id) {
249
		foreach ($ids_mot_cle_et_enfants as $id) {
250
			$ids_a_delier[] = $id['id_mot_cle'];
250
			$ids_a_delier[] = $id['id_mot_cle'];
251
		}
251
		}
252
 
252
 
253
		$ids_elements_lies = $this->obtenirIdElementsLiesPourIds($ids_a_delier);
253
		$ids_elements_lies = $this->obtenirIdElementsLiesPourIds($ids_a_delier);
254
		$suppression_liaison = $this->supprimerToutesLiaisonsIdsMotsCles($ids_a_delier, $user_id);
254
		$suppression_liaison = $this->supprimerToutesLiaisonsIdsMotsCles($ids_a_delier, $user_id);
255
 
255
 
256
		foreach ($ids_elements_lies as $id_element_lie) {
256
		foreach ($ids_elements_lies as $id_element_lie) {
257
			self::regenererIndexTexteMotCle($id_element_lie['id_element_lie'], $this->mode);
257
			self::regenererIndexTexteMotCle($id_element_lie['id_element_lie'], $this->mode);
258
		}
258
		}
259
 
259
 
260
		// suppression du mot clé proprement dit ainsi que de ses enfants
260
		// suppression du mot clé proprement dit ainsi que de ses enfants
261
		$suppression = $this->supprimerMotCleEtEnfantsParId($id_mot_cle, $user_id);
261
		$suppression = $this->supprimerMotCleEtEnfantsParId($id_mot_cle, $user_id);
262
 
262
 
263
		return $suppression && $suppression_liaison;
263
		return $suppression && $suppression_liaison;
264
	}
264
	}
265
 
265
 
266
	public function supprimerMotCleEtEnfantsParId($id_mot_cle, $user_id) {
266
	public function supprimerMotCleEtEnfantsParId($id_mot_cle, $user_id) {
267
		$idMotCleP = Cel::db()->proteger($id_mot_cle);
267
		$idMotCleP = Cel::db()->proteger($id_mot_cle);
268
		$requete = 'SELECT path '.
268
		$requete = 'SELECT path '.
269
			"FROM {$this->table_mots_cles} ".
269
			"FROM {$this->table_mots_cles} ".
270
			"WHERE id = $idMotCleP ".
270
			"WHERE id = $idMotCleP ".
271
			' -- '.__FILE__.':'.__LINE__;
271
			' -- '.__FILE__.':'.__LINE__;
272
		$chemin = Cel::db()->requeter($requete);
272
		$chemin = Cel::db()->requeter($requete);
273
 
273
 
274
		$suppression = true;
274
		$suppression = true;
275
		// vérification pour empecher la suppression accidentelle de tout l'arbre,
275
		// vérification pour empecher la suppression accidentelle de tout l'arbre,
276
		// cas qui ne devrait jamais arriver normalement
276
		// cas qui ne devrait jamais arriver normalement
277
		if (!empty($chemin) && $chemin != '/') {
277
		if (!empty($chemin) && $chemin != '/') {
278
			$chemin = $chemin[0]['chemin'];
278
			$chemin = $chemin[0]['chemin'];
279
			$cheminP = Cel::db()->proteger($chemin.'%');
279
			$cheminP = Cel::db()->proteger($chemin.'%');
280
			$idUtilisateurP = Cel::db()->proteger($user_id);
280
			$idUtilisateurP = Cel::db()->proteger($user_id);
281
 
281
 
282
			$requete = "DELETE FROM {$this->table_mots_cles} ".
282
			$requete = "DELETE FROM {$this->table_mots_cles} ".
283
				"WHERE path LIKE $cheminP ".
283
				"WHERE path LIKE $cheminP ".
284
				"AND user_id = $idUtilisateurP ".
284
				"AND user_id = $idUtilisateurP ".
285
				' -- '.__FILE__.':'.__LINE__;;
285
				' -- '.__FILE__.':'.__LINE__;;
286
 
286
 
287
			$suppression = Cel::db()->executer($requete);
287
			$suppression = Cel::db()->executer($requete);
288
		}
288
		}
289
 
289
 
290
		return ($suppression !== false);
290
		return ($suppression !== false);
291
 
291
 
292
	}
292
	}
293
 
293
 
294
	public function obtenirIdsMotClesPourMotsCles($mots_cles, $user_id) {
294
	public function obtenirIdsMotClesPourMotsCles($mots_cles, $user_id) {
295
		$motsClesP = array();
295
		$motsClesP = array();
296
		foreach ($mots_cles as $mot_cle) {
296
		foreach ($mots_cles as $mot_cle) {
297
			$motsClesP[] = Cel::db()->proteger(self::simplifier($mot_cle));
297
			$motsClesP[] = Cel::db()->proteger(self::simplifier($mot_cle));
298
		}
298
		}
299
		$listeMotsClesP = implode(',', $motsClesP);
299
		$listeMotsClesP = implode(',', $motsClesP);
300
		$idUtilisateurP = Cel::db()->proteger($user_id);
300
		$idUtilisateurP = Cel::db()->proteger($user_id);
301
 
301
 
302
		$requete = 'SELECT id as id_mot_cle, name as mot_cle '.
302
		$requete = 'SELECT id as id_mot_cle, name as mot_cle '.
303
			"FROM {$this->table_mots_cles} ".
303
			"FROM {$this->table_mots_cles} ".
304
			"WHERE mot_cle IN ($listeMotsClesP) ".
304
			"WHERE mot_cle IN ($listeMotsClesP) ".
305
			"AND user_id = $idUtilisateurP ".
305
			"AND user_id = $idUtilisateurP ".
306
			' -- '.__FILE__.':'.__LINE__;
306
			' -- '.__FILE__.':'.__LINE__;
307
 
307
 
308
		$resultat = Cel::db()->executerRequete($requete);
308
		$resultat = Cel::db()->executerRequete($requete);
309
		return $resultat;
309
		return $resultat;
310
	}
310
	}
311
 
311
 
312
 
312
 
313
 
313
 
314
	public function obtenirIdElementsLiesPourIds($ids_mots_cles) {
314
	public function obtenirIdElementsLiesPourIds($ids_mots_cles) {
315
		$idsElementsLies = array();
315
		$idsElementsLies = array();
316
		if (!empty($ids_mots_cles)) {
316
		if (!empty($ids_mots_cles)) {
317
			$idsMotsClesP = Cel::db()->proteger($ids_mots_cles);
317
			$idsMotsClesP = Cel::db()->proteger($ids_mots_cles);
318
			$listeIdsMotsCles = implode(',', $idsMotsClesP);
318
			$listeIdsMotsCles = implode(',', $idsMotsClesP);
319
 
319
 
320
			$requete = "SELECT {$this->id_element_lie} as id_element_lie ".
320
			$requete = "SELECT {$this->id_element_lie} as id_element_lie ".
321
				"FROM {$this->table_liaison} ".
321
				"FROM {$this->table_liaison} ".
322
				"WHERE {$this->id_mot_cle} IN ($listeIdsMotsCles) ".
322
				"WHERE {$this->id_mot_cle} IN ($listeIdsMotsCles) ".
323
				' -- '.__FILE__.':'.__LINE__;
323
				' -- '.__FILE__.':'.__LINE__;
324
 
324
 
325
 
325
 
326
			$idsElementsLies = Cel::db()->requeter($requete);
326
			$idsElementsLies = Cel::db()->requeter($requete);
327
		}
327
		}
328
		return $idsElementsLies;
328
		return $idsElementsLies;
329
	}
329
	}
330
 
330
 
331
	/**
331
	/**
332
	 *
332
	 *
333
	 * Fonctions statiques utilitaires
333
	 * Fonctions statiques utilitaires
334
	 * (Dans l'idéal toute la classe pourrait être statique car elle n'a
334
	 * (Dans l'idéal toute la classe pourrait être statique car elle n'a
335
	 * pas d'état (mais il faudrait passer $mode à toutes les fonctions)
335
	 * pas d'état (mais il faudrait passer $mode à toutes les fonctions)
336
	 *
336
	 *
337
	 */
337
	 */
338
	public static function getTablesMotsClesEtLiaisons($mode) {
338
	public static function getTablesMotsClesEtLiaisons($mode) {
339
		if ($mode == 'obs') {
339
		if ($mode == 'obs') {
340
			$table_liaison = 'occurrence_user_occurrence_tag';
340
			$table_liaison = 'occurrence_user_occurrence_tag';
341
			$table_mots_cles = 'user_occurrence_tag';
341
			$table_mots_cles = 'user_occurrence_tag';
342
			$id_mot_cle = "user_occurrence_tag_id";
342
			$id_mot_cle = "user_occurrence_tag_id";
343
			$id_element_lie = "occurrence_id";
343
			$id_element_lie = "occurrence_id";
344
		} else {
344
		} else {
345
			$table_liaison = 'photo_tag_photo';
345
			$table_liaison = 'photo_tag_photo';
346
			$table_mots_cles = 'photo_tag';
346
			$table_mots_cles = 'photo_tag';
347
			$id_mot_cle = "photo_tag_id";
347
			$id_mot_cle = "photo_tag_id";
348
			$id_element_lie = "photo_id";
348
			$id_element_lie = "photo_id";
349
		}
349
		}
350
		return array($table_liaison, $table_mots_cles, $id_mot_cle, $id_element_lie);
350
		return array($table_liaison, $table_mots_cles, $id_mot_cle, $id_element_lie);
351
	}
351
	}
352
	/**
352
	/**
353
	 * Renvoie un template de recherche sur les ids de mots clés utilisables avec sprintf.
353
	 * Renvoie un template de recherche sur les ids de mots clés utilisables avec sprintf.
354
	 */
354
	 */
355
	public static function obtenirTemplateRequeteMotsClesIds($mode) {
355
	public static function obtenirTemplateRequeteMotsClesIds($mode) {
356
	    list($table_liaison, $table_mots_cles, $id_mot_cle, $id_element_lie) = self::getTablesMotsClesEtLiaisons($mode);
356
	    list($table_liaison, $table_mots_cles, $id_mot_cle, $id_element_lie) = self::getTablesMotsClesEtLiaisons($mode);
357
	    $requeteTpl = "SELECT $id_element_lie FROM $table_liaison WHERE $id_mot_cle IN (%s) ";
357
	    $requeteTpl = "SELECT $id_element_lie FROM $table_liaison WHERE $id_mot_cle IN (%s) ";
358
	    return $requeteTpl;
358
	    return $requeteTpl;
359
	}
359
	}
360
	/**
360
	/**
361
	 * Régénère le champ "mots_cles_texte" l'entité liée (image ou obs)
361
	 * Régénère le champ "mots_cles_texte" l'entité liée (image ou obs)
362
	 * et met à jour sa date de modification
362
	 * et met à jour sa date de modification
363
	 */
363
	 */
364
	public static function regenererIndexTexteMotCle($id_element_lie, $mode) {
364
	public static function regenererIndexTexteMotCle($id_element_lie, $mode) {
365
		$idElementLieP = Cel::db()->proteger($id_element_lie);
365
		$idElementLieP = Cel::db()->proteger($id_element_lie);
366
		$sqlTpl = self::obtenirTemplateRequeteMotsClesTexte($mode);
366
		$sqlTpl = self::obtenirTemplateRequeteMotsClesTexte($mode);
367
		$sousRequete = sprintf($sqlTpl, $idElementLieP);
367
		$sousRequete = sprintf($sqlTpl, $idElementLieP);
368
 
368
 
369
		list($table, $champId) = self::getNomTablesEtChampsElementsLies($mode);
369
		list($table, $champId) = self::getNomTablesEtChampsElementsLies($mode);
370
		$requete = "UPDATE $table ".
370
		$requete = "UPDATE $table ".
371
			"SET mots_cles_texte = ($sousRequete) ".
371
			"SET mots_cles_texte = ($sousRequete) ".
372
			", date_modification = NOW() ".
372
			", date_modification = NOW() ".
373
			"WHERE $champId = $idElementLieP ".
373
			"WHERE $champId = $idElementLieP ".
374
			' -- '.__FILE__.':'.__LINE__;
374
			' -- '.__FILE__.':'.__LINE__;
375
 
375
 
376
		return Cel::db()->executer($requete);
376
		return Cel::db()->executer($requete);
377
	}
377
	}
378
 
378
 
379
	private static function getNomTablesEtChampsElementsLies($mode) {
379
	private static function getNomTablesEtChampsElementsLies($mode) {
380
		$tables = array();
380
		$tables = array();
381
		if ($mode == 'obs') {
381
		if ($mode == 'obs') {
382
			$tables = array('occurrence', 'id');
382
			$tables = array('occurrence', 'id');
383
		} else {
383
		} else {
384
			$tables = array('photo', 'id');
384
			$tables = array('photo', 'id');
385
		}
385
		}
386
		return $tables;
386
		return $tables;
387
	}
387
	}
388
 
388
 
389
	/**
389
	/**
390
	 * Renvoie un template de requete pour selectionner la concatenation de mots clé
390
	 * Renvoie un template de requete pour selectionner la concatenation de mots clé
391
	 * pour un element donné (utilisable avec sprintf)
391
	 * pour un element donné (utilisable avec sprintf)
392
	 */
392
	 */
393
	public static function obtenirTemplateRequeteMotsClesTexte($mode) {
393
	public static function obtenirTemplateRequeteMotsClesTexte($mode) {
394
	    list($table_liaison, $table_mots_cles, $id_mot_cle, $id_element_lie) = self::getTablesMotsClesEtLiaisons($mode);
394
	    list($table_liaison, $table_mots_cles, $id_mot_cle, $id_element_lie) = self::getTablesMotsClesEtLiaisons($mode);
395
 
395
 
396
		$requeteTpl = 'SELECT GROUP_CONCAT(name) '.
396
		$requeteTpl = 'SELECT GROUP_CONCAT(name) '.
397
			"FROM $table_mots_cles AS cm ".
397
			"FROM $table_mots_cles AS cm ".
398
			"INNER JOIN $table_liaison AS cml ON cml.$id_mot_cle = cm.$id_mot_cle ".
398
			"INNER JOIN $table_liaison AS cml ON cml.$id_mot_cle = cm.$id_mot_cle ".
399
			"AND cml.$id_element_lie = %s ";
399
			"AND cml.$id_element_lie = %s ";
400
 
400
 
401
		return $requeteTpl;
401
		return $requeteTpl;
402
	}
402
	}
403
 
403
 
404
 
404
 
405
	// Méthodes utilitaires
405
	// Méthodes utilitaires
406
 
406
 
407
	/**
407
	/**
408
	 * La profondeur d'un noeud est déterminée par le nombre de slashs
408
	 * La profondeur d'un noeud est déterminée par le nombre de slashs
409
	 * qu'il contient (étant donné que ceux ci sont interdits dans le texte du mot clé.
409
	 * qu'il contient (étant donné que ceux ci sont interdits dans le texte du mot clé.
410
	 */
410
	 */
411
	static public function comparerProfNoeuds($a, $b) {
411
	static public function comparerProfNoeuds($a, $b) {
412
		$nb_slashs_a = substr_count($a['path'], '/');
412
		$nb_slashs_a = substr_count($a['path'], '/');
413
		$nb_slashs_b = substr_count($a['path'], '/');
413
		$nb_slashs_b = substr_count($a['path'], '/');
414
		$cmp = 0;
414
		$cmp = 0;
415
 
415
 
416
		if ($nb_slashs_a == $nb_slashs_b) {
416
		if ($nb_slashs_a == $nb_slashs_b) {
417
			$cmp = strcasecmp($a['path'], $b['path']);
417
			$cmp = strcasecmp($a['path'], $b['path']);
418
		} else {
418
		} else {
419
			$cmp = ($a['path'] > $b['path']) ? +1 : -1;
419
			$cmp = ($a['path'] > $b['path']) ? +1 : -1;
420
		}
420
		}
421
		return $cmp;
421
		return $cmp;
422
	}
422
	}
423
 
423
 
424
	static public function getCheminHarmonise($chemin_parent, $mot_cle) {
424
	static public function getCheminHarmonise($chemin_parent, $mot_cle) {
425
		return self::harmoniserChemin($chemin_parent.'/'.self::simplifier($mot_cle).'/');
425
		return self::harmoniserChemin($chemin_parent.'/'.self::simplifier($mot_cle).'/');
426
	}
426
	}
427
 
427
 
428
	static public function harmoniserChemin($chemin) {
428
	static public function harmoniserChemin($chemin) {
429
		$chemin = self::startsWith($chemin,'/') ? $chemin : '/'.$chemin;
429
		$chemin = self::startsWith($chemin,'/') ? $chemin : '/'.$chemin;
430
		$chemin = self::endsWith($chemin,'/') ? $chemin : $chemin.'/';
430
		$chemin = self::endsWith($chemin,'/') ? $chemin : $chemin.'/';
431
		$chemin = str_replace('//', '/', $chemin);
431
		$chemin = str_replace('//', '/', $chemin);
432
		// mise en minuscule du chemin afin d'éviter des cas où l'on aurait
432
		// mise en minuscule du chemin afin d'éviter des cas où l'on aurait
433
		// des même mots clés avec minuscule et majuscule
433
		// des même mots clés avec minuscule et majuscule
434
		$chemin = strtolower($chemin);
434
		$chemin = strtolower($chemin);
435
		$chemin = self::supprimerAccents($chemin);
435
		$chemin = self::supprimerAccents($chemin);
436
		return $chemin;
436
		return $chemin;
437
	}
437
	}
438
 
438
 
439
	static function supprimerAccents($str, $charset='utf-8') {
439
	static function supprimerAccents($str, $charset='utf-8') {
440
		$str = htmlentities($str, ENT_NOQUOTES, $charset);
440
		$str = htmlentities($str, ENT_NOQUOTES, $charset);
441
		$str = preg_replace('#&([A-za-z])(?:acute|cedil|circ|grave|orn|ring|slash|th|tilde|uml);#', '\1', $str);
441
		$str = preg_replace('#&([A-za-z])(?:acute|cedil|circ|grave|orn|ring|slash|th|tilde|uml);#', '\1', $str);
442
		$str = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $str); // pour les ligatures e.g. '&oelig;'
442
		$str = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $str); // pour les ligatures e.g. '&oelig;'
443
		$str = preg_replace('#&[^;]+;#', '', $str); // supprime les autres caractères
443
		$str = preg_replace('#&[^;]+;#', '', $str); // supprime les autres caractères
444
		return $str;
444
		return $str;
445
	}
445
	}
446
 
446
 
447
	/**
447
	/**
448
	 * Fonction de slugification du mot clé
448
	 * Fonction de slugification du mot clé
449
	 *
449
	 *
450
	 * Ni slashes ou antislashes ou virgules (ce qui fausserait l'arbre ou bien les mots
450
	 * Ni slashes ou antislashes ou virgules (ce qui fausserait l'arbre ou bien les mots
451
	 * clés texte dans les tables obs ou image)
451
	 * clés texte dans les tables obs ou image)
452
	 */
452
	 */
453
	static public function simplifier($text) {
453
	static public function simplifier($text) {
454
		$caracteresASupprimer = array('\\','/', ',');
454
		$caracteresASupprimer = array('\\','/', ',');
455
		$text = str_replace($caracteresASupprimer, '', $text);
455
		$text = str_replace($caracteresASupprimer, '', $text);
456
		$text = trim($text);
456
		$text = trim($text);
457
		return $text;
457
		return $text;
458
	}
458
	}
459
 
459
 
460
	/**
460
	/**
461
	 * Gardée pour compatibilité ancienne version (mais devrait être supprimée
461
	 * Gardée pour compatibilité ancienne version (mais devrait être supprimée
462
	 * dans le futur
462
	 * dans le futur
463
	 */
463
	 */
464
	static function nettoyerMotsClesAvantSuppression($chaine) {
464
	static function nettoyerMotsClesAvantSuppression($chaine) {
465
		$valeur = str_replace('null', '', $chaine);
465
		$valeur = str_replace('null', '', $chaine);
466
		$valeur = trim($valeur, ';;');
466
		$valeur = trim($valeur, ';;');
467
		return $valeur;
467
		return $valeur;
468
	}
468
	}
469
 
469
 
470
	public static function startsWith($haystack, $needle) {
470
	public static function startsWith($haystack, $needle) {
471
		return $needle === '' || strpos($haystack, $needle) === 0;
471
		return $needle === '' || strpos($haystack, $needle) === 0;
472
	}
472
	}
473
 
473
 
474
	public  static function endsWith($haystack, $needle) {
474
	public  static function endsWith($haystack, $needle) {
475
		return $needle === '' || substr($haystack, -strlen($needle)) === $needle;
475
		return $needle === '' || substr($haystack, -strlen($needle)) === $needle;
476
	}
476
	}
477
 
477
 
478
	/**
478
	/**
479
	* Fonction utilisée pour importer les anciens mots clés saisis dans les widget dans un compte identifié
479
	* Fonction utilisée pour importer les anciens mots clés saisis dans les widget dans un compte identifié
480
	* Dans ce cas là, le widget remplit la case user_id par le mail indiqué lors de la saisie
480
	* Dans ce cas là, le widget remplit la case user_id par le mail indiqué lors de la saisie
481
	* @param string $mail_utilisateur
481
	* @param string $mail_utilisateur
482
	* @param string $user_id
482
	* @param string $user_id
483
	*/
483
	*/
484
	public static function migrerMotsClesMailVersId($mail_utilisateur, $infos_utilisateur) {
484
	public static function migrerMotsClesMailVersId($mail_utilisateur, $infos_utilisateur) {
485
		return self::migrerLiaisonEtMotsCles($mail_utilisateur, $infos_utilisateur, 'obs') &&
485
		return self::migrerLiaisonEtMotsCles($mail_utilisateur, $infos_utilisateur, 'obs') &&
486
				self::migrerLiaisonEtMotsCles($mail_utilisateur, $infos_utilisateur, 'images');
486
				self::migrerLiaisonEtMotsCles($mail_utilisateur, $infos_utilisateur, 'images');
487
	}
487
	}
488
 
488
 
489
	/**
489
	/**
490
	 * ATTENTION : cette fonction suppose que l'utilisateur n'ai pas déjà de mots clés dans le CEL
490
	 * ATTENTION : cette fonction suppose que l'utilisateur n'ai pas déjà de mots clés dans le CEL
491
	 * avec l'identifiant $user_id ce qui est normalement le cas
491
	 * avec l'identifiant $user_id ce qui est normalement le cas
492
	 * ça devrait normalement marcher correctement même s'il en a déjà mais ça n'a pas été testé
492
	 * ça devrait normalement marcher correctement même s'il en a déjà mais ça n'a pas été testé
493
	 */
493
	 */
494
	private static function migrerLiaisonEtMotsCles($email_utilisateur, $infos_utilisateur, $mode) {
494
	private static function migrerLiaisonEtMotsCles($email_utilisateur, $infos_utilisateur, $mode) {
495
	    list($table_liaisons, $table_mots_cles, $id_mot_cle, $id_element_lie) = self::getTablesMotsClesEtLiaisons($mode);
495
	    list($table_liaisons, $table_mots_cles, $id_mot_cle, $id_element_lie) = self::getTablesMotsClesEtLiaisons($mode);
496
		$idUtilisateurP = Cel::db()->proteger($infos_utilisateur['user_id']);
496
		$idUtilisateurP = Cel::db()->proteger($infos_utilisateur['user_id']);
497
		$emailUtilisateurP = Cel::db()->proteger($email_utilisateur);
497
		$emailUtilisateurP = Cel::db()->proteger($email_utilisateur);
498
 
498
 
499
		$requete_migration_mc = "UPDATE {$table_mots_cles} ".
499
		$requete_migration_mc = "UPDATE {$table_mots_cles} ".
500
			"SET user_id = $idUtilisateurP ".
500
			"SET user_id = $idUtilisateurP ".
501
			"WHERE user_id = $emailUtilisateurP ";
501
			"WHERE user_id = $emailUtilisateurP ";
502
 
502
 
503
		$migration = Cel::db()->executer($requete_migration_mc);
503
		$migration = Cel::db()->executer($requete_migration_mc);
504
		$migration = ($migration !== false) ? true : false;
504
		$migration = ($migration !== false) ? true : false;
505
		return $migration;
505
		return $migration;
506
	}
506
	}
507
}
507
}