Subversion Repositories eFlore/Applications.coel

Rev

Rev 1581 | Rev 1698 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1497 jpm 1
<?php
2
/**
3
 * Service fournissant des informations sur les collections et les structures répondant aux critères de recherche
4
 * fournis en paramêtre.
5
 * Encodage en entrée : utf8
6
 * Encodage en sortie : utf8
7
 *
8
 * @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
9
 * @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
10
 * @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
11
 * @version $Id$
12
 * @copyright 2009
13
 */
14
class CoelRecherche extends Coel {
15
 
16
	/**
17
	 * Méthode principale appelée avec une requête de type GET.
18
	 * Elle sert d'aiguilleur pour appeller la méthode correspondant au type de recherche passé en paramêtre.
19
	 */
20
	public function getElement($param = array()) {
21
		// Initialisation des variables
22
		$info = array();
23
 
24
		// Nour recherchons le type de requête demandé
25
		$type = $param[0];
26
 
27
		$methode = 'getElement'.$type;
28
		if (method_exists($this, $methode)) {
29
			array_shift($param);
30
			$info = $this->$methode($param);
31
		} else {
32
			$this->messages[] = "Le type de recherche demandé '$type' n'est pas disponible.";
33
		}
34
 
35
		// Envoie sur la sortie standard
36
		$this->envoyer($info);
37
	}
38
 
39
 	/* Méthode pour récupérer une liste d'information sur les collections et/ou structures en fonction de mots et de
40
 	 * restrictions.
41
	 * Appelée avec les paramêtres d'url suivant :
42
	 * /CoelRecherche/ParDefaut/_
43
	 * ou les _ représentent dans l'ordre : mots
44
	 * Si un des paramêtres est abscent, il prendre la valeur *
45
	 */
46
	public function getElementParDefaut($param) {
47
		// Initialisation des variables
48
		$info = array();
49
 
50
		// Pré traitement des paramêtres
51
		$p = $this->pretraiterParametresUrl($param);
52
 
53
		// Construction de la requête
54
		$requete = 	(($this->distinct) ? 'SELECT DISTINCT' : 'SELECT').' cs_id_structure, cs_ville, cs_nom, '.
1646 alex 55
					'cs_code_postal, cs_latitude, cs_longitude, cc_id_collection, cc_nom '.
1497 jpm 56
					$this->construireFromEtWhere($p).
1517 jpm 57
					'ORDER BY '.((!is_null($this->orderby)) ? $this->orderby  : 'cs_ville ASC, cs_nom ASC, cc_nom ASC').' '.
1497 jpm 58
					"LIMIT $this->start, $this->limit ";
1545 jpm 59
 
1497 jpm 60
		// Récupération des résultats
61
		try {
62
			$donnees = $this->bdd->query($requete)->fetchAll(PDO::FETCH_ASSOC);
63
			if ($donnees === false) {
64
				$this->messages[] = "La requête a retourné aucun résultat.";
65
			} else {
66
				$info = $donnees;
67
			}
68
		} catch (PDOException $e) {
69
			$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage());
70
		}
71
		return $info;
72
	}
73
 
74
	/* Méthode pour récupérer une liste d'information sur les collections et/ou structures en fonction de mots et de
75
 	 * restrictions.
76
	 * Appelée avec les paramêtres d'url suivant :
77
	 * /CoelRecherche/ParDefaut/_
78
	 * ou les _ représentent dans l'ordre : mots
79
	 * Si un des paramêtres est abscent, il prendre la valeur *
80
	 */
81
	public function getElementNombre($param) {
82
		// Initialisation des variables
83
		$info = array();
84
 
85
		// Pré traitement des paramêtres
86
		$p = $this->pretraiterParametresUrl($param);
87
 
88
		// Construction de la requête
1545 jpm 89
		// Il est important de compter le nombre d'association structure-collection différentes pour obtenir le bon nombre
90
		$requete = 	(($this->distinct) ? 'SELECT DISTINCT' : 'SELECT').' COUNT(cs_id_structure) AS nbre, cc_id_collection '.
1497 jpm 91
					$this->construireFromEtWhere($p).
1501 jpm 92
					'ORDER BY '.((!is_null($this->orderby)) ? $this->orderby  : 'cs_ville ASC, cs_nom ASC').' ';
1497 jpm 93
 
94
		// Récupération des résultats
95
		try {
96
			$donnees = $this->bdd->query($requete)->fetch(PDO::FETCH_ASSOC);
97
			if ($donnees === false) {
98
				$this->messages[] = "La requête a retourné aucun résultat.";
99
			} else {
100
				$info = $donnees['nbre'];
101
			}
102
		} catch (PDOException $e) {
103
			$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage());
104
		}
