Subversion Repositories eFlore/Applications.cel

Rev

Details | 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 {
13
 
14
	private $config;
15
	private $mode;
16
 
17
	private $table_liaison;
18
	private $table_mots_cles;
19
 
2032 aurelien 20
	//TODO: trigger pour les tables liaisons
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;
26
 
27
		if($mode == 'obs') {
28
			$this->table_liaison = 'cel_obs_tags_path_liaison';
29
			$this->table_mots_cles = 'cel_obs_tags_path';
30
		} else {
31
			$this->table_liaison = 'cel_images_tags_path_liaison';
32
			$this->table_mots_cles = 'cel_images_tags_path';
33
		}
2025 aurelien 34
	}
2026 aurelien 35
 
2027 aurelien 36
	public function construireRequeteOr($mots_cles) {
37
		return $this->construireRequete($mots_cles, 'OR');
38
	}
39
 
40
	public function construireRequeteCheminOr($mots_cles) {
41
		return $this->construireRequeteChemin($mots_cles, 'OR');
42
	}
43
 
44
	public function construireRequeteAnd($mots_cles) {
45
		return $this->construireRequete($mots_cles, 'AND');
46
	}
47
 
48
	public function construireRequeteCheminAnd($mots_cles) {
49
		return $this->construireRequeteChemin($mots_cles, 'AND');
50
	}
51
 
52
	public function construireRequete($mots_cles, $operateur = 'AND') {
53
		$criteres = array();
54
		$premier = array_pop($mots_cles);
2032 aurelien 55
		$requete = "SELECT * FROM ".$this->table_liaison." lmc ".
56
		           "INNER JOIN ".$this->table_mots_cles." mc ".
57
		           "ON mc.tag = ".Cel::db()->proteger($premier)." AND lmc.id_tag = mc.id_tag ";
2027 aurelien 58
		foreach ($mots_cles as $mot_cle) {
2032 aurelien 59
			$requete .= " ".$operateur." id_element_lie IN (SELECT id_element_lie FROM ".$this->table_liaison." lmc ".
60
							"INNER JOIN ".$this->table_mots_cles." mc ".
61
		           			"ON mc.tag = ".Cel::db()->proteger($mot_cle)." AND lmc.id_tag = mc.id_tag ".
62
						") ";
2027 aurelien 63
		}
2032 aurelien 64
 
2027 aurelien 65
		$images = Cel::db()->requeter($requete);
66
		return $images;
67
	}
68
 
69
	private function construireRequeteChemin($mots_cles, $operateur = 'AND') {
2032 aurelien 70
			$criteres = array();
2027 aurelien 71
		$premier = array_pop($mots_cles);
2032 aurelien 72
		$requete = "SELECT * FROM ".$this->table_liaison." lmc ".
73
		           "INNER JOIN ".$this->table_mots_cles." mc ".
74
		           "ON mc.chemin LIKE ".Cel::db()->proteger('%'.$premier.'%')." AND lmc.id_tag = mc.id_tag ";
2027 aurelien 75
		foreach ($mots_cles as $mot_cle) {
2032 aurelien 76
			$requete .= " ".$operateur." id_element_lie IN (SELECT id_element_lie FROM ".$this->table_liaison." lmc ".
77
							"INNER JOIN ".$this->table_mots_cles." mc ".
78
		           			"ON mc.chemin LIKE ".Cel::db()->proteger('%'.$mot_cle.'%')." AND lmc.id_tag = mc.id_tag ".
79
						") ";
2027 aurelien 80
		}
2032 aurelien 81
 
2027 aurelien 82
		$images = Cel::db()->requeter($requete);
83
		return $images;
84
	}
85
 
2025 aurelien 86
	public function obtenirArbre($id_utilisateur, $chemin = "/") {
87
 
88
		$requete = "SELECT * FROM ".$this->table_mots_cles." ".
89
		"WHERE id_utilisateur = ".Cel::db()->proteger($id_utilisateur)." AND ".
2026 aurelien 90
		"chemin LIKE ".Cel::db()->proteger($chemin."%")." ".
91
		"ORDER BY chemin";
2025 aurelien 92
 
2026 aurelien 93
		$arbre = Cel::db()->requeter($requete.' -- '.__FILE__.':'.__LINE__);
94
		usort($arbre, array('GestionMotsClesChemin', 'comparerProfNoeuds'));
2025 aurelien 95
 
96
		return $arbre;
97
	}
