Subversion Repositories eFlore/Applications.coel

Rev

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