105
 
106
		return $info;
107
	}
108
 
109
	private function pretraiterParametresUrl($param) {
110
		// Tableau des paramêtres qui peuvent être passés dans l'url
111
		$params_passes = array('mots' => 'str',
112
			'sci' => 'bool',
113
			'bot' => 'int',
114
			'zg' => 'str',
115
			'p' => 'str',
116
			'pr' => 'int',
1506 jpm 117
			'str-d' => 'defaut',
1581 jpm 118
			'veg' => 'int',
119
			'projets' => 'int');
1497 jpm 120
 
121
		$p = $this->traiterParametresUrl(array_keys($params_passes), $param, false);
1506 jpm 122
		$this->debug[] = $param;
1497 jpm 123
		foreach ($params_passes as $param_passe => $type) {
124
			if (isset($p[$param_passe])) {
125
				// Suppression des éventuels espaces en début et fin de chaine
126
				$valeur = trim($p[$param_passe]);
127
 
128
				// Type de paramêtre chaine
129
				if ($type == 'str') {
130
					// Suppression des slash
131
					$valeur = stripslashes($valeur);
132
 
133
					// Utilisation d'une recherche de chaîne exacte
134
					if (preg_match('/^"(.*)"$/', $valeur, $match)) {
135
						$valeur = '%'.$match[1].'%';
136
					} else {
137
						// Recherche de mots non liés
138
						$mots = explode(' ', $valeur);
139
						$valeur = '%'.implode ('%', $mots).'%';
140
					}
141
					// Mise en place des quotes pour l'intérogation dans la bdd
142
					$valeur = $this->bdd->quote($valeur);
143
				}
144
				// Type de paramêtre booléen
145
				if ($type == 'bool') {
146
					if (preg_match('/^[0]$/', $valeur)) {
147
						$valeur = false;
148
					} else if (preg_match('/^[1]$/', $valeur)) {
149
						$valeur = true;
150
					} else {
1506 jpm 151
						$this->messages[] = "Le paramêtre '$param_passe' attend une valeur de type 0 ou 1 et non '$valeur'.";
1497 jpm 152
						$valeur = null;
153
					}
154
 
155
				}
156
				// Type de paramêtre entier
157
				if ($type == 'int') {
158
					if (!preg_match('/^(?:[0-9]+,\s*)*[0-9]+$/', $valeur)) {
1506 jpm 159
						$this->messages[] = "Le paramêtre '$param_passe' attend une ou plusieurs valeurs de type entiers ".
1497 jpm 160
							"séparés par des virgules et non '$valeur'.";
161
						$valeur = null;
162
					}
163
				}
164
 
165
				$p[$param_passe] = $valeur;
166
			}
167
		}
1506 jpm 168
 
1497 jpm 169
		return $p;
170
	}
171
 
