Subversion Repositories eFlore/Applications.coel

Rev

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