Subversion Repositories eFlore/Applications.del

Rev

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

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