98
 
2026 aurelien 99
	public function insererParChemin($mot_cle, $chemin_parent, $id_utilisateur) {
2025 aurelien 100
 
2026 aurelien 101
		$chemin_mot_cle = self::getCheminHarmonise($chemin_parent, $mot_cle);
2025 aurelien 102
 
2032 aurelien 103
		$requete = "INSERT IGNORE INTO ".$this->table_mots_cles." (chemin, id_utilisateur, tag) ".
2025 aurelien 104
		           "VALUES (".
105
		           		Cel::db()->proteger($chemin_mot_cle).", ".
106
						Cel::db()->proteger($id_utilisateur).", ".
2026 aurelien 107
						Cel::db()->proteger($mot_cle)." ".
2025 aurelien 108
		           ")";
2032 aurelien 109
 
2025 aurelien 110
		$insertion = Cel::db()->executer($requete.' -- '.__FILE__.':'.__LINE__);
111
 
112
		return $insertion;
113
	}
114
 
115
	public function insererParIdParent($mot_cle, $id_parent, $id_utilisateur) {
116
 
117
		$mot_cle_simp = self::simplifier($mot_cle);
118
 
2032 aurelien 119
		$sous_requete_chemin = "(SELECT chemin FROM ".$this->table_mots_cles." ctp ".
120
		                       "WHERE ctp.id_tag = ".Cel::db()->proteger($id_parent).")";
2025 aurelien 121
 
122
		$requete = "INSERT INTO ".$this->table_mots_cles."(chemin, id_utilisateur, tag) ".
123
		           "VALUES (".
2032 aurelien 124
						"CONCAT(".$sous_requete_chemin.",".Cel::db()->proteger($mot_cle_simp).",'/'), ".
2025 aurelien 125
						Cel::db()->proteger($id_utilisateur).", ".
2032 aurelien 126
						Cel::db()->proteger($mot_cle)." ".
2025 aurelien 127
		           ")";
128
 
129
		$insertion = Cel::db()->executer($requete.' -- '.__FILE__.':'.__LINE__);
130
 
131
		return $insertion;
132
	}
133
 
2032 aurelien 134
	public function lierParId($id_mot_cle, $id_element_lie) {
135
 
136
		$requete = "INSERT INTO ".$this->table_liaison." (id_element_lie, id_tag) ".
2025 aurelien 137
					"VALUES (".
2032 aurelien 138
				   		Cel::db()->proteger($id_element_lie).", ".
139
				   		Cel::db()->proteger($id_mot_cle)." ".
2025 aurelien 140
				   	") ".
2032 aurelien 141
					"ON DUPLICATE KEY UPDATE id_element_lie = id_element_lie ";
2025 aurelien 142
 
143
		$liaison = Cel::db()->executer($requete.' -- '.__FILE__.':'.__LINE__);
144
 
145
		return $liaison;
146
	}
147
 
2032 aurelien 148
	public function lierParChemin($chemin, $id_element_lie, $id_utilisateur) {
149
 
150
		$sous_requete_chemin = '(SELECT id_tag FROM '.$this->table_mots_cles.' '.
151
								'WHERE chemin = '.Cel::db()->proteger(self::harmoniserChemin($chemin)).' '.
152
								'AND id_utilisateur = '.Cel::db()->proteger($id_utilisateur).' '.
153
								')';
154
 
155
		$requete = "INSERT INTO ".$this->table_liaison." (id_element_lie, id_tag) ".
2025 aurelien 156
					"VALUES (".
2032 aurelien 157
						Cel::db()->proteger($id_element_lie).", ".
158
						$sous_requete_chemin." ".
2025 aurelien 159
				   	") ".
2032 aurelien 160
					"ON DUPLICATE KEY UPDATE id_element_lie = id_element_lie ";
2025 aurelien 161
 
162
		$liaison = Cel::db()->executer($requete.' -- '.__FILE__.':'.__LINE__);
163
 
164
		return $liaison;
165
	}
166
 
2032 aurelien 167
	// OK jusqu'ici !
168
 
2025 aurelien 169
	// Déplacer un mot clé et le renommer est une même opération, dans le cas du renommage,
170
	// seule la fin du chemin change
