Subversion Repositories eFlore/Applications.del

Rev

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

Rev 1881 Rev 1888
1
<?php
1
<?php
2
// declare(encoding='UTF-8');
2
// declare(encoding='UTF-8');
3
/**
3
/**
4
 * Classe contenant des méthodes permettant de construire les requêtes SQL complexe concernant les images et obs.
4
 * Classe contenant des méthodes permettant de construire les requêtes SQL complexe concernant les images et obs.
5
 * Rempli un tableau des clauses "join", "where", "group by" et "oder by" nécessaire à la *recherche* des ids des
5
 * Rempli un tableau des clauses "join", "where", "group by" et "oder by" nécessaire à la *recherche* des ids des
6
 * observations/images correspondantes aux filtres passés dans l'url du web service de recherche
6
 * observations/images correspondantes aux filtres passés dans l'url du web service de recherche
7
 * (ListeImages et ListeObservations).
7
 * (ListeImages et ListeObservations).
8
 *
8
 *
9
 * Attention, cela signifie que toutes les tables ne sont pas *forcément* jointées, par exemple si aucune
9
 * Attention, cela signifie que toutes les tables ne sont pas *forcément* jointées, par exemple si aucune
10
 * contrainte ne le nécessite.
10
 * contrainte ne le nécessite.
11
 * La requête construite ici est utile pour récupérer la liste des ids d'observations/images qui match.
11
 * La requête construite ici est utile pour récupérer la liste des ids d'observations/images qui match.
12
 * Pour la récupération effective de "toutes" les données nécessaire au retour du web service en json, c'est une autre
12
 * Pour la récupération effective de "toutes" les données nécessaire au retour du web service en json, c'est une autre
13
 * requête directement dans le web service qui s'en charge. Cette technique en deux étapes est la plus rapide !
13
 * requête directement dans le web service qui s'en charge. Cette technique en deux étapes est la plus rapide !
14
 *
14
 *
15
 * Note: toujours rajouter les préfixes de table (di, do ou du), en fonction de ce que défini
15
 * Note: toujours rajouter les préfixes de table (di, do ou du), en fonction de ce que défini
16
 * les JOIN qui sont utilisés :
16
 * les JOIN qui sont utilisés :
17
 * - le préfix de del_image est "di"
17
 * - le préfix de del_image est "di"
18
 * - le préfix de del_observation est "do"
18
 * - le préfix de del_observation est "do"
19
 * - le préfix de del_utilisateur est "du"
19
 * - le préfix de del_utilisateur est "du"
20
 *
20
 *
21
 * @category  DEL
21
 * @category  DEL
22
 * @package   Services
22
 * @package   Services
23
 * @package   Bibliotheque
23
 * @package   Bibliotheque
24
 * @version   0.1
24
 * @version   0.1
25
 * @author    Mathias CHOUET <mathias@tela-botanica.org>
25
 * @author    Mathias CHOUET <mathias@tela-botanica.org>
26
 * @author    Jean-Pascal MILCENT <jpm@tela-botanica.org>
26
 * @author    Jean-Pascal MILCENT <jpm@tela-botanica.org>
27
 * @author    Aurelien PERONNET <aurelien@tela-botanica.org>
27
 * @author    Aurelien PERONNET <aurelien@tela-botanica.org>
28
 * @license   GPL v3 <http://www.gnu.org/licenses/gpl.txt>
28
 * @license   GPL v3 <http://www.gnu.org/licenses/gpl.txt>
29
 * @license   CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
29
 * @license   CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
30
 * @copyright 1999-2014 Tela Botanica <accueil@tela-botanica.org>
30
 * @copyright 1999-2014 Tela Botanica <accueil@tela-botanica.org>
31
 */
31
 */