172
	private function construireFromEtWhere($p) {
173
		// Initialisation de variables
174
		$from_et_where = '';
175
		$from = 'FROM coel_collection '.
176
			'	LEFT JOIN coel_structure ON (cc_ce_structure = cs_id_structure) ';
177
		$where = 'WHERE ';
178
 
179
		// Construire from et where en fonction des paramêtres
180
		if (isset($p['mots'])) {
181
			$where .= 'AND ('.
182
				"	cc_nom LIKE {$p['mots']} ".
183
				"	OR cc_truk_nom_alternatif LIKE {$p['mots']} ".
184
				"	OR cc_truk_code LIKE {$p['mots']} ".
185
				"	OR cc_description LIKE {$p['mots']} ".
186
				"	OR cc_description_specialiste LIKE {$p['mots']} ".
187
				"	OR cc_historique LIKE {$p['mots']} ".
188
 
189
				"	OR cs_nom LIKE {$p['mots']} ".
1506 jpm 190
				"	OR cs_truk_nom_alternatif LIKE {$p['mots']} ".
191
				"	OR cs_description LIKE {$p['mots']} ".
1497 jpm 192
				"	OR cs_adresse_01 LIKE {$p['mots']} ".
193
				"	OR cs_adresse_02 LIKE {$p['mots']} ".
194
				"	OR cs_ville LIKE {$p['mots']} ".
195
				"	OR cs_truk_identifiant_alternatif LIKE {$p['mots']} ".
1506 jpm 196
				"	OR cs_condition_acces LIKE {$p['mots']} ".
197
				"	OR cs_condition_usage LIKE {$p['mots']} ".
198
				"	OR cs_truk_telephone LIKE {$p['mots']} ".
199
				"	OR cs_courriel LIKE {$p['mots']} ".
200
				"	OR cs_truk_url LIKE {$p['mots']} ".
1497 jpm 201
				') ';
202
		}
203
		if (isset($p['sci'])) {
204
			if ($p['sci'] === true) {
1502 jpm 205
				$where .= 'AND csv_mark_visite_avec_motif = 1 ';
206
			} else if ($p['sci'] === false) {
1497 jpm 207
				$where .= 'AND csv_mark_acces_ss_motif = 1 ';
208
			}
209
		}
210
		if (isset($p['bot'])) {
211
			$where .= "AND ccb_ce_truk_type IN ({$p['bot']}) ";
212
		}
213
		if (isset($p['zg'])) {
214
			$where .= "AND cc_truk_couverture_lieu LIKE {$p['zg']} ";
215
		}
216
		if (isset($p['p'])) {
217
			$where .= "AND cp_fmt_nom_complet LIKE {$p['p']} ";
218
		}
219
		if (isset($p['pr'])) {
220
			$where .= "AND ccap_id_role IN ({$p['pr']}) ";
221
		}
222
		if (isset($p['str-d'])) {
223
			$where .= 'AND cs_ce_truk_pays = 2654 '.
224
				"AND cs_code_postal LIKE '{$p['str-d']}%' ";
225
		}
226
 
1506 jpm 227
		if (isset($p['veg'])) {
228
			$veg = explode(',', $p['veg']);
229
			$veg_nbre = count($veg);
230
 
231
			if ($veg_nbre == 1) {
232
				$where .= "AND ccb_truk_nature LIKE '%{$p['veg']}%' ";
233
			} else {
234
				$recherche = array();
235
				foreach ($veg as $id) {
236
					$recherche[] = "ccb_truk_nature LIKE '%$id%'";
237
				}
238
				$where .= 'AND ('.implode(' OR ', $recherche).') ';
239
			}
1581 jpm 240
		}
1506 jpm 241
 
1581 jpm 242
		if (isset($p['projets'])) {
243
			$where .= "AND cc_ce_projet IN ({$p['projets']}) ".
244
				"AND cs_ce_projet IN ({$p['projets']}) ";
245
		}
246
 
1497 jpm 247
		$where = str_replace('WHERE AND', 'WHERE', $where);
248
 
249
		// Gestion du from en fonction des paramêtres
1507 jpm 250
		if (isset($p['str-d'])) {// ATTENTION : Remplace $from, doit être situé en première position!
251
			$from = 'FROM coel_structure '.
252
					'	LEFT JOIN coel_collection ON (cs_id_structure = cc_ce_structure) ';
253
		}
1497 jpm 254
		if (isset($p['sci'])) {
255
			$from .= '	LEFT JOIN coel_structure_valorisation ON (cs_id_structure = csv_id_structure) ';
256
		}
1506 jpm 257
		if (isset($p['bot']) || isset($p['veg'])) {
1497 jpm 258
			$from .= '	LEFT JOIN coel_collection_botanique ON (cc_id_collection = ccb_id_collection) ';
259
		}
260
		if (isset($p['p']) || isset($p['pr'])) {
261
			$from .= '	LEFT JOIN coel_collection_a_personne ON (cc_id_collection = ccap_id_collection) ';
262
		}
263
		if (isset($p['p'])) {
264
			$from .= '	LEFT JOIN coel_personne ON (ccap_id_personne = cp_id_personne) ';
265
		}
266
 
267
		// Retour du From et Where associé
268
		if (count($p) == 0) {
269
			$from_et_where = $from;
270
		} else {
271
			$from_et_where = $from.$where;
272
		}
273
		return $from_et_where;
274
	}
275
}
276
?>