171
	public function renommerChemin($ancien_chemin, $nouveau_chemin, $id_utilisateur) {
2026 aurelien 172
 
173
		$ancien_chemin = self::harmoniserChemin($ancien_chemin);
174
		$nouveau_chemin = self::harmoniserChemin($nouveau_chemin);
175
 
176
		$ancien_chemin_p = Cel::db()->proteger($ancien_chemin);
177
		$nouveau_chemin_p = Cel::db()->proteger($nouveau_chemin);
178
 
2025 aurelien 179
		// TODO : triggers pour les tables liées ?
2026 aurelien 180
		$requete = "UPDATE ".$this->table_mots_cles." ".
181
		       	   "SET chemin = REPLACE(chemin,".$ancien_chemin_p.", ".$nouveau_chemin_p.") ".
2025 aurelien 182
				   "WHERE chemin LIKE ".Cel::db()->proteger($ancien_chemin."%")." AND ".
183
		           "id_utilisateur = ".Cel::db()->proteger($id_utilisateur)." ";
2032 aurelien 184
 
2026 aurelien 185
		$deplacement = Cel::db()->executer($requete.' -- '.__FILE__.':'.__LINE__);
2025 aurelien 186
 
2026 aurelien 187
		return $deplacement;
2025 aurelien 188
	}
189
 
190
	public function supprimerChemin($chemin, $id_utilisateur) {
191
		// TODO : triggers pour les tables liées ?
192
		$requete = "DELETE FROM ".$this->$table_mots_cles." ".
193
                   	"WHERE chemin LIKE ".Cel::db()->proteger($chemin."%")." AND ".
194
                   	"id_utilisateur = ".Cel::db()->proteger($id_utilisateur)." ";
195
 
196
		$suppression = Cel::db()->executer($requete.' -- '.__FILE__.':'.__LINE__);
197
 
198
		return $suppression;
199
 
200
	}
201
 
202
	// Fonctions utilitaires
203
	static public function comparerProfNoeuds($a, $b) {
204
 
205
		$nb_slashs_a = substr_count($a['chemin'], '/');
206
		$nb_slashs_b = substr_count($a['chemin'], '/');
207
		$cmp = 0;
208
 
209
		if($nb_slashs_a == $nb_slashs_b) {
210
			$cmp = strcmp($a['chemin'], $b['chemin']);
211
		} else {
212
			$cmp = ($a['chemin'] > $b['chemin']) ? +1 : -1;
213
		}
214
 
215
		return $cmp;
216
	}
217
 
2026 aurelien 218
	static public function getCheminHarmonise($chemin_parent, $mot_cle) {
219
		return self::harmoniserChemin($chemin_parent.'/'.self::simplifier($mot_cle).'/');
220
	}
221
 
222
	static public function harmoniserChemin($chemin) {
223
		$chemin = self::startsWith($chemin,'/') ? $chemin : '/'.$chemin;
224
		$chemin = self::endsWith($chemin,'/') ? $chemin : $chemin.'/';
225
		return str_replace('//', '/', $chemin);
226
	}
227
 
2025 aurelien 228
	// fonction de slugification du mot clé
229
	// http://stackoverflow.com/questions/2955251/php-function-to-make-slug-url-string
230
	static public function simplifier($text)
231
	{
2026 aurelien 232
		return trim(str_replace(array('\\','/'), '', $text));
2025 aurelien 233
		// replace non letter or digits by -
234
		$text = preg_replace('~[^\\pL\d]+~u', '-', $text);
235
 
236
		// trim
237
		$text = trim($text, '-');
238
 
239
		// transliterate
240
		$text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
241
 
242
		// lowercase
243
		$text = strtolower($text);
244
 
245
		// remove unwanted characters
246
		$text = preg_replace('~[^-\w]+~', '', $text);
247
 
248
		if (empty($text))
249
		{
250
			return 'n-a';
251
		}
252
 
253
		return $text;
254
	}
2026 aurelien 255
 
256
	static public function startsWith($haystack, $needle) {
257
		return $needle === "" || strpos($haystack, $needle) === 0;
258
	}
259
 
260
	static public function endsWith($haystack, $needle) {
261
		return $needle === "" || substr($haystack, -strlen($needle)) === $needle;
262
	}
2025 aurelien 263
}
264
 
265
?>