32
class Sql {
32
class Sql {
33
 
33
 
34
	const APPLI_IMG = 'IMG';
34
	const APPLI_IMG = 'IMG';
35
	const APPLI_OBS = 'OBS';
35
	const APPLI_OBS = 'OBS';
36
 
36
 
37
	private $conteneur;
37
	private $conteneur;
38
	private $bdd;
38
	private $bdd;
39
	private $parametres = array();
39
	private $parametres = array();
40
	private $appli;
40
	private $appli;
41
	private $requete = array(
41
	private $requete = array(
42
		'join' => array(),
42
		'join' => array(),
43
		'where' => array(),
43
		'where' => array(),
44
		'groupby' => array(),
44
		'groupby' => array(),
45
		'orderby' => array());
45
		'orderby' => array());
46
 
46
 
47
	private $champsPrenom = array('du.prenom', 'prenom_utilisateur');
47
	private $champsPrenom = array('du.prenom', 'prenom_utilisateur');
48
	private $champsNom = array('du.nom',  'nom_utilisateur');
48
	private $champsNom = array('du.nom',  'nom_utilisateur');
49
 
49
 
50
 
50
 
51
	public function __construct(Conteneur $conteneur) {
51
	public function __construct(Conteneur $conteneur) {
52
		$this->conteneur = $conteneur;
52
		$this->conteneur = $conteneur;
53
		$this->bdd = $this->conteneur->getBdd();
53
		$this->bdd = $this->conteneur->getBdd();
54
	}
54
	}
55
 
55
 
56
	public function setParametres(Array $parametres) {
56
	public function setParametres(Array $parametres) {
57
		$this->parametres = $parametres;
57
		$this->parametres = $parametres;
58
	}
58
	}
59
 
59
 
60
	public function setAppli($appliType) {
60
	public function setAppli($appliType) {
61
		if ($appliType == 'IMG' || $appliType == 'OBS') {
61
		if ($appliType == 'IMG' || $appliType == 'OBS') {
62
			$this->appli = $appliType;
62
			$this->appli = $appliType;
63
		} else {
63
		} else {
64
			throw new Exception("Les types d'appli disponible sont : IMG (pour PictoFlora) et OBS (pour IdentiPlante)");
64
			throw new Exception("Les types d'appli disponible sont : IMG (pour PictoFlora) et OBS (pour IdentiPlante)");
65
		}
65
		}
66
	}
66
	}
67
 
67
 
68
	private function getPrefixe() {
68
	private function getPrefixe() {
69
		return $this->appli === 'IMG' ? 'di' : 'do';
69
		return $this->appli === 'IMG' ? 'di' : 'do';
70
	}
70
	}
71
 
71
 
72
	private function etreAppliImg() {
72
	private function etreAppliImg() {
73
		return $this->appli === 'IMG' ? true : false;
73
		return $this->appli === 'IMG' ? true : false;
74
	}
74
	}
75
 
75
 
76
	private function etreAppliObs() {
76
	private function etreAppliObs() {
77
		return $this->appli === 'OBS' ? true : false;
77
		return $this->appli === 'OBS' ? true : false;
78
	}
78
	}
79
 
79
 
80
	public function getRequeteSql() {
80
	public function getRequeteSql() {
81
		return $this->requete;
81
		return $this->requete;
82
	}
82
	}
83
 
83
 
84
	private function addJoin($join) {
84
	private function addJoin($join) {
85
		if (!isset($this->requete['join'][$join])) {
85
		if (!isset($this->requete['join'][$join])) {
86
			$this->requete['join'][] = $join;
86
			$this->requete['join'][] = $join;
87
		}
87
		}
88
	}
88
	}
89
 
89
 
90
	public function getJoin() {
90
	public function getJoin() {
91
		return ($this->requete['join'] ? implode(' ', array_unique($this->requete['join'])).' ' : '');
91
		return ($this->requete['join'] ? implode(' ', array_unique($this->requete['join'])).' ' : '');
92
	}
92
	}
93
 
93
 
94
	private function addJoinDis($join) {
94
	private function addJoinDis($join) {
95
		$this->requete['join']['dis'] = $join;
95
		$this->requete['join']['dis'] = $join;
96
	}
96
	}
97
 
97
 
98
	private function addWhere($idParam, $where) {
98
	private function addWhere($idParam, $where) {
99
		if (isset($this->parametres['_parametres_condition_or_'])
99
		if (isset($this->parametres['_parametres_condition_or_'])
100
				&& in_array($idParam, $this->parametres['_parametres_condition_or_'])) {
100
				&& in_array($idParam, $this->parametres['_parametres_condition_or_'])) {
101
			$this->requete['where']['OR'][] = $where;
101
			$this->requete['where']['OR'][] = $where;
102
		} else {
102
		} else {
103
			$this->requete['where']['AND'][] = $where;
103
			$this->requete['where']['AND'][] = $where;
104
		}
104
		}
105
	}
105
	}
106
	public function getWhere() {
106
	public function getWhere() {
107
		if (isset($this->requete['where']['OR']) && count($this->requete['where']['OR']) > 0) {
107
		if (isset($this->requete['where']['OR']) && count($this->requete['where']['OR']) > 0) {
108
			$this->requete['where']['AND'][] = '('.implode(' OR ', $this->requete['where']['OR']).')';
108
			$this->requete['where']['AND'][] = '('.implode(' OR ', $this->requete['where']['OR']).')';
109
		}
109
		}
110
 
110
 
111
		$where = ' TRUE ';
111
		$where = ' TRUE ';
112
		if (isset($this->requete['where']['AND']) && count($this->requete['where']['AND']) > 0) {
112
		if (isset($this->requete['where']['AND']) && count($this->requete['where']['AND']) > 0) {
113
			$where = implode(' AND ', $this->requete['where']['AND']).' ';
113
			$where = implode(' AND ', $this->requete['where']['AND']).' ';
114
		}
114
		}
115
		return $where;
115
		return $where;
116
	}
116
	}
117
 
117
 
118
	private function addGroupBy($groupBy) {
118
	private function addGroupBy($groupBy) {
119
		$this->requete['groupby'][] = $groupBy;
119
		$this->requete['groupby'][] = $groupBy;
120
	}
120
	}
121
 
121
 
122
	public function getGroupBy() {
122
	public function getGroupBy() {
123
		$groupby = '';
123
		$groupby = '';
124
		if (isset($this->requete['groupby']) && count($this->requete['groupby']) > 0) {
124
		if (isset($this->requete['groupby']) && count($this->requete['groupby']) > 0) {
125
			$groupby = 'GROUP BY '.implode(', ', array_unique($this->requete['groupby'])).' ';
125
			$groupby = 'GROUP BY '.implode(', ', array_unique($this->requete['groupby'])).' ';
126
		}
126
		}
127
		return $groupby;
127
		return $groupby;
128
	}
128
	}
129
 
129
 
130
	private function addOrderBy($orderby) {
130
	private function addOrderBy($orderby) {
131
		$this->requete['orderby'][] = $orderby;
131
		$this->requete['orderby'][] = $orderby;
132
	}
132
	}
133
 
133
 
134
	public function getOrderBy() {
134
	public function getOrderBy() {
135
		$orderby = '';
135
		$orderby = '';
136
		if (isset($this->requete['orderby']) && count($this->requete['orderby']) > 0) {
136
		if (isset($this->requete['orderby']) && count($this->requete['orderby']) > 0) {
137
			$orderby = 'ORDER BY '.implode(', ', array_unique($this->requete['orderby'])).' ';
137
			$orderby = 'ORDER BY '.implode(', ', array_unique($this->requete['orderby'])).' ';
138
		}
138
		}
139
		return $orderby;
139
		return $orderby;
140
	}
140
	}
141
 
141
 
142
	public function getLimit() {
142
	public function getLimit() {
143
		return 'LIMIT '.$this->parametres['navigation.depart'].','.$this->parametres['navigation.limite'].' ';
143
		return 'LIMIT '.$this->parametres['navigation.depart'].','.$this->parametres['navigation.limite'].' ';
144
	}
144
	}
145
 
145
 
146
	/**
146
	/**
147
 
147
 
148
	 *
148
	 *
149
	 * @param $p les paramètres (notamment de masque) passés par l'URL et déjà traités/filtrés (sauf quotes)
149
	 * @param $p les paramètres (notamment de masque) passés par l'URL et déjà traités/filtrés (sauf quotes)
150
	 * @param $req le tableau, passé par référence représentant les composants de la requête à bâtir
150
	 * @param $req le tableau, passé par référence représentant les composants de la requête à bâtir
151
	 */
151
	 */
152
	public function ajouterContraintes() {
152
	public function ajouterContraintes() {
153
		$this->ajouterContrainteAuteur();
153
		$this->ajouterContrainteAuteur();
154
		$this->ajouterContrainteDate();
154
		$this->ajouterContrainteDate();
155
		$this->ajouterContrainteDepartement();
155
		$this->ajouterContrainteDepartement();
156
		$this->ajouterContrainteIdZoneGeo();
156
		$this->ajouterContrainteIdZoneGeo();
157
		$this->ajouterContrainteGenre();
157
		$this->ajouterContrainteGenre();
158
		$this->ajouterContrainteFamille();
158
		$this->ajouterContrainteFamille();
159
		$this->ajouterContrainteNs();
159
		$this->ajouterContrainteNs();
160
		$this->ajouterContrainteNn();
160
		$this->ajouterContrainteNn();
161
		$this->ajouterContrainteReferentiel();
161
		$this->ajouterContrainteReferentiel();
162
		$this->ajouterContrainteCommune();
162
		$this->ajouterContrainteCommune();
163
	}
163
	}
164
 
164
 
165
	private function ajouterContrainteAuteur() {
165
	private function ajouterContrainteAuteur() {
166
		if (isset($this->parametres['masque.auteur'])) {
166
		if (isset($this->parametres['masque.auteur'])) {
167
			$auteur = $this->parametres['masque.auteur'];
167
			$auteur = $this->parametres['masque.auteur'];
168
			// id du poster de l'obs
168
			// id du poster de l'obs
169
			$prefixe = $this->getPrefixe();
169
			$prefixe = $this->getPrefixe();
170
			$this->addJoin("LEFT JOIN del_utilisateur AS du ON (du.id_utilisateur = $prefixe.ce_utilisateur) ");
170
			$this->addJoin("LEFT JOIN del_utilisateur AS du ON (du.id_utilisateur = $prefixe.ce_utilisateur) ");
171
 
171
 
172
			if (is_numeric($auteur)) {
172
			if (is_numeric($auteur)) {
173
				$this->ajouterContrainteAuteurId();
173
				$this->ajouterContrainteAuteurId();
174
			} elseif(preg_match('/@[a-z0-9-]+(?:\.[a-z0-9-]+)*\.[a-z]{2,}$/i', $auteur)) {
174
			} elseif(preg_match('/@[a-z0-9-]+(?:\.[a-z0-9-]+)*\.[a-z]{2,}$/i', $auteur)) {
175
				$this->ajouterContrainteAuteurEmail();
175
				$this->ajouterContrainteAuteurEmail();
176
			} else {
176
			} else {
177
				$this->ajouterContrainteAuteurIntitule();
177
				$this->ajouterContrainteAuteurIntitule();
178
			}
178
			}
179
		}
179
		}
180
	}
180
	}
181
 
181
 
182
	private function ajouterContrainteAuteurId() {
182
	private function ajouterContrainteAuteurId() {
183
		$id = $this->parametres['masque.auteur'];
183
		$id = $this->parametres['masque.auteur'];
184
		$prefixe = $this->getPrefixe();
184
		$prefixe = $this->getPrefixe();
185
		$sqlTpl = "(du.id_utilisateur = %1\$d OR $prefixe.ce_utilisateur = %1\$d)";
185
		$sqlTpl = "(du.id_utilisateur = %1\$d OR $prefixe.ce_utilisateur = %1\$d)";
186
		$whereAuteur = sprintf($sqlTpl, $id);
186
		$whereAuteur = sprintf($sqlTpl, $id);
187
		$this->addWhere('masque.auteur', $whereAuteur);
187
		$this->addWhere('masque.auteur', $whereAuteur);
188
	}
188
	}
189
 
189
 
190
	private function ajouterContrainteAuteurEmail() {
190
	private function ajouterContrainteAuteurEmail() {
191
		$email = $this->parametres['masque.auteur'];
191
		$email = $this->parametres['masque.auteur'];
192
		$prefixe = $this->getPrefixe();
192
		$prefixe = $this->getPrefixe();
193
		$sqlTpl = "(du.courriel LIKE %1\$s OR $prefixe.courriel_utilisateur LIKE %1\$s )";
193
		$sqlTpl = "(du.courriel LIKE %1\$s OR $prefixe.courriel_utilisateur LIKE %1\$s )";
194
		$emailP = $this->bdd->proteger("$email%");
194
		$emailP = $this->bdd->proteger("$email%");
195
		$whereAuteur = sprintf($sqlTpl, $emailP);
195
		$whereAuteur = sprintf($sqlTpl, $emailP);
196
		$this->addWhere('masque.auteur', $whereAuteur);
196
		$this->addWhere('masque.auteur', $whereAuteur);
197
	}
197
	}
198
 
198
 
199
	/**
199
	/**
200
	 * Retourne une clause where du style:
200
	 * Retourne une clause where du style:
201
	 * CONCAT(IF(du.prenom IS NULL, "", du.prenom), [...] vdi.i_nomutilisateur) REGEXP 'xxx'
201
	 * CONCAT(IF(du.prenom IS NULL, "", du.prenom), [...] vdi.i_nomutilisateur) REGEXP 'xxx'
202
	 */
202
	 */
203
	private function ajouterContrainteAuteurIntitule() {
203
	private function ajouterContrainteAuteurIntitule() {
204
		$auteurExplode = explode(' ', $this->parametres['masque.auteur']);
204
		$auteurExplode = explode(' ', $this->parametres['masque.auteur']);
205
		$nbreMots = count($auteurExplode);
205
		$nbreMots = count($auteurExplode);
206
 
206
 
207
		if ($nbreMots == 1) {
207
		if ($nbreMots == 1) {
208
			$this->ajouterContrainteAuteurPrenomOuNom();
208
			$this->ajouterContrainteAuteurPrenomOuNom();
209
		} else if ($nbreMots == 2) {
209
		} else if ($nbreMots == 2) {
210
			$this->ajouterContrainteAuteurPrenomEtNom();
210
			$this->ajouterContrainteAuteurPrenomEtNom();
211
		}
211
		}
212
	}
212
	}
213
 
213
 
214
	private function ajouterContrainteAuteurPrenomOuNom() {
214
	private function ajouterContrainteAuteurPrenomOuNom() {
215
		$prenomOuNom = $this->parametres['masque.auteur'];
215
		$prenomOuNom = $this->parametres['masque.auteur'];
216
 
216
 
217
		$sqlTpl = 'CONCAT(%s,%s) LIKE %s';
217
		$sqlTpl = 'CONCAT(%s,%s) LIKE %s';
218
		$prefixe = $this->getPrefixe();
218
		$prefixe = $this->getPrefixe();
219
		$champsPrenomSql = self::ajouterIfNullPourConcat($this->champsPrenom, $prefixe);
219
		$champsPrenomSql = self::ajouterIfNullPourConcat($this->champsPrenom, $prefixe);
220
		$champsNomSql = self::ajouterIfNullPourConcat($this->champsNom, $prefixe);
220
		$champsNomSql = self::ajouterIfNullPourConcat($this->champsNom, $prefixe);
221
		$auteurMotif = $this->bdd->proteger("%$prenomOuNom%");
221
		$auteurMotif = $this->bdd->proteger("%$prenomOuNom%");
222
 
222
 
223
		$auteurWhere = sprintf($sqlTpl, $champsPrenomSql, $champsNomSql, $auteurMotif);
223
		$auteurWhere = sprintf($sqlTpl, $champsPrenomSql, $champsNomSql, $auteurMotif);
224
		$this->addWhere('masque.auteur', $auteurWhere);
224
		$this->addWhere('masque.auteur', $auteurWhere);
225
	}
225
	}
226
 
226
 
227
	private function ajouterContrainteAuteurPrenomEtNom() {
227
	private function ajouterContrainteAuteurPrenomEtNom() {
228
		list($prenom, $nom) = explode(' ', $this->parametres['masque.auteur']);
228
		list($prenom, $nom) = explode(' ', $this->parametres['masque.auteur']);
229
 
229
 
230
		$sqlTpl = '(CONCAT(%1$s,%2$s) LIKE %3$s AND CONCAT(%1$s,%2$s) LIKE %4$s)';
230
		$sqlTpl = '(CONCAT(%1$s,%2$s) LIKE %3$s AND CONCAT(%1$s,%2$s) LIKE %4$s)';
231
		$prefixe = $this->getPrefixe();
231
		$prefixe = $this->getPrefixe();
232
		$champsPrenomSql = self::ajouterIfNullPourConcat($this->champsPrenom, $prefixe);
232
		$champsPrenomSql = self::ajouterIfNullPourConcat($this->champsPrenom, $prefixe);
233
		$champsNomSql = self::ajouterIfNullPourConcat($this->champsNom, $prefixe);
233
		$champsNomSql = self::ajouterIfNullPourConcat($this->champsNom, $prefixe);
234
		$prenomMotif = $this->bdd->proteger("%$prenom%");
234
		$prenomMotif = $this->bdd->proteger("%$prenom%");
235
		$nomMotif = $this->bdd->proteger("%$nom%");
235
		$nomMotif = $this->bdd->proteger("%$nom%");
236
 
236
 
237
		$auteurWhere = sprintf($sqlTpl, $champsPrenomSql, $champsNomSql, $prenomMotif, $nomMotif);
237
		$auteurWhere = sprintf($sqlTpl, $champsPrenomSql, $champsNomSql, $prenomMotif, $nomMotif);
238
		$this->addWhere('masque.auteur', $auteurWhere);
238
		$this->addWhere('masque.auteur', $auteurWhere);
239
	}
239
	}
240
 
240
 
241
	/**
241
	/**
242
	 * Lorsque l'on concatène des champs, un seul NULL prend le dessus.
242
	 * Lorsque l'on concatène des champs, un seul NULL prend le dessus.
243
	 * Il faut donc utiliser la syntaxe IFNULL(%s, "").
243
	 * Il faut donc utiliser la syntaxe IFNULL(%s, "").
244
	 * Cette fonction effectue aussi l'implode() "final".
244
	 * Cette fonction effectue aussi l'implode() "final".
245
	 */
245
	 */
246
	private static function ajouterIfNullPourConcat($champs, $prefixe) {
246
	private static function ajouterIfNullPourConcat($champs, $prefixe) {
247
		$champsProteges = array();
247
		$champsProteges = array();
248
		foreach ($champs as $champ) {
248
		foreach ($champs as $champ) {
249
			if (strstr($champ, '.') === false) {
249
			if (strstr($champ, '.') === false) {
250
				$champ = "$prefixe.$champ";
250
				$champ = "$prefixe.$champ";
251
			}
251
			}
252
			$champsProteges[] = "IFNULL($champ, '')";
252
			$champsProteges[] = "IFNULL($champ, '')";
253
		}
253
		}
254
		return implode(',', $champsProteges);
254
		return implode(',', $champsProteges);
255
	}
255
	}
256
 
256
 
257
	private function ajouterContrainteDate() {
257
	private function ajouterContrainteDate() {
258
		if (isset($this->parametres['masque.date'])) {
258
		if (isset($this->parametres['masque.date'])) {
259
			$date = $this->parametres['masque.date'];
259
			$date = $this->parametres['masque.date'];
260
			if (preg_match('/^\d{4}$/', $date) && $date < 2030 && $date > 1600) {
260
			if (preg_match('/^\d{4}$/', $date) && $date < 2030 && $date > 1600) {
261
				$sqlTpl = "YEAR(do.date_observation) = %d";
261
				$sqlTpl = "YEAR(do.date_observation) = %d";
262
				$dateWhere = sprintf($sqlTpl, $date);
262
				$dateWhere = sprintf($sqlTpl, $date);
263
				$this->addWhere('masque.date', $dateWhere);
263
				$this->addWhere('masque.date', $dateWhere);
264
			} else {
264
			} else {
265
				$sqlTpl = "do.date_observation = %s";
265
				$sqlTpl = "do.date_observation = %s";
266
				$dateP = $this->bdd->proteger($date);
266
				$dateP = $this->bdd->proteger($date);
267
				$dateWhere = sprintf($sqlTpl, $dateP);
267
				$dateWhere = sprintf($sqlTpl, $dateP);
268
				$this->addWhere('masque.date', $dateWhere);
268
				$this->addWhere('masque.date', $dateWhere);
269
			}
269
			}
270
 
270
 
271
			if ($this->etreAppliImg()) {
271
			if ($this->etreAppliImg()) {
272
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
272
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
273
			}
273
			}
274
		}
274
		}
275
	}
275
	}
276
 
276
 
277
	private function ajouterContrainteDepartement() {
277
	private function ajouterContrainteDepartement() {
278
		if (isset($this->parametres['masque.departement'])) {
278
		if (isset($this->parametres['masque.departement'])) {
279
			$dept = $this->parametres['masque.departement'];
279
			$dept = $this->parametres['masque.departement'];
280
			$deptMotif = $this->bdd->proteger("INSEE-C:$dept");
280
			$deptMotif = $this->bdd->proteger("INSEE-C:$dept");
281
			$this->addWhere('masque.departement', "do.ce_zone_geo LIKE $deptMotif");
281
			$this->addWhere('masque.departement', "do.ce_zone_geo LIKE $deptMotif");
282
 
282
 
283
			if ($this->etreAppliImg()) {
283
			if ($this->etreAppliImg()) {
284
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
284
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
285
			}
285
			}
286
		}
286
		}
287
	}
287
	}
288
 
288
 
289
	private function ajouterContrainteIdZoneGeo() {
289
	private function ajouterContrainteIdZoneGeo() {
290
		if (isset($this->parametres['masque.id_zone_geo'])) {
290
		if (isset($this->parametres['masque.id_zone_geo'])) {
291
			$idZgMotif = $this->bdd->proteger($this->parametres['masque.id_zone_geo']);
291
			$idZgMotif = $this->bdd->proteger($this->parametres['masque.id_zone_geo']);
292
			$this->addWhere('masque.id_zone_geo', "do.ce_zone_geo = $idZgMotif");
292
			$this->addWhere('masque.id_zone_geo', "do.ce_zone_geo = $idZgMotif");
293
 
293
 
294
			if ($this->etreAppliImg()) {
294
			if ($this->etreAppliImg()) {
295
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
295
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
296
			}
296
			}
297
		}
297
		}
298
	}
298
	}
299
 
299
 
300
	private function ajouterContrainteGenre() {
300
	private function ajouterContrainteGenre() {
301
		if (isset($this->parametres['masque.genre'])) {
301
		if (isset($this->parametres['masque.genre'])) {
302
			$genre = $this->parametres['masque.genre'];
302
			$genre = $this->parametres['masque.genre'];
303
			$genreMotif = $this->bdd->proteger("%$genre% %");
303
			$genreMotif = $this->bdd->proteger("%$genre% %");
304
			$this->addWhere('masque.genre', "do.nom_sel LIKE $genreMotif");
304
			$this->addWhere('masque.genre', "do.nom_sel LIKE $genreMotif");
305
 
305
 
306
			if ($this->etreAppliImg()) {
306
			if ($this->etreAppliImg()) {
307
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
307
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
308
			}
308
			}
309
		}
309
		}
310
	}
310
	}
311
 
311
 
312
	private function ajouterContrainteFamille() {
312
	private function ajouterContrainteFamille() {
313
		if (isset($this->parametres['masque.famille'])) {
313
		if (isset($this->parametres['masque.famille'])) {
314
			$familleMotif = $this->bdd->proteger($this->parametres['masque.famille']);
314
			$familleMotif = $this->bdd->proteger($this->parametres['masque.famille']);
315
			$this->addWhere('masque.famille', "do.famille = $familleMotif");
315
			$this->addWhere('masque.famille', "do.famille = $familleMotif");
316
 
316
 
317
			if ($this->etreAppliImg()) {
317
			if ($this->etreAppliImg()) {
318
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
318
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
319
			}
319
			}
320
		}
320
		}
321
	}
321
	}
322
 
322
 
323
	private function ajouterContrainteNs() {
323
	private function ajouterContrainteNs() {
324
		if (isset($this->parametres['masque.ns'])) {
324
		if (isset($this->parametres['masque.ns'])) {
325
			$ns = $this->parametres['masque.ns'];
325
			$ns = $this->parametres['masque.ns'];
326
			$nsMotif = $this->bdd->proteger("$ns%");
326
			$nsMotif = $this->bdd->proteger("$ns%");
327
			$this->addWhere('masque.ns', "do.nom_sel LIKE $nsMotif");
327
			$this->addWhere('masque.ns', "do.nom_sel LIKE $nsMotif");
328
 
328
 
329
			if ($this->etreAppliImg()) {
329
			if ($this->etreAppliImg()) {
330
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
330
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
331
			}
331
			}
332
		}
332
		}
333
	}
333
	}
334
 
334
 
335
	private function ajouterContrainteNn() {
335
	private function ajouterContrainteNn() {
336
		if (isset($this->parametres['masque.nn'])) {
336
		if (isset($this->parametres['masque.nn'])) {
337
			$sqlTpl = '(do.nom_sel_nn = %1$d OR do.nom_ret_nn = %1$d)';
337
			$sqlTpl = '(do.nom_sel_nn = %1$d OR do.nom_ret_nn = %1$d)';
338
			$nnWhere = sprintf($sqlTpl, $this->parametres['masque.nn']);
338
			$nnWhere = sprintf($sqlTpl, $this->parametres['masque.nn']);
339
			$this->addWhere('masque.nn', $nnWhere);
339
			$this->addWhere('masque.nn', $nnWhere);
340
 
340
 
341
			if ($this->etreAppliImg()) {
341
			if ($this->etreAppliImg()) {
342
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
342
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
343
			}
343
			}
344
		}
344
		}
345
	}
345
	}
346
 
346
 
347
	private function ajouterContrainteReferentiel() {
347
	private function ajouterContrainteReferentiel() {
348
		if (isset($this->parametres['masque.referentiel'])) {
348
		if (isset($this->parametres['masque.referentiel'])) {
349
			$ref = $this->parametres['masque.referentiel'];
349
			$ref = $this->parametres['masque.referentiel'];
350
			$refMotif = $this->bdd->proteger("$ref%");
350
			$refMotif = $this->bdd->proteger("$ref%");
351
			$this->addWhere('masque.referentiel', "do.nom_referentiel LIKE $refMotif");
351
			$this->addWhere('masque.referentiel', "do.nom_referentiel LIKE $refMotif");
352
 
352
 
353
			if ($this->etreAppliImg()) {
353
			if ($this->etreAppliImg()) {
354
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
354
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
355
			}
355
			}
356
		}
356
		}
357
	}
357
	}
358
 
358
 
359
	private function ajouterContrainteCommune() {
359
	private function ajouterContrainteCommune() {
360
		if (isset($this->parametres['masque.commune'])) {
360
		if (isset($this->parametres['masque.commune'])) {
361
			$commune = $this->parametres['masque.commune'];
361
			$commune = $this->parametres['masque.commune'];
362
			$communeMotif = $this->bdd->proteger("$commune%");
362
			$communeMotif = $this->bdd->proteger("$commune%");
363
			$this->addWhere('masque.commune', "do.zone_geo LIKE $communeMotif");
363
			$this->addWhere('masque.commune', "do.zone_geo LIKE $communeMotif");
364
 
364
 
365
			if ($this->etreAppliImg()) {
365
			if ($this->etreAppliImg()) {
366
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
366
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
367
			}
367
			}
368
		}
368
		}
369
	}
369
	}
370
 
370
 
371
	public function ajouterConstrainteAppliObs() {
371
	public function ajouterConstrainteAppliObs() {
372
		$this->ajouterContrainteTagCel();
372
		$this->ajouterContrainteTagCel();
373
		$this->ajouterContrainteType();
373
		$this->ajouterContrainteType();
374
		// TODO : ATTENTION -> vue que l'on utilise une vue basée sur les images, nous devons grouper par obs
374
		// TODO : ATTENTION -> vue que l'on utilise une vue basée sur les images, nous devons grouper par obs
375
		$this->addGroupBy('do.id_observation');
375
		$this->addGroupBy('do.id_observation');
376
	}
376
	}
377
 
377
 
378
	private function ajouterContrainteType() {
378
	private function ajouterContrainteType() {
379
		if (isset($this->parametres['masque.type'])) {
379
		if (isset($this->parametres['masque.type'])) {
380
			if (array_key_exists('adeterminer', $this->parametres['masque.type'])) {
380
			if (array_key_exists('adeterminer', $this->parametres['masque.type'])) {
381
				// Récupèration de toutes les observations qui on le tag "aDeterminer" *ou* qui n'ont pas de nom d'espèce
381
				// Récupèration de toutes les observations qui on le tag "aDeterminer" *ou* qui n'ont pas de nom d'espèce
382
				// *ou* qui ont la "certitude" à ("aDeterminer" *ou* "douteux")
382
				// *ou* qui ont la "certitude" à ("aDeterminer" *ou* "douteux")
383
				$this->addWhere('masque.type', '('.
383
				$this->addWhere('masque.type', '('.
384
					'do.certitude = "aDeterminer" '.
384
					'do.certitude = "aDeterminer" '.
385
					'OR do.certitude = "douteux" '.
385
					'OR do.certitude = "douteux" '.
386
					'OR do.mots_cles_texte LIKE "%aDeterminer%" '.
386
					'OR do.mots_cles_texte LIKE "%aDeterminer%" '.
387
					'OR do.nom_sel_nn IS NULL '.
387
					'OR do.nom_sel_nn IS NULL '.
388
					'OR do.nom_sel_nn = 0 '.// il ne DEVRAIT pas y avoir d'entrées à 0, mais il y en a quand-même !!
388
					'OR do.nom_sel_nn = 0 '.// il ne DEVRAIT pas y avoir d'entrées à 0, mais il y en a quand-même !!
389
					')');
389
					')');
390
			}
390
			}
391
			if (array_key_exists('validees', $this->parametres['masque.type'])) {
391
			if (array_key_exists('validees', $this->parametres['masque.type'])) {
392
				// Récupèration de toutes les observations ayant un commentaire doté de proposition_retenue = 1
392
				// Récupèration de toutes les observations ayant un commentaire doté de proposition_retenue = 1
393
				$this->addJoin('INNER JOIN del_commentaire AS dc '.
393
				$this->addJoin('INNER JOIN del_commentaire AS dc '.
394
					'ON (do.id_observation = dc.ce_observation AND dc.proposition_retenue = 1) ');
394
					'ON (do.id_observation = dc.ce_observation AND dc.proposition_retenue = 1) ');
395
			}
395
			}
396
 
396
 
397
			if (array_key_exists('endiscussion', $this->parametres['masque.type'])) {
397
			if (array_key_exists('endiscussion', $this->parametres['masque.type'])) {
398
				$nbreCommentaire =(int) ($this->conteneur->getParametre('observations.nb_commentaires_discussion'));
398
				$nbreCommentaire =(int) ($this->conteneur->getParametre('observations.nb_commentaires_discussion'));
399
				$this->addWhere('masque.type', '(SELECT COUNT(id_commentaire) FROM del_commentaire AS dc '.
399
				$this->addWhere('masque.type', '(SELECT COUNT(id_commentaire) FROM del_commentaire AS dc '.
400
					"WHERE ce_observation = id_observation) > $nbreCommentaire ");
400
					"WHERE ce_observation = id_observation) > $nbreCommentaire ");
401
			}
401
			}
402
 
402
 
403
			if ($this->etreAppliImg()) {
403
			if ($this->etreAppliImg()) {
404
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
404
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
405
			}
405
			}
406
		}
406
		}
407
	}
407
	}
408
 
408
 
409
	public function ajouterConstrainteAppliImg() {
409
	public function ajouterConstrainteAppliImg() {
410
		$this->ajouterContrainteMilieu();
410
		$this->ajouterContrainteMilieu();
411
		$this->ajouterContrainteTri();
411
		$this->ajouterContrainteTri();
412
		$this->ajouterContrainteTagCel();
412
		$this->ajouterContrainteTagCel();
413
		$this->ajouterContrainteTagDel();
413
		$this->ajouterContrainteTagDel();
414
	}
414
	}
415
 
415
 
416
	private function ajouterContrainteMilieu() {
416
	private function ajouterContrainteMilieu() {
417
		if (isset($this->parametres['masque.milieu'])) {
417
		if (isset($this->parametres['masque.milieu'])) {
418
			$milieu = $this->parametres['masque.milieu'];
418
			$milieu = $this->parametres['masque.milieu'];
419
			$milieuMotif = $this->bdd->proteger("%$milieu%");
419
			$milieuMotif = $this->bdd->proteger("%$milieu%");
420
			$this->addWhere('masque.milieu', "do.milieu LIKE $milieuMotif");
420
			$this->addWhere('masque.milieu', "do.milieu LIKE $milieuMotif");
421
 
421
 
422
			if ($this->etreAppliImg()) {
422
			if ($this->etreAppliImg()) {
423
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
423
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
424
			}
424
			}
425
		}
425
		}
426
	}
426
	}
427
 
427
 
428
	private function ajouterContrainteTri() {
428
	private function ajouterContrainteTri() {
429
		if (isset($this->parametres['tri'])) {
429
		if (isset($this->parametres['tri'])) {
430
			$tri = $this->parametres['tri'];
430
			$tri = $this->parametres['tri'];
431
 
431
 
432
			if (isset($this->parametres['protocole'])  && ($tri == 'moyenne-arithmetique' || $tri == 'points')) {
432
			if (isset($this->parametres['protocole'])  && ($tri == 'moyenne-arithmetique' || $tri == 'points')) {
433
				// $this->parametres['protocole'] *est* défini (cf Outils::filtrerUrlsParams...())
433
				// $this->parametres['protocole'] *est* défini (cf Outils::filtrerUrlsParams...())
434
				$sqlTpl = 'LEFT JOIN del_image_stat AS dis ON di.id_image = dis.ce_image AND dis.ce_protocole = %d';
434
				$sqlTpl = 'LEFT JOIN del_image_stat AS dis ON di.id_image = dis.ce_image AND dis.ce_protocole = %d';
435
				$triSql = sprintf($sqlTpl, $this->parametres['protocole']);
435
				$triSql = sprintf($sqlTpl, $this->parametres['protocole']);
436
				$this->addJoinDis($triSql);
436
				$this->addJoinDis($triSql);
437
			}
437
			}
438
 
438
 
439
			if (isset($this->parametres['ordre']) && $tri == 'tags') {
439
			if (isset($this->parametres['ordre']) && $tri == 'tags') {
440
				$typeJointure = ($this->parametres['ordre'] == 'desc') ? 'INNER' : 'LEFT';
440
				$typeJointure = ($this->parametres['ordre'] == 'desc') ? 'INNER' : 'LEFT';
441
				$this->addJoin("$typeJointure JOIN del_image_stat AS dis ON di.id_image = dis.ce_image");
441
				$this->addJoin("$typeJointure JOIN del_image_stat AS dis ON di.id_image = dis.ce_image");
442
				// nécessaire (dup ce_image dans del_image_stat)
442
				// nécessaire (dup ce_image dans del_image_stat)
443
				$this->addGroupBy('di.ce_observation');
443
				$this->addGroupBy('di.ce_observation');
444
			}
444
			}
445
		}
445
		}
446
	}
446
	}
447
 
447
 
448
	private function ajouterContrainteTagCel() {
448
	private function ajouterContrainteTagCel() {
449
		if (isset($this->parametres['masque.tag_cel'])) {
449
		if (isset($this->parametres['masque.tag_cel'])) {
450
			if (isset($this->parametres['masque.tag_cel']['AND'])) {
450
			if (isset($this->parametres['masque.tag_cel']['AND'])) {
451
				$tags = $this->parametres['masque.tag_cel']['AND'];
451
				$tags = $this->parametres['masque.tag_cel']['AND'];
452
				$clausesWhere = array();
452
				$clausesWhere = array();
453
				foreach ($tags as $tag) {
453
				foreach ($tags as $tag) {
454
					$tagMotif = $this->bdd->proteger("%$tag%");
454
					$tagMotif = $this->bdd->proteger("%$tag%");
455
					$sqlTpl = "CONCAT(IFNULL(do.mots_cles_texte,''),IFNULL(di.mots_cles_texte,'')) LIKE %s";
455
					$sqlTpl = "CONCAT(IFNULL(do.mots_cles_texte,''),IFNULL(di.mots_cles_texte,'')) LIKE %s";
456
					$clausesWhere[] = sprintf($sqlTpl, $tagMotif);
456
					$clausesWhere[] = sprintf($sqlTpl, $tagMotif);
457
				}
457
				}
458
				$whereTags = implode(' AND ', $clausesWhere);
458
				$whereTags = implode(' AND ', $clausesWhere);
459
				$this->addWhere('masque.tag_cel', "($whereTags)");
459
				$this->addWhere('masque.tag_cel', "($whereTags)");
460
			} else if (isset($this->parametres['masque.tag_cel']['OR'])) {
460
			} else if (isset($this->parametres['masque.tag_cel']['OR'])) {
461
				$tags = $this->parametres['masque.tag_cel']['OR'];
461
				$tags = $this->parametres['masque.tag_cel']['OR'];
462
				$sqlTpl = "CONCAT(IFNULL(do.mots_cles_texte,''),IFNULL(di.mots_cles_texte,'')) REGEXP %s";
462
				$sqlTpl = "CONCAT(IFNULL(do.mots_cles_texte,''),IFNULL(di.mots_cles_texte,'')) REGEXP %s";
463
				$tagMotif = $this->bdd->proteger(implode('|', $tags));
463
				$tagMotif = $this->bdd->proteger(implode('|', $tags));
464
				$tagSql = sprintf($sqlTpl, $tagMotif);
464
				$tagSql = sprintf($sqlTpl, $tagMotif);
465
				$this->addWhere('masque.tag_cel', $tagSql);
465
				$this->addWhere('masque.tag_cel', $tagSql);
466
			}
466
			}
467
			if ($this->etreAppliImg()) {
467
			if ($this->etreAppliImg()) {
468
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
468
				$this->addJoin('LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ');
469
			}
469
			}
470
			if ($this->etreAppliObs()) {
470
			if ($this->etreAppliObs()) {
471
				$this->addJoin('LEFT JOIN del_image AS di ON (do.id_observation = di.ce_observation) ');
471
				$this->addJoin('LEFT JOIN del_image AS di ON (do.id_observation = di.ce_observation) ');
472
			}
472
			}
473
		}
473
		}
474
	}
474
	}
475
 
475
 
476
	/**
476
	/**
477
	 * Plusieurs solutions sont disponibles dans les anciennes versions (voir DelTk et l'historique SVN de ce fichier).
477
	 * Plusieurs solutions sont disponibles dans les anciennes versions (voir DelTk et l'historique SVN de ce fichier).
478
	 */
478
	 */
479
	private function ajouterContrainteTagDel() {
479
	private function ajouterContrainteTagDel() {
480
		if (isset($this->parametres['masque.tag_del'])) {
480
		if (isset($this->parametres['masque.tag_del'])) {
481
			if (isset($this->parametres['masque.tag_del']['AND'])) {
481
			if (isset($this->parametres['masque.tag_del']['AND'])) {
482
				$tags = $this->parametres['masque.tag_del']['AND'];
482
				$tags = $this->parametres['masque.tag_del']['AND'];
483
				// optimisation: en cas de "AND" on sort() l'input et le GROUP_CONCAT()
483
				// optimisation: en cas de "AND" on sort() l'input et le GROUP_CONCAT()
484
				// donc nous utilisons des ".*" plutôt que de multiples conditions et "|"
484
				// donc nous utilisons des ".*" plutôt que de multiples conditions et "|"
485
				sort($tags);
485
				sort($tags);
486
				$tagsMotif = $this->bdd->proteger(implode('.*', $tags));
486
				$tagsMotif = $this->bdd->proteger(implode('.*', $tags));
487
				$requete = 'SELECT ce_image '.
487
				$requete = 'SELECT ce_image '.
488
					'FROM del_image_tag '.
488
					'FROM del_image_tag '.
489
					'WHERE actif = 1 '.
489
					'WHERE actif = 1 '.
490
					'GROUP BY ce_image '.
490
					'GROUP BY ce_image '.
491
					"HAVING GROUP_CONCAT(tag_normalise ORDER BY tag_normalise) REGEXP $tagsMotif ".
491
					"HAVING GROUP_CONCAT(tag_normalise ORDER BY tag_normalise) REGEXP $tagsMotif ".
492
					' -- '.__FILE__.' : '.__LINE__;
492
					' -- '.__FILE__.' : '.__LINE__;
493
				$sql = $this->recupererSqlContrainteTag($requete);
493
				$sql = $this->recupererSqlContrainteTag($requete);
494
				$this->addWhere('masque.tag_del', $sql);
494
				$this->addWhere('masque.tag_del', $sql);
495
 
495
 
496
			} else if (isset($this->parametres['masque.tag_del']['OR'])) {
496
			} else if (isset($this->parametres['masque.tag_del']['OR'])) {
497
				$tags = $this->parametres['masque.tag_del']['OR'];
497
				$tags = $this->parametres['masque.tag_del']['OR'];
498
				$tagsMotif = $this->bdd->proteger(implode('|', $tags));
498
				$tagsMotif = $this->bdd->proteger(implode('|', $tags));
499
				$requete = 'SELECT ce_image '.
499
				$requete = 'SELECT ce_image '.
500
					'FROM del_image_tag '.
500
					'FROM del_image_tag '.
501
					'WHERE actif = 1 '.
501
					'WHERE actif = 1 '.
502
					'GROUP BY ce_image '.
502
					'GROUP BY ce_image '.
503
					"HAVING GROUP_CONCAT(tag_normalise) REGEXP $tagsMotif ".
503
					"HAVING GROUP_CONCAT(tag_normalise) REGEXP $tagsMotif ".
504
					' -- '.__FILE__.' : '.__LINE__;
504
					' -- '.__FILE__.' : '.__LINE__;
505
 
505
 
506
				$sql = $this->recupererSqlContrainteTag($requete);
506
				$sql = $this->recupererSqlContrainteTag($requete);
507
				$this->addWhere('masque.tag_del', $sql);
507
				$this->addWhere('masque.tag_del', $sql);
508
			}
508
			}
509
		}
509
		}
510
	}
510
	}
511
 
511
 
512
	private function recupererSqlContrainteTag($requete) {
512
	private function recupererSqlContrainteTag($requete) {
513
		$resultats = $this->bdd->recupererTous($requete);
513
		$resultats = $this->bdd->recupererTous($requete);
514
		$ids = array();
514
		$ids = array();
515
		foreach ($resultats as $resultat) {
515
		foreach ($resultats as $resultat) {
516
			$ids[] = $resultat['ce_image'];
516
			$ids[] = $resultat['ce_image'];
517
		}
517
		}
518
 
518
 
519
		if (!empty($ids)) {
519
		if (!empty($ids)) {
520
			$clauseIn = implode(',', $ids);
520
			$clauseIn = implode(',', $ids);
521
		} else {
521
		} else {
522
			$clauseIn = 'SELECT ce_image FROM del_image_tag WHERE false';
522
			$clauseIn = 'SELECT ce_image FROM del_image_tag WHERE false';
523
		}
523
		}
524
		return "di.id_image IN ($clauseIn)";
524
		return "di.id_image IN ($clauseIn)";
525
	}
525
	}
526
 
526
 
527
	/**
527
	/**
528
	 * Partie spécifique à PictoFlora:
528
	 * Partie spécifique à PictoFlora:
529
	 * Attention : si le critère de tri n'est pas suffisant, les résultats affichés peuvent varier à chaque appel
529
	 * Attention : si le critère de tri n'est pas suffisant, les résultats affichés peuvent varier à chaque appel
530
	 * de la même page de résultat de PictoFlora.
530
	 * de la même page de résultat de PictoFlora.
531
	 */
531
	 */
532
	public function definirOrdreSqlAppliImg() {
532
	public function definirOrdreSqlAppliImg() {
533
		$ordre = $this->parametres['ordre'];
533
		$ordre = $this->parametres['ordre'];
534
 
534
 
535
		switch ($this->parametres['tri']) {
535
		switch ($this->parametres['tri']) {
536
			case 'moyenne-arithmetique' :
536
			case 'moyenne-arithmetique' :
537
				$this->addOrderBy("dis.moyenne $ordre, dis.nb_votes $ordre, id_image DESC");
537
				$this->addOrderBy("dis.moyenne $ordre, dis.nb_votes $ordre, id_image $ordre");
538
				break;
538
				break;
539
			case 'points' :
539
			case 'points' :
540
				$this->addOrderBy("dis.nb_points $ordre, dis.moyenne $ordre, dis.nb_votes $ordre, id_image DESC");
540
				$this->addOrderBy("dis.nb_points $ordre, dis.moyenne $ordre, dis.nb_votes $ordre, id_image $ordre");
541
				break;
541
				break;
542
			case 'tags' :
542
			case 'tags' :
543
				$this->addOrderBy("dis.nb_tags $ordre, id_image DESC");
543
				$this->addOrderBy("dis.nb_tags $ordre, id_image $ordre");
544
				break;
544
				break;
545
			case 'date_observation' :
545
			case 'date_observation' :
546
				$this->addOrderBy("date_observation $ordre, ce_observation $ordre");
546
				$this->addOrderBy("date_observation $ordre, ce_observation $ordre");
547
				break;
547
				break;
548
			case 'date_transmission' :
548
			case 'date_transmission' :
549
			default:
549
			default:
550
				$this->addOrderBy("di.date_transmission $ordre, ce_observation $ordre");
550
				$this->addOrderBy("di.date_transmission $ordre, ce_observation $ordre");
551
		}
551
		}
552
	}
552
	}
553
 
553
 
554
	public function definirOrdreSqlAppliObs() {
554
	public function definirOrdreSqlAppliObs() {
555
		$ordre = $this->parametres['ordre'];
555
		$ordre = $this->parametres['ordre'];
556
 
556
 
557
		// parmi self::$tri_possible
557
		// parmi self::$tri_possible
558
		switch ($this->parametres['tri']) {
558
		switch ($this->parametres['tri']) {
559
			case 'date_observation' :
559
			case 'date_observation' :
560
				$this->addOrderBy("date_observation $ordre, id_observation $ordre");
560
				$this->addOrderBy("date_observation $ordre, id_observation $ordre");
561
				break;
561
				break;
562
			default:
562
			default:
563
				$this->addOrderBy("do.date_transmission $ordre, id_observation $ordre");
563
				$this->addOrderBy("do.date_transmission $ordre, id_observation $ordre");
564
		}
564
		}
565
	}
565
	}
566
 
566
 
567
	public function getAliasDesChamps($champsEtAlias, $select = null, $prefix = null) {
567
	public function getAliasDesChamps($champsEtAlias, $select = null, $prefix = null) {
568
		$arr = ($select) ? array_intersect_key($champsEtAlias, array_flip($select)) :  $champsEtAlias;
568
		$arr = ($select) ? array_intersect_key($champsEtAlias, array_flip($select)) :  $champsEtAlias;
569
		$keys = array_keys($arr);
569
		$keys = array_keys($arr);
570
 
570
 
571
		if ($prefix) {
571
		if ($prefix) {
572
			array_walk($keys, create_function('&$val, $k, $prefix', '$val = sprintf("%s.`%s`", $prefix, $val);'), $prefix);
572
			array_walk($keys, create_function('&$val, $k, $prefix', '$val = sprintf("%s.`%s`", $prefix, $val);'), $prefix);
573
		} else {
573
		} else {
574
			array_walk($keys, create_function('&$val, $k', '$val = sprintf("`%s`", $val);'));
574
			array_walk($keys, create_function('&$val, $k', '$val = sprintf("`%s`", $val);'));
575
		}
575
		}
576
 
576
 
577
		return implode(', ', array_map(create_function('$v, $k', 'return sprintf("%s AS `%s`", $k, $v);'), $arr, $keys));
577
		return implode(', ', array_map(create_function('$v, $k', 'return sprintf("%s AS `%s`", $k, $v);'), $arr, $keys));
578
	}
578
	}
579
 
579
 
580
	public function getVotesDesImages($idsImages, $protocole = null) {
580
	public function getVotesDesImages($idsImages, $protocole = null) {
581
		if (!$idsImages) return;
581
		if (!$idsImages) return;
582
 
582
 
583
		$mappingVotes = $this->conteneur->getParametreTableau('votes.mapping');
583
		$mappingVotes = $this->conteneur->getParametreTableau('votes.mapping');
584
		$mappingProtocoles = $this->conteneur->getParametreTableau('protocoles.mapping');
584
		$mappingProtocoles = $this->conteneur->getParametreTableau('protocoles.mapping');
585
 		$selectVotes = array('id_vote', 'ce_image', 'ce_protocole', 'ce_utilisateur', 'valeur', 'date');
585
 		$selectVotes = array('id_vote', 'ce_image', 'ce_protocole', 'ce_utilisateur', 'valeur', 'date');
586
		$selectProtocole = array('id_protocole', 'intitule', 'descriptif', 'tag');
586
		$selectProtocole = array('id_protocole', 'intitule', 'descriptif', 'tag');
587
		$voteChamps = $this->getAliasDesChamps($mappingVotes, $selectVotes, 'v'); // "v": cf alias dans la requête
587
		$voteChamps = $this->getAliasDesChamps($mappingVotes, $selectVotes, 'v'); // "v": cf alias dans la requête
588
		$protoChamps = $this->getAliasDesChamps($mappingProtocoles, $selectProtocole, 'p');
588
		$protoChamps = $this->getAliasDesChamps($mappingProtocoles, $selectProtocole, 'p');
589
		$idImgsConcat = implode(',', $idsImages);
589
		$idImgsConcat = implode(',', $idsImages);
590
 
590
 
591
		$requete = "SELECT $voteChamps, $protoChamps ".
591
		$requete = "SELECT $voteChamps, $protoChamps ".
592
			'FROM del_image_vote AS v '.
592
			'FROM del_image_vote AS v '.
593
			'	INNER JOIN del_image_protocole AS p ON (v.ce_protocole = p.id_protocole) '.
593
			'	INNER JOIN del_image_protocole AS p ON (v.ce_protocole = p.id_protocole) '.
594
			"WHERE v.ce_image IN ($idImgsConcat) ".
594
			"WHERE v.ce_image IN ($idImgsConcat) ".
595
			($protocole ? "	AND v.ce_protocole = $protocole " : '').
595
			($protocole ? "	AND v.ce_protocole = $protocole " : '').
596
			"ORDER BY FIELD(v.ce_image, $idImgsConcat) ".
596
			"ORDER BY FIELD(v.ce_image, $idImgsConcat) ".
597
			'-- '.__FILE__.':'.__LINE__;
597
			'-- '.__FILE__.':'.__LINE__;
598
		return $this->bdd->recupererTous($requete);
598
		return $this->bdd->recupererTous($requete);
599
	}
599
	}
600
 
600
 
601
	/**
601
	/**
602
	 * Ajoute les informations sur le protocole et les votes aux images.
602
	 * Ajoute les informations sur le protocole et les votes aux images.
603
	 *
603
	 *
604
	 * ATTENTION : Subtilité, nous passons ici le tableau d'images indexé par id_image qui est bien
604
	 * ATTENTION : Subtilité, nous passons ici le tableau d'images indexé par id_image qui est bien
605
	 * plus pratique pour associer les vote à un tableau, puisque nous ne connaissons pas les id d'observation.
605
	 * plus pratique pour associer les vote à un tableau, puisque nous ne connaissons pas les id d'observation.
606
	 * Mais magiquement (par référence), cela va remplir notre tableau indexé par couple d'id (id_image, id_observation)
606
	 * Mais magiquement (par référence), cela va remplir notre tableau indexé par couple d'id (id_image, id_observation)
607
	 * cf ListeImages::reformateImagesDoubleIndex() à qui revient la tâche de créer ces deux versions
607
	 * cf ListeImages::reformateImagesDoubleIndex() à qui revient la tâche de créer ces deux versions
608
	 * simultanément lorsque c'est encore possible.
608
	 * simultanément lorsque c'est encore possible.
609
	 */
609
	 */
610
	// TODO : supprimer cette "subtilité" source d'erreurs
610
	// TODO : supprimer cette "subtilité" source d'erreurs
611
	public function ajouterInfosVotesProtocoles($votes, &$images) {
611
	public function ajouterInfosVotesProtocoles($votes, &$images) {
612
		if (!$votes) return;
612
		if (!$votes) return;
613
 
613
 
614
		$mappingVotes = $this->conteneur->getParametreTableau('votes.mapping');
614
		$mappingVotes = $this->conteneur->getParametreTableau('votes.mapping');
615
		$mappingProtocoles = $this->conteneur->getParametreTableau('protocoles.mapping');
615
		$mappingProtocoles = $this->conteneur->getParametreTableau('protocoles.mapping');
616
 
616
 
617
		// pour chaque vote
617
		// pour chaque vote
618
		foreach ($votes as $vote) {
618
		foreach ($votes as $vote) {
619
			$imgId = $vote['image.id'];
619
			$imgId = $vote['image.id'];
620
			$protoId = $vote['protocole.id'];
620
			$protoId = $vote['protocole.id'];
621
 
621
 
622
			if (!array_key_exists('protocoles_votes', $images[$imgId]) ||
622
			if (!array_key_exists('protocoles_votes', $images[$imgId]) ||
623
					!array_key_exists($protoId, $images[$imgId]['protocoles_votes'])) {
623
					!array_key_exists($protoId, $images[$imgId]['protocoles_votes'])) {
624
				// extrait les champs spécifique au protocole (le LEFT JOIN de chargerVotesImage les ramène en doublons
624
				// extrait les champs spécifique au protocole (le LEFT JOIN de chargerVotesImage les ramène en doublons
625
				$protocole = array_intersect_key($vote, array_flip($mappingProtocoles));
625
				$protocole = array_intersect_key($vote, array_flip($mappingProtocoles));
626
				$images[$imgId]['protocoles_votes'][$protoId] = $protocole;
626
				$images[$imgId]['protocoles_votes'][$protoId] = $protocole;
627
			}
627
			}
628
 
628
 
629
			$chpsVotes = array('id_vote', 'ce_image', 'ce_utilisateur', 'valeur', 'date');
629
			$chpsVotes = array('id_vote', 'ce_image', 'ce_utilisateur', 'valeur', 'date');
630
			$voteSelection = array_intersect_key($mappingVotes, array_flip($chpsVotes));
630
			$voteSelection = array_intersect_key($mappingVotes, array_flip($chpsVotes));
631
			$vote = array_intersect_key($vote, array_flip($voteSelection));
631
			$vote = array_intersect_key($vote, array_flip($voteSelection));
632
			$images[$imgId]['protocoles_votes'][$protoId]['votes'][$vote['vote.id']] = $vote;
632
			$images[$imgId]['protocoles_votes'][$protoId]['votes'][$vote['vote.id']] = $vote;
633
		}
633
		}
634
	}
634
	}
635
 
635
 
636
	public function getTotalLignesTrouvees() {
636
	public function getTotalLignesTrouvees() {
637
		$resultat = $this->bdd->recuperer('SELECT FOUND_ROWS() AS nbre');
637
		$resultat = $this->bdd->recuperer('SELECT FOUND_ROWS() AS nbre -- '.__FILE__.':'.__LINE__);
638
		return intval($resultat['nbre']);
638
		return intval($resultat['nbre']);
639
	}
639
	}
640
}
640
}