Subversion Repositories eFlore/Applications.del

Rev

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

Rev 2121 Rev 2140
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('prenom_utilisateur');
47
	private $champsPrenom = array('prenom_utilisateur');
48
	private $champsNom = array('nom_utilisateur');
48
	private $champsNom = array('nom_utilisateur');
49
	private $champsSousRequeteObs = array('masque.genre', 'masque.famille', 'masque.ns', 'masque.commune', 'masque.milieu', 'masque.pays');
49
	private $champsSousRequeteObs = array('masque.genre', 'masque.famille', 'masque.ns', 'masque.commune', 'masque.milieu', 'masque.pays');
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';
74
	}
74
	}
75
 
75
 
76
	private function etreAppliObs() {
76
	private function etreAppliObs() {
77
		return $this->appli === 'OBS' ? true : false;
77
		return $this->appli === 'OBS';
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] = $join;
86
			$this->requete['join'][$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
			if ($this->etreAppliImg() && in_array($idParam, $this->champsSousRequeteObs)) {
101
			if ($this->etreAppliImg() && in_array($idParam, $this->champsSousRequeteObs)) {
102
				$this->requete['where']['OR_SOUS_REQUETE'][] = $where;
102
				$this->requete['where']['OR_SOUS_REQUETE'][] = $where;
103
			} else {
103
			} else {
104
				$this->requete['where']['OR'][] = $where;
104
				$this->requete['where']['OR'][] = $where;
105
			}
105
			}
106
		} else {
106
		} else {
107
			$this->requete['where']['AND'][] = $where;
107
			$this->requete['where']['AND'][] = $where;
108
		}
108
		}
109
	}
109
	}
110
 
110
 
111
	public function getWhere() {
111
	public function getWhere() {
112
		// Sous-requete spéciale pour éviter de rechercher dans la table obs jointe à img depuis Pictoflora...
112
		// Sous-requete spéciale pour éviter de rechercher dans la table obs jointe à img depuis Pictoflora...
113
		if (isset($this->requete['where']['OR_SOUS_REQUETE']) && count($this->requete['where']['OR_SOUS_REQUETE']) > 0) {
113
		if (isset($this->requete['where']['OR_SOUS_REQUETE']) && count($this->requete['where']['OR_SOUS_REQUETE']) > 0) {
114
			$clauseWhereSousRequete = implode(' OR ', $this->requete['where']['OR_SOUS_REQUETE']);
114
			$clauseWhereSousRequete = implode(' OR ', $this->requete['where']['OR_SOUS_REQUETE']);
115
			$sousRequete = 'di.ce_observation IN '.
115
			$sousRequete = 'di.ce_observation IN '.
116
				"(SELECT id_observation FROM del_observation AS do WHERE $clauseWhereSousRequete ) ";
116
				"(SELECT id_observation FROM del_observation AS do WHERE $clauseWhereSousRequete ) ";
117
			$this->requete['where']['OR'][] = "( $sousRequete )";
117
			$this->requete['where']['OR'][] = "( $sousRequete )";
118
			unset($this->requete['join'][$this->getSqlJointureObs()]);
118
			unset($this->requete['join'][$this->getSqlJointureObs()]);
119
		}
119
		}
120
 
120
 
121
		if (isset($this->requete['where']['OR']) && count($this->requete['where']['OR']) > 0) {
121
		if (isset($this->requete['where']['OR']) && count($this->requete['where']['OR']) > 0) {
122
			$this->requete['where']['AND'][] = '('.implode(' OR ', $this->requete['where']['OR']).')';
122
			$this->requete['where']['AND'][] = '('.implode(' OR ', $this->requete['where']['OR']).')';
123
		}
123
		}
124
 
124
 
125
		$where = ' TRUE ';
125
		$where = ' TRUE ';
126
		if (isset($this->requete['where']['AND']) && count($this->requete['where']['AND']) > 0) {
126
		if (isset($this->requete['where']['AND']) && count($this->requete['where']['AND']) > 0) {
127
			$where = implode(' AND ', $this->requete['where']['AND']).' ';
127
			$where = implode(' AND ', $this->requete['where']['AND']).' ';
128
		}
128
		}
129
		return $where;
129
		return $where;
130
	}
130
	}
131
 
131
 
132
	private function addGroupBy($groupBy) {
132
	private function addGroupBy($groupBy) {
133
		$this->requete['groupby'][] = $groupBy;
133
		$this->requete['groupby'][] = $groupBy;
134
	}
134
	}
135
 
135
 
136
	public function getGroupBy() {
136
	public function getGroupBy() {
137
		$groupby = '';
137
		$groupby = '';
138
		if (isset($this->requete['groupby']) && count($this->requete['groupby']) > 0) {
138
		if (isset($this->requete['groupby']) && count($this->requete['groupby']) > 0) {
139
			$groupby = 'GROUP BY '.implode(', ', array_unique($this->requete['groupby'])).' ';
139
			$groupby = 'GROUP BY '.implode(', ', array_unique($this->requete['groupby'])).' ';
140
		}
140
		}
141
		return $groupby;
141
		return $groupby;
142
	}
142
	}
143
 
143
 
144
	private function addOrderBy($orderby) {
144
	private function addOrderBy($orderby) {
145
		$this->requete['orderby'][] = $orderby;
145
		$this->requete['orderby'][] = $orderby;
146
	}
146
	}
147
 
147
 
148
	public function getOrderBy() {
148
	public function getOrderBy() {
149
		$orderby = '';
149
		$orderby = '';
150
		if (isset($this->requete['orderby']) && count($this->requete['orderby']) > 0) {
150
		if (isset($this->requete['orderby']) && count($this->requete['orderby']) > 0) {
151
			$orderby = 'ORDER BY '.implode(', ', array_unique($this->requete['orderby'])).' ';
151
			$orderby = 'ORDER BY '.implode(', ', array_unique($this->requete['orderby'])).' ';
152
		}
152
		}
153
		return $orderby;
153
		return $orderby;
154
	}
154
	}
155
 
155
 
156
	public function getLimit() {
156
	public function getLimit() {
157
		return 'LIMIT '.$this->parametres['navigation.depart'].','.$this->parametres['navigation.limite'].' ';
157
		return 'LIMIT '.$this->parametres['navigation.depart'].','.$this->parametres['navigation.limite'].' ';
158
	}
158
	}
159
 
159
 
160
	/**
160
	/**
161
 
-
 
162
	 *
-
 
163
	 * @param $p les paramètres (notamment de masque) passés par l'URL et déjà traités/filtrés (sauf quotes)
161
	 * @param $p les paramètres (notamment de masque) passés par l'URL et déjà traités/filtrés (sauf quotes)
164
	 * @param $req le tableau, passé par référence représentant les composants de la requête à bâtir
162
	 * @param $req le tableau, passé par référence représentant les composants de la requête à bâtir
165
	 */
163
	 */
166
	public function ajouterContraintes() {
164
	public function ajouterContraintes() {
167
		$this->ajouterContrainteAuteur();
165
		$this->ajouterContrainteAuteur();
168
		$this->ajouterContrainteDate();
166
		$this->ajouterContrainteDate();
169
		$this->ajouterContraintePays();
167
		$this->ajouterContraintePays();
170
		$this->ajouterContrainteDepartement();
168
		$this->ajouterContrainteDepartement();
171
		$this->ajouterContrainteIdZoneGeo();
169
		$this->ajouterContrainteIdZoneGeo();
172
		$this->ajouterContrainteGenre();
170
		$this->ajouterContrainteGenre();
173
		$this->ajouterContrainteFamille();
171
		$this->ajouterContrainteFamille();
174
		$this->ajouterContrainteNs();
172
		$this->ajouterContrainteNs();
175
		$this->ajouterContrainteNn();
173
		$this->ajouterContrainteNn();
176
		$this->ajouterContrainteReferentiel();
174
		$this->ajouterContrainteReferentiel();
177
		$this->ajouterContrainteCommune();
175
		$this->ajouterContrainteCommune();
-
 
176
		$this->ajouterContraintePnInscrits();
178
	}
177
	}
179
 
178
 
180
	private function ajouterContrainteAuteur() {
179
	private function ajouterContrainteAuteur() {
181
		if (isset($this->parametres['masque.auteur'])) {
180
		if (isset($this->parametres['masque.auteur'])) {
182
			$auteur = $this->parametres['masque.auteur'];
181
			$auteur = $this->parametres['masque.auteur'];
183
			// id du poster de l'obs
182
			// id du poster de l'obs
184
			$prefixe = $this->getPrefixe();
183
			$prefixe = $this->getPrefixe();
185
 
184
 
186
			if (is_numeric($auteur)) {
185
			if (is_numeric($auteur)) {
187
				$this->ajouterContrainteAuteurId();
186
				$this->ajouterContrainteAuteurId();
188
			} elseif(preg_match('/@[a-z0-9-]+(?:\.[a-z0-9-]+)*\.[a-z]{2,}$/i', $auteur)) {
187
			} elseif(preg_match('/@[a-z0-9-]+(?:\.[a-z0-9-]+)*\.[a-z]{2,}$/i', $auteur)) {
189
				$this->ajouterContrainteAuteurEmail();
188
				$this->ajouterContrainteAuteurEmail();
190
			} else {
189
			} else {
191
				$this->ajouterContrainteAuteurIntitule();
190
				$this->ajouterContrainteAuteurIntitule();
192
			}
191
			}
193
		}
192
		}
194
	}
193
	}
195
 
194
 
196
	private function ajouterContrainteAuteurId() {
195
	private function ajouterContrainteAuteurId() {
197
		$id = $this->parametres['masque.auteur'];
196
		$id = $this->parametres['masque.auteur'];
198
		$prefixe = $this->getPrefixe();
197
		$prefixe = $this->getPrefixe();
199
		$sqlTpl = "($prefixe.ce_utilisateur = %1\$d)";
198
		$sqlTpl = "($prefixe.ce_utilisateur = %1\$d)";
200
		$whereAuteur = sprintf($sqlTpl, $id);
199
		$whereAuteur = sprintf($sqlTpl, $id);
201
		$this->addWhere('masque.auteur', $whereAuteur);
200
		$this->addWhere('masque.auteur', $whereAuteur);
202
	}
201
	}
203
 
202
 
204
	private function ajouterContrainteAuteurEmail() {
203
	private function ajouterContrainteAuteurEmail() {
205
		$email = $this->parametres['masque.auteur'];
204
		$email = $this->parametres['masque.auteur'];
206
		$prefixe = $this->getPrefixe();
205
		$prefixe = $this->getPrefixe();
207
		$sqlTpl = "($prefixe.courriel_utilisateur LIKE %1\$s )";
206
		$sqlTpl = "($prefixe.courriel_utilisateur LIKE %1\$s )";
208
		$emailP = $this->bdd->proteger("$email%");
207
		$emailP = $this->bdd->proteger("$email%");
209
		$whereAuteur = sprintf($sqlTpl, $emailP);
208
		$whereAuteur = sprintf($sqlTpl, $emailP);
210
		$this->addWhere('masque.auteur', $whereAuteur);
209
		$this->addWhere('masque.auteur', $whereAuteur);
211
	}
210
	}
212
 
211
 
213
	/**
212
	/**
214
	 * Retourne une clause where du style:
213
	 * Retourne une clause where du style:
215
	 * CONCAT(IF(du.prenom IS NULL, "", du.prenom), [...] vdi.i_nomutilisateur) REGEXP 'xxx'
214
	 * CONCAT(IF(du.prenom IS NULL, "", du.prenom), [...] vdi.i_nomutilisateur) REGEXP 'xxx'
216
	 */
215
	 */
217
	private function ajouterContrainteAuteurIntitule() {
216
	private function ajouterContrainteAuteurIntitule() {
218
		$auteurExplode = explode(' ', $this->parametres['masque.auteur']);
217
		$auteurExplode = explode(' ', $this->parametres['masque.auteur']);
219
		$nbreMots = count($auteurExplode);
218
		$nbreMots = count($auteurExplode);
220
 
219
 
221
		if ($nbreMots == 1) {
220
		if ($nbreMots == 1) {
222
			$this->ajouterContrainteAuteurPrenomOuNom();
221
			$this->ajouterContrainteAuteurPrenomOuNom();
223
		} else if ($nbreMots == 2) {
222
		} else if ($nbreMots == 2) {
224
			$this->ajouterContrainteAuteurPrenomEtNom();
223
			$this->ajouterContrainteAuteurPrenomEtNom();
225
		}
224
		}
226
	}
225
	}
227
 
226
 
228
	private function ajouterContrainteAuteurPrenomOuNom() {
227
	private function ajouterContrainteAuteurPrenomOuNom() {
229
		$prenomOuNom = $this->parametres['masque.auteur'];
228
		$prenomOuNom = $this->parametres['masque.auteur'];
230
 
229
 
231
		$sqlTpl = 'CONCAT(%s,%s) LIKE %s';
230
		$sqlTpl = 'CONCAT(%s,%s) LIKE %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
		$auteurMotif = $this->bdd->proteger("%$prenomOuNom%");
234
		$auteurMotif = $this->bdd->proteger("%$prenomOuNom%");
236
 
235
 
237
		$auteurWhere = sprintf($sqlTpl, $champsPrenomSql, $champsNomSql, $auteurMotif);
236
		$auteurWhere = sprintf($sqlTpl, $champsPrenomSql, $champsNomSql, $auteurMotif);
238
		$this->addWhere('masque.auteur', $auteurWhere);
237
		$this->addWhere('masque.auteur', $auteurWhere);
239
	}
238
	}
240
 
239
 
241
	private function ajouterContrainteAuteurPrenomEtNom() {
240
	private function ajouterContrainteAuteurPrenomEtNom() {
242
		list($prenom, $nom) = explode(' ', $this->parametres['masque.auteur']);
241
		list($prenom, $nom) = explode(' ', $this->parametres['masque.auteur']);
243
 
242
 
244
		$sqlTpl = '(CONCAT(%1$s,%2$s) LIKE %3$s AND CONCAT(%1$s,%2$s) LIKE %4$s)';
243
		$sqlTpl = '(CONCAT(%1$s,%2$s) LIKE %3$s AND CONCAT(%1$s,%2$s) LIKE %4$s)';
245
		$prefixe = $this->getPrefixe();
244
		$prefixe = $this->getPrefixe();
246
		$champsPrenomSql = self::ajouterIfNullPourConcat($this->champsPrenom, $prefixe);
245
		$champsPrenomSql = self::ajouterIfNullPourConcat($this->champsPrenom, $prefixe);
247
		$champsNomSql = self::ajouterIfNullPourConcat($this->champsNom, $prefixe);
246
		$champsNomSql = self::ajouterIfNullPourConcat($this->champsNom, $prefixe);
248
		$prenomMotif = $this->bdd->proteger("%$prenom%");
247
		$prenomMotif = $this->bdd->proteger("%$prenom%");
249
		$nomMotif = $this->bdd->proteger("%$nom%");
248
		$nomMotif = $this->bdd->proteger("%$nom%");
250
 
249
 
251
		$auteurWhere = sprintf($sqlTpl, $champsPrenomSql, $champsNomSql, $prenomMotif, $nomMotif);
250
		$auteurWhere = sprintf($sqlTpl, $champsPrenomSql, $champsNomSql, $prenomMotif, $nomMotif);
252
		$this->addWhere('masque.auteur', $auteurWhere);
251
		$this->addWhere('masque.auteur', $auteurWhere);
253
	}
252
	}
254
 
253
 
255
	/**
254
	/**
256
	 * Lorsque l'on concatène des champs, un seul NULL prend le dessus.
255
	 * Lorsque l'on concatène des champs, un seul NULL prend le dessus.
257
	 * Il faut donc utiliser la syntaxe IFNULL(%s, "").
256
	 * Il faut donc utiliser la syntaxe IFNULL(%s, "").
258
	 * Cette fonction effectue aussi l'implode() "final".
257
	 * Cette fonction effectue aussi l'implode() "final".
259
	 */
258
	 */
260
	private static function ajouterIfNullPourConcat($champs, $prefixe) {
259
	private static function ajouterIfNullPourConcat($champs, $prefixe) {
261
		$champsProteges = array();
260
		$champsProteges = array();
262
		foreach ($champs as $champ) {
261
		foreach ($champs as $champ) {
263
			if (strstr($champ, '.') === false) {
262
			if (strstr($champ, '.') === false) {
264
				$champ = "$prefixe.$champ";
263
				$champ = "$prefixe.$champ";
265
			}
264
			}
266
			$champsProteges[] = "IFNULL($champ, '')";
265
			$champsProteges[] = "IFNULL($champ, '')";
267
		}
266
		}
268
		return implode(',', $champsProteges);
267
		return implode(',', $champsProteges);
269
	}
268
	}
270
 
269
 
271
	private function ajouterContrainteDate() {
270
	private function ajouterContrainteDate() {
272
		if (isset($this->parametres['masque.date'])) {
271
		if (isset($this->parametres['masque.date'])) {
273
			$date = $this->parametres['masque.date'];
272
			$date = $this->parametres['masque.date'];
274
			if (preg_match('/^\d{4}$/', $date) && $date < 2030 && $date > 1600) {
273
			if (preg_match('/^\d{4}$/', $date) && $date < 2030 && $date > 1600) {
275
				$sqlTpl = "YEAR(do.date_observation) = %d";
274
				$sqlTpl = "YEAR(do.date_observation) = %d";
276
				$dateWhere = sprintf($sqlTpl, $date);
275
				$dateWhere = sprintf($sqlTpl, $date);
277
				$this->addWhere('masque.date', $dateWhere);
276
				$this->addWhere('masque.date', $dateWhere);
278
			} else {
277
			} else {
279
				$sqlTpl = "do.date_observation = %s";
278
				$sqlTpl = "do.date_observation = %s";
280
				$dateP = $this->bdd->proteger($date);
279
				$dateP = $this->bdd->proteger($date);
281
				$dateWhere = sprintf($sqlTpl, $dateP);
280
				$dateWhere = sprintf($sqlTpl, $dateP);
282
				$this->addWhere('masque.date', $dateWhere);
281
				$this->addWhere('masque.date', $dateWhere);
283
			}
282
			}
284
 
283
 
285
			$this->ajouterJoinObsSiNecessaire();
284
			$this->ajouterJoinObsSiNecessaire();
286
		}
285
		}
287
	}
286
	}
288
 
287
 
289
	private function ajouterContrainteDepartement() {
288
	private function ajouterContrainteDepartement() {
290
		if (isset($this->parametres['masque.departement'])) {
289
		if (isset($this->parametres['masque.departement'])) {
291
			$dept = $this->parametres['masque.departement'];
290
			$dept = $this->parametres['masque.departement'];
292
			$deptMotif = $this->bdd->proteger("INSEE-C:$dept");
291
			$deptMotif = $this->bdd->proteger("INSEE-C:$dept");
293
			$this->addWhere('masque.departement', "do.ce_zone_geo LIKE $deptMotif");
292
			$this->addWhere('masque.departement', "do.ce_zone_geo LIKE $deptMotif");
294
 
293
 
295
			$this->ajouterJoinObsSiNecessaire();
294
			$this->ajouterJoinObsSiNecessaire();
296
		}
295
		}
297
	}
296
	}
298
	
297
	
299
	private function ajouterContraintePays() {
298
	private function ajouterContraintePays() {
300
		if (isset($this->parametres['masque.pays'])) {
299
		if (isset($this->parametres['masque.pays'])) {
301
			// Attention le standard contient parfois FX pour la france métropolitaine
300
			// Attention le standard contient parfois FX pour la france métropolitaine
302
			// Dans ce cas particulier on cherche donc FR et FX
301
			// Dans ce cas particulier on cherche donc FR et FX
303
			$this->parametres['masque.pays'] = strtoupper($this->parametres['masque.pays']);
302
			$this->parametres['masque.pays'] = strtoupper($this->parametres['masque.pays']);
304
			if(strpos($this->parametres['masque.pays'], 'FR') !== false) {
303
			if(strpos($this->parametres['masque.pays'], 'FR') !== false) {
305
				$this->parametres['masque.pays'] = str_replace('FR', 'FR,FX', $this->parametres['masque.pays']);
304
				$this->parametres['masque.pays'] = str_replace('FR', 'FR,FX', $this->parametres['masque.pays']);
306
			}
305
			}
307
			$pays = explode(',', $this->parametres['masque.pays']);
306
			$pays = explode(',', $this->parametres['masque.pays']);
308
			$pays = implode(',', $this->bdd->proteger($pays));
307
			$pays = implode(',', $this->bdd->proteger($pays));
309
			$this->addWhere('masque.pays', "do.pays IN ($pays)");
308
			$this->addWhere('masque.pays', "do.pays IN ($pays)");
310
	
309
	
311
			$this->ajouterJoinObsSiNecessaire();
310
			$this->ajouterJoinObsSiNecessaire();
312
		}
311
		}
313
	}
312
	}
314
 
313
 
315
	private function ajouterContrainteIdZoneGeo() {
314
	private function ajouterContrainteIdZoneGeo() {
316
		if (isset($this->parametres['masque.id_zone_geo'])) {
315
		if (isset($this->parametres['masque.id_zone_geo'])) {
317
			$idZgMotif = $this->bdd->proteger($this->parametres['masque.id_zone_geo']);
316
			$idZgMotif = $this->bdd->proteger($this->parametres['masque.id_zone_geo']);
318
			$this->addWhere('masque.id_zone_geo', "do.ce_zone_geo = $idZgMotif");
317
			$this->addWhere('masque.id_zone_geo', "do.ce_zone_geo = $idZgMotif");
319
			
318
			
320
			$this->ajouterJoinObsSiNecessaire();
319
			$this->ajouterJoinObsSiNecessaire();
321
		}
320
		}
322
	}
321
	}
323
 
322
 
324
	private function ajouterContrainteGenre() {
323
	private function ajouterContrainteGenre() {
325
		if (isset($this->parametres['masque.genre'])) {
324
		if (isset($this->parametres['masque.genre'])) {
326
			$genre = $this->parametres['masque.genre'];
325
			$genre = $this->parametres['masque.genre'];
327
			$genreMotif = $this->bdd->proteger("$genre%");
326
			$genreMotif = $this->bdd->proteger("$genre%");
328
			$this->addWhere('masque.genre', "do.nom_sel LIKE $genreMotif");
327
			$this->addWhere('masque.genre', "do.nom_sel LIKE $genreMotif");
329
 
328
 
330
			$this->ajouterJoinObsSiNecessaire();
329
			$this->ajouterJoinObsSiNecessaire();
331
		}
330
		}
332
	}
331
	}
333
 
332
 
334
	private function ajouterContrainteFamille() {
333
	private function ajouterContrainteFamille() {
335
		if (isset($this->parametres['masque.famille'])) {
334
		if (isset($this->parametres['masque.famille'])) {
336
			$familleMotif = $this->bdd->proteger($this->parametres['masque.famille']);
335
			$familleMotif = $this->bdd->proteger($this->parametres['masque.famille']);
337
			$this->addWhere('masque.famille', "do.famille = $familleMotif");
336
			$this->addWhere('masque.famille', "do.famille = $familleMotif");
338
 
337
 
339
			$this->ajouterJoinObsSiNecessaire();
338
			$this->ajouterJoinObsSiNecessaire();
340
		}
339
		}
341
	}
340
	}
342
 
341
 
343
	private function ajouterContrainteNs() {
342
	private function ajouterContrainteNs() {
344
		if (isset($this->parametres['masque.ns'])) {
343
		if (isset($this->parametres['masque.ns'])) {
345
			$ns = $this->parametres['masque.ns'];
344
			$ns = $this->parametres['masque.ns'];
346
			$nsMotif = $this->bdd->proteger("$ns%");
345
			$nsMotif = $this->bdd->proteger("$ns%");
347
			$this->addWhere('masque.ns', "do.nom_sel LIKE $nsMotif");
346
			$this->addWhere('masque.ns', "do.nom_sel LIKE $nsMotif");
348
			
347
			
349
			$this->ajouterJoinObsSiNecessaire();
348
			$this->ajouterJoinObsSiNecessaire();
350
		}
349
		}
351
	}
350
	}
352
 
351
 
353
	private function ajouterContrainteNn() {
352
	private function ajouterContrainteNn() {
354
		if (isset($this->parametres['masque.nn'])) {
353
		if (isset($this->parametres['masque.nn'])) {
355
			$sqlTpl = '(do.nom_sel_nn = %1$d OR do.nom_ret_nn = %1$d)';
354
			$sqlTpl = '(do.nom_sel_nn = %1$d OR do.nom_ret_nn = %1$d)';
356
			$nnWhere = sprintf($sqlTpl, $this->parametres['masque.nn']);
355
			$nnWhere = sprintf($sqlTpl, $this->parametres['masque.nn']);
357
			$this->addWhere('masque.nn', $nnWhere);
356
			$this->addWhere('masque.nn', $nnWhere);
358
 
357
 
359
			$this->ajouterJoinObsSiNecessaire();
358
			$this->ajouterJoinObsSiNecessaire();
360
		}
359
		}
361
	}
360
	}
362
 
361
 
363
	private function ajouterContrainteReferentiel() {
362
	private function ajouterContrainteReferentiel() {
364
		if (isset($this->parametres['masque.referentiel'])) {
363
		if (isset($this->parametres['masque.referentiel'])) {
365
			$ref = $this->parametres['masque.referentiel'];
364
			$ref = $this->parametres['masque.referentiel'];
366
			$refMotif = $this->bdd->proteger("$ref%");
365
			$refMotif = $this->bdd->proteger("$ref%");
367
			$this->addWhere('masque.referentiel', "do.nom_referentiel LIKE $refMotif");
366
			$this->addWhere('masque.referentiel', "do.nom_referentiel LIKE $refMotif");
368
 
367
 
369
			$this->ajouterJoinObsSiNecessaire();
368
			$this->ajouterJoinObsSiNecessaire();
370
		}
369
		}
371
	}
370
	}
372
 
371
 
373
	private function ajouterContrainteCommune() {
372
	private function ajouterContrainteCommune() {
374
		if (isset($this->parametres['masque.commune'])) {
373
		if (isset($this->parametres['masque.commune'])) {
375
			$commune = $this->parametres['masque.commune'];
374
			$commune = $this->parametres['masque.commune'];
376
			$communeMotif = $this->bdd->proteger("$commune%");
375
			$communeMotif = $this->bdd->proteger("$commune%");
377
			$this->addWhere('masque.commune', "do.zone_geo LIKE $communeMotif");
376
			$this->addWhere('masque.commune', "do.zone_geo LIKE $communeMotif");
378
 
377
 
379
			$this->ajouterJoinObsSiNecessaire();
378
			$this->ajouterJoinObsSiNecessaire();
380
		}
379
		}
381
	}
380
	}
-
 
381
 
-
 
382
	/**
-
 
383
	 * Si masque.pninscritsseulement vaut true, les observations ayant un tag
-
 
384
	 * "plantnet" mais dont l'auteur n'est pas inscrit à TB seront éliminées
-
 
385
	 * (décision FlorisTic 2016-09)
-
 
386
	 */
-
 
387
	protected function ajouterContraintePnInscrits() {
-
 
388
		if (isset($this->parametres['masque.pninscritsseulement'])) {
-
 
389
			// avec la classe ParametresFiltrage, on ne passe là que si le masque vaut 1
-
 
390
			$motifMotClePlantnet = "'%plantnet%'";
-
 
391
			$this->addWhere('masque.pninscritsseulement', "((do.mots_cles_texte NOT LIKE $motifMotClePlantnet OR do.mots_cles_texte IS NULL) OR do.ce_utilisateur != 0)");
-
 
392
 
-
 
393
			$this->ajouterJoinObsSiNecessaire();
-
 
394
		}
-
 
395
	}
382
	
396
	
383
	private function ajouterJoinObsSiNecessaire() {
397
	private function ajouterJoinObsSiNecessaire() {
384
			if ($this->etreAppliImg()) {
398
			if ($this->etreAppliImg()) {
385
				$this->addJoin($this->getSqlJointureObs());
399
				$this->addJoin($this->getSqlJointureObs());
386
			}
400
			}
387
	}
401
	}
388
	
402
	
389
	private function getSqlJointureObs() {
403
	private function getSqlJointureObs() {
390
		$typeJointure = !empty($this->parametres['masque']) ? 'LEFT' : 'INNER';
404
		$typeJointure = !empty($this->parametres['masque']) ? 'LEFT' : 'INNER';
391
		return $typeJointure.' JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ';
405
		return $typeJointure.' JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ';
392
	}
406
	}
-
 
407
 
393
 
408
	// la constrainte de nostre bon roy
394
	public function ajouterConstrainteAppliObs() {
409
	public function ajouterConstrainteAppliObs() {
395
		$this->ajouterContrainteTagCel();
410
		$this->ajouterContrainteTagCel();
396
		$this->ajouterContrainteType();
411
		$this->ajouterContrainteType();
397
		// TODO : ATTENTION -> vue que l'on utilise une vue basée sur les images, nous devons grouper par obs
412
		// TODO : ATTENTION -> vu que l'on utilise une vue basée sur les images, nous devons grouper par obs
398
		$this->addGroupBy('do.id_observation');
413
		$this->addGroupBy('do.id_observation');
399
	}
414
	}
400
 
415
 
401
	private function ajouterContrainteType() {
416
	private function ajouterContrainteType() {
402
		// Les contraintes régissant les onglets sont issus de la réunion dont le compte rendu 
417
		// Les contraintes régissant les onglets sont issus de la réunion dont le compte rendu 
403
		// disponible ici : http://tela-botanica.net/intranet/wakka.php?wiki=Octobre2014
418
		// disponible ici : http://tela-botanica.net/intranet/wakka.php?wiki=Octobre2014
404
		// Ce lien est à modifier pour pointer vers toute nouvelle réunion modifiant ce fonctionnement
419
		// Ce lien est à modifier pour pointer vers toute nouvelle réunion modifiant ce fonctionnement
405
		
420
		
406
		if (isset($this->parametres['masque.type'])) {
421
		if (isset($this->parametres['masque.type'])) {
407
			if (array_key_exists('adeterminer', $this->parametres['masque.type'])) {
422
			if (array_key_exists('adeterminer', $this->parametres['masque.type'])) {
408
				// A DETERMINER : toutes les observations qui ont le tag "aDeterminer" 
423
				// A DETERMINER : toutes les observations qui ont le tag "aDeterminer" 
409
				// *ou* qui n'ont pas de nom d'espèce
424
				// *ou* qui n'ont pas de nom d'espèce
410
				// *ou* qui ont la "certitude" à ("aDeterminer" *ou* "douteux")
425
				// *ou* qui ont la "certitude" à ("aDeterminer" *ou* "douteux")
411
				$this->addWhere('masque.type', '('.
426
				$this->addWhere('masque.type', '('.
412
					'do.certitude = "aDeterminer" '.
427
					'do.certitude = "aDeterminer" '.
413
					'OR do.certitude = "douteux" '.
428
					'OR do.certitude = "douteux" '.
414
					'OR do.mots_cles_texte LIKE "%aDeterminer%" '.
429
					'OR do.mots_cles_texte LIKE "%aDeterminer%" '.
415
					'OR do.nom_sel_nn IS NULL '.
430
					'OR do.nom_sel_nn IS NULL '.
416
					'OR do.nom_sel_nn = 0 '.// il ne DEVRAIT pas y avoir d'entrées à 0, mais il y en a quand-même !!
431
					'OR do.nom_sel_nn = 0 '.// il ne DEVRAIT pas y avoir d'entrées à 0, mais il y en a quand-même !!
417
					')');
432
					')');
418
			}
433
			}
419
			
434
			
420
			if (array_key_exists('validees', $this->parametres['masque.type'])) {
435
			if (array_key_exists('validees', $this->parametres['masque.type'])) {
421
				// VALIDEES : toutes les observations ayant un commentaire doté de proposition_retenue = 1
436
				// VALIDEES : toutes les observations ayant un commentaire doté de proposition_retenue = 1
422
				// ou bien possédant une proposition initiale avec un nom valide ayant totalisé un score d'au moins 4
437
				// ou bien possédant une proposition initiale avec un nom valide ayant totalisé un score d'au moins 4
423
				// (ce qui correspond à au moins deux votes positifs dans la plupart des cas, dont un identifié)
438
				// (ce qui correspond à au moins deux votes positifs dans la plupart des cas, dont un identifié)
424
				$sous_requete_score_prop_votees = $this->getSousRequeteSommeVotesPropositions();				
439
				$sous_requete_score_prop_votees = $this->getSousRequeteSommeVotesPropositions();				
425
				$this->addJoin('INNER JOIN del_commentaire AS dc '.
440
				$this->addJoin('INNER JOIN del_commentaire AS dc '.
426
					'ON ( '.
441
					'ON ( '.
427
						'do.id_observation = dc.ce_observation '.
442
						'do.id_observation = dc.ce_observation '.
428
						'AND ( '.
443
						'AND ( '.
429
							'dc.proposition_retenue = 1 OR '.
444
							'dc.proposition_retenue = 1 OR '.
430
							'( '.
445
							'( '.
431
								'dc.proposition_initiale = 1 '.
446
								'dc.proposition_initiale = 1 '.
432
								'AND dc.nom_sel_nn != 0 '.
447
								'AND dc.nom_sel_nn != 0 '.
433
								'AND dc.nom_sel_nn IS NOT NULL '.
448
								'AND dc.nom_sel_nn IS NOT NULL '.
434
								' AND dc.id_commentaire IN ('.$sous_requete_score_prop_votees.' >= 4) '.
449
								' AND dc.id_commentaire IN ('.$sous_requete_score_prop_votees.' >= 4) '.
435
							') '.
450
							') '.
436
						') '.
451
						') '.
437
					')'
452
					')'
438
				);
453
				);
439
			}
454
			}
440
			
455
			
441
			if(array_key_exists('aconfirmer', $this->parametres['masque.type'])) {
456
			if(array_key_exists('aconfirmer', $this->parametres['masque.type'])) {
442
				// A CONFIRMER : toutes les observations moins les validées et à confirmer
457
				// A CONFIRMER : toutes les observations moins les validées et à confirmer
443
				// i.e. : des observations avec un nom valide, qui ne sont pas à déterminer
458
				// i.e. : des observations avec un nom valide, qui ne sont pas à déterminer
444
				// (ni certitude "aDeterminer" ou "douteuse", ni mot clé),
459
				// (ni certitude "aDeterminer" ou "douteuse", ni mot clé),
445
				// ne possédant pas de proposition officiellement retenue 
460
				// ne possédant pas de proposition officiellement retenue 
446
				// et ayant une proposition initiale totalisant un score de moins de 4 
461
				// et ayant une proposition initiale totalisant un score de moins de 4 
447
				$sous_requete_score_prop_votees = $this->getSousRequeteSommeVotesPropositions();
462
				$sous_requete_score_prop_votees = $this->getSousRequeteSommeVotesPropositions();
448
				$this->addWhere('masque.type', 
463
				$this->addWhere('masque.type', 
449
						'('.
464
						'('.
450
							'do.id_observation IN ('.
465
							'do.id_observation IN ('.
451
								'SELECT dc.ce_observation FROM del_commentaire dc WHERE dc.proposition_retenue = 0'.
466
								'SELECT dc.ce_observation FROM del_commentaire dc WHERE dc.proposition_retenue = 0'.
452
								' AND ( '.
467
								' AND ( '.
453
									'dc.proposition_initiale = 1 '.
468
									'dc.proposition_initiale = 1 '.
454
									'AND dc.nom_sel_nn != 0 '.
469
									'AND dc.nom_sel_nn != 0 '.
455
									'AND dc.nom_sel_nn IS NOT NULL '.
470
									'AND dc.nom_sel_nn IS NOT NULL '.
456
									'AND dc.id_commentaire IN ('.$sous_requete_score_prop_votees.' < 4) '.
471
									'AND dc.id_commentaire IN ('.$sous_requete_score_prop_votees.' < 4) '.
457
								') '.
472
								') '.
458
							') AND do.id_observation NOT IN ('.
473
							') AND do.id_observation NOT IN ('.
459
								'SELECT dc.ce_observation FROM del_commentaire dc '.
474
								'SELECT dc.ce_observation FROM del_commentaire dc '.
460
								'WHERE '.
475
								'WHERE '.
461
								' dc.proposition_retenue = 1'.
476
								' dc.proposition_retenue = 1'.
462
							') '.
477
							') '.
463
							'AND do.certitude != "douteux" AND do.certitude != "aDeterminer" '.
478
							'AND do.certitude != "douteux" AND do.certitude != "aDeterminer" '.
464
							'AND do.mots_cles_texte NOT LIKE "%aDeterminer%" '.
479
							'AND do.mots_cles_texte NOT LIKE "%aDeterminer%" '.
465
							'AND do.nom_sel_nn != 0 '.
480
							'AND do.nom_sel_nn != 0 '.
466
							'AND do.nom_sel_nn IS NOT NULL'.
481
							'AND do.nom_sel_nn IS NOT NULL'.
467
						') '	
482
						') '	
468
					);
483
					);
469
			}	
484
			}	
470
 
485
 
471
			$this->ajouterJoinObsSiNecessaire();
486
			$this->ajouterJoinObsSiNecessaire();
472
		}
487
		}
473
	}
488
	}
474
	
489
	
475
	private function getSousRequeteSommeVotesPropositions() {
490
	private function getSousRequeteSommeVotesPropositions() {
476
		// ATTENTION : un vote identifié compte 3 votes anonymes (dans les deux sens)
491
		// ATTENTION : un vote identifié compte 3 votes anonymes (dans les deux sens)
477
		return  'SELECT ce_proposition '.
492
		return  'SELECT ce_proposition '.
478
				'FROM del_commentaire_vote dcv '.
493
				'FROM del_commentaire_vote dcv '.
479
				'GROUP BY ce_proposition HAVING '.
494
				'GROUP BY ce_proposition HAVING '.
480
				'SUM(CASE '.
495
				'SUM(CASE '.
481
				'	WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP \'^-?[0-9]+$\' != 0 THEN 3 '.
496
				'	WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP \'^-?[0-9]+$\' != 0 THEN 3 '.
482
				'	WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP \'^-?[0-9]+$\' != 0 THEN -3 '.
497
				'	WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP \'^-?[0-9]+$\' != 0 THEN -3 '.
483
				'	WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP \'^-?[0-9]+$\' = 0 THEN 1 '.
498
				'	WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP \'^-?[0-9]+$\' = 0 THEN 1 '.
484
				'	WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP \'^-?[0-9]+$\' = 0 THEN -1 '.
499
				'	WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP \'^-?[0-9]+$\' = 0 THEN -1 '.
485
				'END '.
500
				'END '.
486
			') ';
501
			') ';
487
	}
502
	}
488
 
503
 
489
	public function ajouterConstrainteAppliImg() {
504
	public function ajouterConstrainteAppliImg() {
490
		$this->ajouterContrainteMilieu();
505
		$this->ajouterContrainteMilieu();
491
		$this->ajouterContrainteTri();
506
		$this->ajouterContrainteTri();
492
		$this->ajouterContrainteTagCel();
507
		$this->ajouterContrainteTagCel();
493
		$this->ajouterContrainteTagDel();
508
		$this->ajouterContrainteTagDel();
-
 
509
		$this->ajouterContraintePnInscrits();
494
	}
510
	}
495
 
511
 
496
	private function ajouterContrainteMilieu() {
512
	private function ajouterContrainteMilieu() {
497
		if (isset($this->parametres['masque.milieu'])) {
513
		if (isset($this->parametres['masque.milieu'])) {
498
			$milieu = $this->parametres['masque.milieu'];
514
			$milieu = $this->parametres['masque.milieu'];
499
			$milieuMotif = $this->bdd->proteger("%$milieu%");
515
			$milieuMotif = $this->bdd->proteger("%$milieu%");
500
			$this->addWhere('masque.milieu', "do.milieu LIKE $milieuMotif");
516
			$this->addWhere('masque.milieu', "do.milieu LIKE $milieuMotif");
501
 
517
 
502
			$this->ajouterJoinObsSiNecessaire();
518
			$this->ajouterJoinObsSiNecessaire();
503
		}
519
		}
504
	}
520
	}
505
 
521
 
506
	private function ajouterContrainteTri() {
522
	private function ajouterContrainteTri() {
507
		if (isset($this->parametres['tri'])) {
523
		if (isset($this->parametres['tri'])) {
508
			$tri = $this->parametres['tri'];
524
			$tri = $this->parametres['tri'];
509
 
525
 
510
			if (isset($this->parametres['protocole'])  && ($tri == 'moyenne-arithmetique' || $tri == 'points')) {
526
			if (isset($this->parametres['protocole'])  && ($tri == 'moyenne-arithmetique' || $tri == 'points')) {
511
				// $this->parametres['protocole'] *est* défini (cf Outils::filtrerUrlsParams...())
527
				// $this->parametres['protocole'] *est* défini (cf Outils::filtrerUrlsParams...())
512
				$sqlTpl = 'LEFT JOIN del_image_stat AS dis ON di.id_image = dis.ce_image AND dis.ce_protocole = %d';
528
				$sqlTpl = 'LEFT JOIN del_image_stat AS dis ON di.id_image = dis.ce_image AND dis.ce_protocole = %d';
513
				$triSql = sprintf($sqlTpl, $this->parametres['protocole']);
529
				$triSql = sprintf($sqlTpl, $this->parametres['protocole']);
514
				$this->addJoinDis($triSql);
530
				$this->addJoinDis($triSql);
515
			}
531
			}
516
 
532
 
517
			if (isset($this->parametres['ordre']) && $tri == 'tags') {
533
			if (isset($this->parametres['ordre']) && $tri == 'tags') {
518
				$typeJointure = ($this->parametres['ordre'] == 'desc') ? 'INNER' : 'LEFT';
534
				$typeJointure = ($this->parametres['ordre'] == 'desc') ? 'INNER' : 'LEFT';
519
				$this->addJoin("$typeJointure JOIN del_image_stat AS dis ON di.id_image = dis.ce_image");
535
				$this->addJoin("$typeJointure JOIN del_image_stat AS dis ON di.id_image = dis.ce_image");
520
			}
536
			}
521
		}
537
		}
522
	}
538
	}
523
 
539
 
524
	private function ajouterContrainteTagCel() {
540
	private function ajouterContrainteTagCel() {
525
		if (isset($this->parametres['masque.tag_cel'])) {
541
		if (isset($this->parametres['masque.tag_cel'])) {
526
			if (isset($this->parametres['masque.tag_cel']['AND'])) {
542
			if (isset($this->parametres['masque.tag_cel']['AND'])) {
527
				$tags = $this->parametres['masque.tag_cel']['AND'];
543
				$tags = $this->parametres['masque.tag_cel']['AND'];
528
				$clausesWhere = array();
544
				$clausesWhere = array();
529
				foreach ($tags as $tag) {
545
				foreach ($tags as $tag) {
530
					$tagMotif = $this->bdd->proteger("%$tag%");
546
					$tagMotif = $this->bdd->proteger("%$tag%");
531
					if ($this->etreAppliImg()) {
547
					if ($this->etreAppliImg()) {
532
						$sousRequete = 'SELECT id_observation '.
548
						$sousRequete = 'SELECT id_observation '.
533
							'FROM del_observation '.
549
							'FROM del_observation '.
534
							"WHERE mots_cles_texte LIKE $tagMotif ";
550
							"WHERE mots_cles_texte LIKE $tagMotif ";
535
						$sql = " (di.mots_cles_texte LIKE $tagMotif OR di.id_image IN ($sousRequete) ) ";
551
						$sql = " (di.mots_cles_texte LIKE $tagMotif OR di.id_image IN ($sousRequete) ) ";
536
					} else {
552
					} else {
537
						// WARNING : la sous-requête est la meilleure solution trouvée pour contrer le fonctionnement
553
						// WARNING : la sous-requête est la meilleure solution trouvée pour contrer le fonctionnement
538
						// étrange de l'optimiseur de MYSQL 5.6 (à retester avec Mysql 5.7 et suivant).
554
						// étrange de l'optimiseur de MYSQL 5.6 (à retester avec Mysql 5.7 et suivant).
539
						$sousRequete = 'SELECT DISTINCT ce_observation '.
555
						$sousRequete = 'SELECT DISTINCT ce_observation '.
540
							'FROM del_image '.
556
							'FROM del_image '.
541
							"WHERE mots_cles_texte LIKE $tagMotif ".
557
							"WHERE mots_cles_texte LIKE $tagMotif ".
542
							'AND ce_observation IS NOT NULL';
558
							'AND ce_observation IS NOT NULL';
543
						$sql = " (do.mots_cles_texte LIKE $tagMotif OR do.id_observation IN ($sousRequete)) ";
559
						$sql = " (do.mots_cles_texte LIKE $tagMotif OR do.id_observation IN ($sousRequete)) ";
544
					}
560
					}
545
					$clausesWhere[] = $sql;
561
					$clausesWhere[] = $sql;
546
				}
562
				}
547
				$whereTags = implode(' AND ', $clausesWhere);
563
				$whereTags = implode(' AND ', $clausesWhere);
548
				$this->addWhere('masque.tag_cel', "($whereTags)");
564
				$this->addWhere('masque.tag_cel', "($whereTags)");
549
			} else if (isset($this->parametres['masque.tag_cel']['OR'])) {
565
			} else if (isset($this->parametres['masque.tag_cel']['OR'])) {
550
				$tags = $this->parametres['masque.tag_cel']['OR'];
566
				$tags = $this->parametres['masque.tag_cel']['OR'];
551
				$tagMotif = $this->bdd->proteger(implode('|', $tags));
567
				$tagMotif = $this->bdd->proteger(implode('|', $tags));
552
				$sqlTpl = "CONCAT(IFNULL(do.mots_cles_texte,''),IFNULL(di.mots_cles_texte,'')) REGEXP %s";
568
				$sqlTpl = "CONCAT(IFNULL(do.mots_cles_texte,''),IFNULL(di.mots_cles_texte,'')) REGEXP %s";
553
				$tagSql = sprintf($sqlTpl, $tagMotif);
569
				$tagSql = sprintf($sqlTpl, $tagMotif);
554
 
570
 
555
				$this->addWhere('masque.tag_cel', $tagSql);
571
				$this->addWhere('masque.tag_cel', $tagSql);
556
 
572
 
557
				if ($this->etreAppliObs()) {
573
				if ($this->etreAppliObs()) {
558
					$this->addJoin('LEFT JOIN del_image AS di ON (di.ce_observation = do.id_observation) ');
574
					$this->addJoin('LEFT JOIN del_image AS di ON (di.ce_observation = do.id_observation) ');
559
				}
575
				}
560
			}
576
			}
561
			$this->ajouterJoinObsSiNecessaire();
577
			$this->ajouterJoinObsSiNecessaire();
562
		}
578
		}
563
	}
579
	}
564
 
580
 
565
	/**
581
	/**
566
	 * Plusieurs solutions sont disponibles dans les anciennes versions (voir DelTk et l'historique SVN de ce fichier).
582
	 * Plusieurs solutions sont disponibles dans les anciennes versions (voir DelTk et l'historique SVN de ce fichier).
567
	 */
583
	 */
568
	private function ajouterContrainteTagDel() {
584
	private function ajouterContrainteTagDel() {
569
		if (isset($this->parametres['masque.tag_del'])) {
585
		if (isset($this->parametres['masque.tag_del'])) {
570
			$nbTags = $this->getNombreDeTags();
586
			$nbTags = $this->getNombreDeTags();
571
			if($nbTags > 1) {
587
			if($nbTags > 1) {
572
				// sous-requêtes car le GROUP BY avec GROUP_CONCAT est *trop* lent
588
				// sous-requêtes car le GROUP BY avec GROUP_CONCAT est *trop* lent
573
				if (isset($this->parametres['masque.tag_del']['AND'])) {
589
				if (isset($this->parametres['masque.tag_del']['AND'])) {
574
					foreach ($this->parametres['masque.tag_del']['AND'] as $mc) {
590
					foreach ($this->parametres['masque.tag_del']['AND'] as $mc) {
575
						$sousRequete = 'SELECT ce_image '.
591
						$sousRequete = 'SELECT ce_image '.
576
							'FROM del_image_tag '.
592
							'FROM del_image_tag '.
577
							'WHERE actif = 1 '.
593
							'WHERE actif = 1 '.
578
							"AND tag_normalise LIKE '%$mc%' ";
594
							"AND tag_normalise LIKE '%$mc%' ";
579
						$this->addWhere('masque.tag_del', "di.id_image IN ($sousRequete)");
595
						$this->addWhere('masque.tag_del', "di.id_image IN ($sousRequete)");
580
					}
596
					}
581
				} else if (isset($this->parametres['masque.tag_del']['OR'])) {
597
				} else if (isset($this->parametres['masque.tag_del']['OR'])) {
582
					$tagsMotif = "'(" . implode('|', $this->parametres['masque.tag_del']['OR']) . ")'";
598
					$tagsMotif = "'(" . implode('|', $this->parametres['masque.tag_del']['OR']) . ")'";
583
					$sousRequete = 'SELECT ce_image '.
599
					$sousRequete = 'SELECT ce_image '.
584
						'FROM del_image_tag '.
600
						'FROM del_image_tag '.
585
						'WHERE actif = 1 '.
601
						'WHERE actif = 1 '.
586
						"AND tag_normalise REGEXP $tagsMotif ";
602
						"AND tag_normalise REGEXP $tagsMotif ";
587
					
603
					
588
					$this->addWhere('masque.tag_del', "di.id_image IN ($sousRequete)");
604
					$this->addWhere('masque.tag_del', "di.id_image IN ($sousRequete)");
589
				}
605
				}
590
			} else {
606
			} else {
591
				// Si un seul tag est demandé il se trouve dans le OR dans le cas de la recherche
607
				// Si un seul tag est demandé il se trouve dans le OR dans le cas de la recherche
592
				// spécifique et dans le AND dans le cas de la recherche générale
608
				// spécifique et dans le AND dans le cas de la recherche générale
593
				// WTF?
609
				// WTF?
594
				$tag = "";
610
				$tag = "";
595
				if(isset($this->parametres['masque.tag_del']['OR'][0])) {
611
				if(isset($this->parametres['masque.tag_del']['OR'][0])) {
596
					$tag = $this->parametres['masque.tag_del']['OR'][0];
612
					$tag = $this->parametres['masque.tag_del']['OR'][0];
597
				} else if(isset($this->parametres['masque.tag_del']['AND'][0])) {
613
				} else if(isset($this->parametres['masque.tag_del']['AND'][0])) {
598
					$tag = $this->parametres['masque.tag_del']['AND'][0];
614
					$tag = $this->parametres['masque.tag_del']['AND'][0];
599
				}
615
				}
600
				
616
				
601
				$sousRequete = 'SELECT ce_image '.
617
				$sousRequete = 'SELECT ce_image '.
602
						'FROM del_image_tag '.
618
						'FROM del_image_tag '.
603
						'WHERE actif = 1 '.
619
						'WHERE actif = 1 '.
604
						'AND tag_normalise LIKE '.$this->bdd->proteger($tag.'%');
620
						'AND tag_normalise LIKE '.$this->bdd->proteger($tag.'%');
605
 
621
 
606
				$this->addWhere('masque.tag_del', "di.id_image IN ($sousRequete)");
622
				$this->addWhere('masque.tag_del', "di.id_image IN ($sousRequete)");
607
			}
623
			}
608
			
624
			
609
		}
625
		}
610
	}
626
	}
611
	
627
	
612
	private function getNombreDeTags() {
628
	private function getNombreDeTags() {
613
		$somme = 0;
629
		$somme = 0;
614
		if (isset($this->parametres['masque.tag_del']['AND'])) {
630
		if (isset($this->parametres['masque.tag_del']['AND'])) {
615
			$somme = count($this->parametres['masque.tag_del']['AND']);
631
			$somme = count($this->parametres['masque.tag_del']['AND']);
616
		} else {
632
		} else {
617
			$somme = count($this->parametres['masque.tag_del']['OR']);
633
			$somme = count($this->parametres['masque.tag_del']['OR']);
618
		}
634
		}
619
		return $somme;
635
		return $somme;
620
	}
636
	}
621
 
637
 
622
	/**
638
	/**
623
	 * Partie spécifique à PictoFlora:
639
	 * Partie spécifique à PictoFlora:
624
	 * Attention : si le critère de tri n'est pas suffisant, les résultats affichés peuvent varier à chaque appel
640
	 * Attention : si le critère de tri n'est pas suffisant, les résultats affichés peuvent varier à chaque appel
625
	 * de la même page de résultat de PictoFlora.
641
	 * de la même page de résultat de PictoFlora.
626
	 */
642
	 */
627
	public function definirOrdreSqlAppliImg() {
643
	public function definirOrdreSqlAppliImg() {
628
		$ordre = $this->parametres['ordre'];
644
		$ordre = $this->parametres['ordre'];
629
		
645
		
630
		$tri = isset($this->parametres['tri']) ? $this->parametres['tri'] : '';
646
		$tri = isset($this->parametres['tri']) ? $this->parametres['tri'] : '';
631
		switch ($tri) {
647
		switch ($tri) {
632
			case 'moyenne-arithmetique' :
648
			case 'moyenne-arithmetique' :
633
				$this->addOrderBy("dis.moyenne $ordre, dis.nb_votes $ordre, id_image $ordre");
649
				$this->addOrderBy("dis.moyenne $ordre, dis.nb_votes $ordre, id_image $ordre");
634
				break;
650
				break;
635
			case 'points' :
651
			case 'points' :
636
				$this->addOrderBy("dis.nb_points $ordre, dis.moyenne $ordre, dis.nb_votes $ordre, id_image $ordre");
652
				$this->addOrderBy("dis.nb_points $ordre, dis.moyenne $ordre, dis.nb_votes $ordre, id_image $ordre");
637
				break;
653
				break;
638
			case 'tags' :
654
			case 'tags' :
639
				$this->addOrderBy("dis.nb_tags $ordre, id_image $ordre");
655
				$this->addOrderBy("dis.nb_tags $ordre, id_image $ordre");
640
				break;
656
				break;
641
			case 'date_observation' :
657
			case 'date_observation' :
642
				$this->addOrderBy("date_observation $ordre, ce_observation $ordre");
658
				$this->addOrderBy("date_observation $ordre, ce_observation $ordre");
643
				break;
659
				break;
644
			case 'date_transmission' :
660
			case 'date_transmission' :
645
			default:
661
			default:
646
				$this->addOrderBy("di.date_transmission $ordre, ce_observation $ordre");
662
				$this->addOrderBy("di.date_transmission $ordre, ce_observation $ordre");
647
		}
663
		}
648
	}
664
	}
649
 
665
 
650
	public function definirOrdreSqlAppliObs() {
666
	public function definirOrdreSqlAppliObs() {
651
		$ordre = $this->parametres['ordre'];
667
		$ordre = $this->parametres['ordre'];
652
 
668
 
653
		// parmi self::$tri_possible
669
		// parmi self::$tri_possible
654
		$tri = isset($this->parametres['tri']) ? $this->parametres['tri'] : '';
670
		$tri = isset($this->parametres['tri']) ? $this->parametres['tri'] : '';
655
			switch ($tri) {
671
			switch ($tri) {
656
			case 'date_observation' :
672
			case 'date_observation' :
657
				$this->addOrderBy("date_observation $ordre, id_observation $ordre");
673
				$this->addOrderBy("date_observation $ordre, id_observation $ordre");
658
				break;			
674
				break;			
659
			case 'nb_commentaires' :
675
			case 'nb_commentaires' :
660
				$sql_nb_comms = '(SELECT COUNT(id_commentaire) FROM del_commentaire AS dc WHERE ce_observation = id_observation)';
676
				$sql_nb_comms = '(SELECT COUNT(id_commentaire) FROM del_commentaire AS dc WHERE ce_observation = id_observation)';
661
				$this->addOrderBy("$sql_nb_comms $ordre, id_observation $ordre");
677
				$this->addOrderBy("$sql_nb_comms $ordre, id_observation $ordre");
662
				break;
678
				break;
663
			case 'date_transmission' :
679
			case 'date_transmission' :
664
			default:
680
			default:
665
				$this->addOrderBy("do.date_transmission $ordre, id_observation $ordre");
681
				$this->addOrderBy("do.date_transmission $ordre, id_observation $ordre");
666
		}
682
		}
667
	}
683
	}
668
 
684
 
669
	public function getAliasDesChamps($champsEtAlias, $select = null, $prefix = null) {
685
	public function getAliasDesChamps($champsEtAlias, $select = null, $prefix = null) {
670
		$arr = ($select) ? array_intersect_key($champsEtAlias, array_flip($select)) :  $champsEtAlias;
686
		$arr = ($select) ? array_intersect_key($champsEtAlias, array_flip($select)) :  $champsEtAlias;
671
		$keys = array_keys($arr);
687
		$keys = array_keys($arr);
672
 
688
 
673
		if ($prefix) {
689
		if ($prefix) {
674
			array_walk($keys, create_function('&$val, $k, $prefix', '$val = sprintf("%s.`%s`", $prefix, $val);'), $prefix);
690
			array_walk($keys, create_function('&$val, $k, $prefix', '$val = sprintf("%s.`%s`", $prefix, $val);'), $prefix);
675
		} else {
691
		} else {
676
			array_walk($keys, create_function('&$val, $k', '$val = sprintf("`%s`", $val);'));
692
			array_walk($keys, create_function('&$val, $k', '$val = sprintf("`%s`", $val);'));
677
		}
693
		}
678
 
694
 
679
		return implode(', ', array_map(create_function('$v, $k', 'return sprintf("%s AS `%s`", $k, $v);'), $arr, $keys));
695
		return implode(', ', array_map(create_function('$v, $k', 'return sprintf("%s AS `%s`", $k, $v);'), $arr, $keys));
680
	}
696
	}
681
 
697
 
682
	public function getVotesDesImages($idsImages, $protocole = null) {
698
	public function getVotesDesImages($idsImages, $protocole = null) {
683
		if (!$idsImages) return;
699
		if (!$idsImages) return;
684
 
700
 
685
		$mappingVotes = $this->conteneur->getParametreTableau('votes.mapping');
701
		$mappingVotes = $this->conteneur->getParametreTableau('votes.mapping');
686
		$mappingProtocoles = $this->conteneur->getParametreTableau('protocoles.mapping');
702
		$mappingProtocoles = $this->conteneur->getParametreTableau('protocoles.mapping');
687
 		$selectVotes = array('id_vote', 'ce_image', 'ce_protocole', 'ce_utilisateur', 'valeur', 'date');
703
 		$selectVotes = array('id_vote', 'ce_image', 'ce_protocole', 'ce_utilisateur', 'valeur', 'date');
688
		$selectProtocole = array('id_protocole', 'intitule', 'descriptif', 'tag');
704
		$selectProtocole = array('id_protocole', 'intitule', 'descriptif', 'tag');
689
		$voteChamps = $this->getAliasDesChamps($mappingVotes, $selectVotes, 'v'); // "v": cf alias dans la requête
705
		$voteChamps = $this->getAliasDesChamps($mappingVotes, $selectVotes, 'v'); // "v": cf alias dans la requête
690
		$protoChamps = $this->getAliasDesChamps($mappingProtocoles, $selectProtocole, 'p');
706
		$protoChamps = $this->getAliasDesChamps($mappingProtocoles, $selectProtocole, 'p');
691
		$idImgsConcat = implode(',', $idsImages);
707
		$idImgsConcat = implode(',', $idsImages);
692
 
708
 
693
		$requete = "SELECT $voteChamps, $protoChamps ".
709
		$requete = "SELECT $voteChamps, $protoChamps ".
694
			'FROM del_image_vote AS v '.
710
			'FROM del_image_vote AS v '.
695
			'	INNER JOIN del_image_protocole AS p ON (v.ce_protocole = p.id_protocole) '.
711
			'	INNER JOIN del_image_protocole AS p ON (v.ce_protocole = p.id_protocole) '.
696
			"WHERE v.ce_image IN ($idImgsConcat) ".
712
			"WHERE v.ce_image IN ($idImgsConcat) ".
697
			($protocole ? "	AND v.ce_protocole = $protocole " : '').
713
			($protocole ? "	AND v.ce_protocole = $protocole " : '').
698
			"ORDER BY FIELD(v.ce_image, $idImgsConcat) ".
714
			"ORDER BY FIELD(v.ce_image, $idImgsConcat) ".
699
			'-- '.__FILE__.':'.__LINE__;
715
			'-- '.__FILE__.':'.__LINE__;
700
		return $this->bdd->recupererTous($requete);
716
		return $this->bdd->recupererTous($requete);
701
	}
717
	}
702
 
718
 
703
	/**
719
	/**
704
	 * Ajoute les informations sur le protocole et les votes aux images.
720
	 * Ajoute les informations sur le protocole et les votes aux images.
705
	 *
721
	 *
706
	 * ATTENTION : Subtilité, nous passons ici le tableau d'images indexé par id_image qui est bien
722
	 * ATTENTION : Subtilité, nous passons ici le tableau d'images indexé par id_image qui est bien
707
	 * plus pratique pour associer les vote à un tableau, puisque nous ne connaissons pas les id d'observation.
723
	 * plus pratique pour associer les vote à un tableau, puisque nous ne connaissons pas les id d'observation.
708
	 * Mais magiquement (par référence), cela va remplir notre tableau indexé par couple d'id (id_image, id_observation)
724
	 * Mais magiquement (par référence), cela va remplir notre tableau indexé par couple d'id (id_image, id_observation)
709
	 * cf ListeImages::reformateImagesDoubleIndex() à qui revient la tâche de créer ces deux versions
725
	 * cf ListeImages::reformateImagesDoubleIndex() à qui revient la tâche de créer ces deux versions
710
	 * simultanément lorsque c'est encore possible.
726
	 * simultanément lorsque c'est encore possible.
711
	 */
727
	 */
712
	// TODO : supprimer cette "subtilité" source d'erreurs
728
	// TODO : supprimer cette "subtilité" source d'erreurs
713
	public function ajouterInfosVotesProtocoles($votes, &$images) {
729
	public function ajouterInfosVotesProtocoles($votes, &$images) {
714
		if (!$votes) return;
730
		if (!$votes) return;
715
 
731
 
716
		$mappingVotes = $this->conteneur->getParametreTableau('votes.mapping');
732
		$mappingVotes = $this->conteneur->getParametreTableau('votes.mapping');
717
		$mappingProtocoles = $this->conteneur->getParametreTableau('protocoles.mapping');
733
		$mappingProtocoles = $this->conteneur->getParametreTableau('protocoles.mapping');
718
 
734
 
719
		// pour chaque vote
735
		// pour chaque vote
720
		foreach ($votes as $vote) {
736
		foreach ($votes as $vote) {
721
			$imgId = $vote['image.id'];
737
			$imgId = $vote['image.id'];
722
			$protoId = $vote['protocole.id'];
738
			$protoId = $vote['protocole.id'];
723
 
739
 
724
			if (!array_key_exists('protocoles_votes', $images[$imgId]) ||
740
			if (!array_key_exists('protocoles_votes', $images[$imgId]) ||
725
					!array_key_exists($protoId, $images[$imgId]['protocoles_votes'])) {
741
					!array_key_exists($protoId, $images[$imgId]['protocoles_votes'])) {
726
				// extrait les champs spécifique au protocole (le LEFT JOIN de chargerVotesImage les ramène en doublons
742
				// extrait les champs spécifique au protocole (le LEFT JOIN de chargerVotesImage les ramène en doublons
727
				$protocole = array_intersect_key($vote, array_flip($mappingProtocoles));
743
				$protocole = array_intersect_key($vote, array_flip($mappingProtocoles));
728
				$images[$imgId]['protocoles_votes'][$protoId] = $protocole;
744
				$images[$imgId]['protocoles_votes'][$protoId] = $protocole;
729
			}
745
			}
730
 
746
 
731
			$chpsVotes = array('id_vote', 'ce_image', 'ce_utilisateur', 'valeur', 'date');
747
			$chpsVotes = array('id_vote', 'ce_image', 'ce_utilisateur', 'valeur', 'date');
732
			$voteSelection = array_intersect_key($mappingVotes, array_flip($chpsVotes));
748
			$voteSelection = array_intersect_key($mappingVotes, array_flip($chpsVotes));
733
			$vote = array_intersect_key($vote, array_flip($voteSelection));
749
			$vote = array_intersect_key($vote, array_flip($voteSelection));
734
			$images[$imgId]['protocoles_votes'][$protoId]['votes'][$vote['vote.id']] = $vote;
750
			$images[$imgId]['protocoles_votes'][$protoId]['votes'][$vote['vote.id']] = $vote;
735
		}
751
		}
736
	}
752
	}
737
 
753
 
738
	public function getTotalLignesTrouvees() {
754
	public function getTotalLignesTrouvees() {
739
		$resultat = $this->bdd->recuperer('SELECT FOUND_ROWS() AS nbre -- '.__FILE__.':'.__LINE__);
755
		$resultat = $this->bdd->recuperer('SELECT FOUND_ROWS() AS nbre -- '.__FILE__.':'.__LINE__);
740
		return intval($resultat['nbre']);
756
		return intval($resultat['nbre']);
741
	}
757
	}
742
	
758
	
743
	public function getRequeteIdObsMonactiviteTout($id_utilisateur, $limite = "") {
759
	public function getRequeteIdObsMonactiviteTout($id_utilisateur, $limite = "") {
744
		/*	
760
		/*	
745
		Une action c'est :
761
		Une action c'est :
746
		- Quelqu'un commente mon observation
762
		- Quelqu'un commente mon observation
747
		- Quelqu'un fait une proposition sur mon observation
763
		- Quelqu'un fait une proposition sur mon observation
748
	
764
	
749
		- Quelqu'un vote pour ma proposition
765
		- Quelqu'un vote pour ma proposition
750
		- Quelqu'un commente ma proposition ou mon commentaire
766
		- Quelqu'un commente ma proposition ou mon commentaire
751
	
767
	
752
		- Quelqu'un vote pour une proposition sur mon observation
768
		- Quelqu'un vote pour une proposition sur mon observation
753
		- Quelqu'un commente une proposition ou un commentaire sur mon observation
769
		- Quelqu'un commente une proposition ou un commentaire sur mon observation
754
		*/
770
		*/
755
		
771
		
756
		// on selectionne aussi la combinaison des champs de date afin que la liste soit triée correctement
772
		// on selectionne aussi la combinaison des champs de date afin que la liste soit triée correctement
757
		// pas d'autre meilleure solution mais attention ce comportement dépend entièrement de mysql
773
		// pas d'autre meilleure solution mais attention ce comportement dépend entièrement de mysql
758
		$requete = "SELECT SQL_CALC_FOUND_ROWS DISTINCT id_observation, ".$this->getCombinaisonChampsDateMax()." as date_max FROM del_observation do ".
774
		$requete = "SELECT SQL_CALC_FOUND_ROWS DISTINCT id_observation, ".$this->getCombinaisonChampsDateMax()." as date_max FROM del_observation do ".
759
				$this->getJointureMonActivite($id_utilisateur).
775
				$this->getJointureMonActivite($id_utilisateur).
760
				$this->getConditionMonActivite($id_utilisateur).
776
				$this->getConditionMonActivite($id_utilisateur).
761
				"ORDER BY date_max DESC ".
777
				"ORDER BY date_max DESC ".
762
				$limite;
778
				$limite;
763
 
779
 
764
		return $requete;
780
		return $requete;
765
	}
781
	}
766
	
782
	
767
	public function getRequeteNbEvenementsDepuisDate($id_utilisateur, $date) {
783
	public function getRequeteNbEvenementsDepuisDate($id_utilisateur, $date) {
768
		$requete = "SELECT COUNT(DISTINCT id_observation) as nb_evenements FROM del_observation do ".
784
		$requete = "SELECT COUNT(DISTINCT id_observation) as nb_evenements FROM del_observation do ".
769
				$this->getJointureMonActivite($id_utilisateur).
785
				$this->getJointureMonActivite($id_utilisateur).
770
				$this->getConditionMonActivite($id_utilisateur).
786
				$this->getConditionMonActivite($id_utilisateur).
771
				"AND ".$this->getCombinaisonChampsDateMax()." > '".$date."' ". 
787
				"AND ".$this->getCombinaisonChampsDateMax()." > '".$date."' ". 
772
				"ORDER BY ".$this->getCombinaisonChampsDateMax()." DESC ";
788
				"ORDER BY ".$this->getCombinaisonChampsDateMax()." DESC ";
773
 
789
 
774
		return $requete;
790
		return $requete;
775
	}
791
	}
776
	
792
	
777
	public function getEvenementsObs($idsObsConcat, $id_utilisateur) {
793
	public function getEvenementsObs($idsObsConcat, $id_utilisateur) {
778
		$sous_champ_date_max = $this->getCombinaisonChampsDateMax()." as date_max";
794
		$sous_champ_date_max = $this->getCombinaisonChampsDateMax()." as date_max";
779
		$sous_champ_date = "dc.date as date_com, dc.nom_sel as nom_sel_com, dcpr.ce_commentaire_parent as parent_com, dcv.date as date_vote, ".
795
		$sous_champ_date = "dc.date as date_com, dc.nom_sel as nom_sel_com, dcpr.ce_commentaire_parent as parent_com, dcv.date as date_vote, ".
780
							"do.date_observation as date_obs, dcp.date_validation as date_validation, dcpr.date as date_com_reponse, ".
796
							"do.date_observation as date_obs, dcp.date_validation as date_validation, dcpr.date as date_com_reponse, ".
781
							"dcvp.nom_sel as nom_sel_com_parent";
797
							"dcvp.nom_sel as nom_sel_com_parent";
782
		$sous_champs_utilisateurs = "dc.ce_utilisateur as utilisateur_commentaire, dcp.ce_utilisateur as utilisateur_commentaire_valide, ".
798
		$sous_champs_utilisateurs = "dc.ce_utilisateur as utilisateur_commentaire, dcp.ce_utilisateur as utilisateur_commentaire_valide, ".
783
									"dcv.ce_utilisateur as utilisateur_vote_commentaire, do.ce_utilisateur as utilisateur_observation, ".
799
									"dcv.ce_utilisateur as utilisateur_vote_commentaire, do.ce_utilisateur as utilisateur_observation, ".
784
									"dcp.ce_validateur as utilisateur_validation, dcvp.ce_utilisateur as utilisateur_commentaire_vote, ".
800
									"dcp.ce_validateur as utilisateur_validation, dcvp.ce_utilisateur as utilisateur_commentaire_vote, ".
785
									"dcpr.ce_utilisateur as utilisateur_commentaire_reponse";
801
									"dcpr.ce_utilisateur as utilisateur_commentaire_reponse";
786
 
802
 
787
		$sous_champs_infos = "dc.nom_sel as proposition_commentaire_nom_sel, dc.texte as proposition_commentaire_texte, dcp.nom_sel as proposition_validee_nom_sel, ".
803
		$sous_champs_infos = "dc.nom_sel as proposition_commentaire_nom_sel, dc.texte as proposition_commentaire_texte, dcp.nom_sel as proposition_validee_nom_sel, ".
788
							 "dcvp.nom_sel as proposition_commentaire_nom_sel_votee, dcpr.texte as proposition_commentaire_texte_commente";
804
							 "dcvp.nom_sel as proposition_commentaire_nom_sel_votee, dcpr.texte as proposition_commentaire_texte_commente";
789
			
805
			
790
		$requete = "SELECT DISTINCT id_observation, ".$sous_champs_utilisateurs.", ".$sous_champ_date_max.", ".$sous_champ_date.", ".$sous_champs_infos." ".
806
		$requete = "SELECT DISTINCT id_observation, ".$sous_champs_utilisateurs.", ".$sous_champ_date_max.", ".$sous_champ_date.", ".$sous_champs_infos." ".
791
				"FROM del_observation do ".
807
				"FROM del_observation do ".
792
				$this->getJointureMonActivite($id_utilisateur).
808
				$this->getJointureMonActivite($id_utilisateur).
793
				$this->getConditionMonActivite($id_utilisateur).
809
				$this->getConditionMonActivite($id_utilisateur).
794
				"AND id_observation IN ($idsObsConcat) ORDER BY date_max DESC";
810
				"AND id_observation IN ($idsObsConcat) ORDER BY date_max DESC";
795
 
811
 
796
		$evenements = $this->bdd->recupererTous($requete);
812
		$evenements = $this->bdd->recupererTous($requete);
797
		return $evenements;
813
		return $evenements;
798
	}
814
	}
799
	
815
	
800
	public function getJointureMonActivite($id_utilisateur) {
816
	public function getJointureMonActivite($id_utilisateur) {
801
		return 	// quelqu'un commente mon observation ou fait une proposition
817
		return 	// quelqu'un commente mon observation ou fait une proposition
802
		"LEFT JOIN del_commentaire dc ON do.id_observation = dc.ce_observation ".
818
		"LEFT JOIN del_commentaire dc ON do.id_observation = dc.ce_observation ".
803
		"	AND do.ce_utilisateur = ".$id_utilisateur." ".
819
		"	AND do.ce_utilisateur = ".$id_utilisateur." ".
804
		"	AND dc.ce_utilisateur != ".$id_utilisateur." ".
820
		"	AND dc.ce_utilisateur != ".$id_utilisateur." ".
805
		// quelqu'un valide ma proposition (et ce n'est pas moi qui l'ai validée)
821
		// quelqu'un valide ma proposition (et ce n'est pas moi qui l'ai validée)
806
		"LEFT JOIN del_commentaire dcp ON do.id_observation = dcp.ce_observation ".
822
		"LEFT JOIN del_commentaire dcp ON do.id_observation = dcp.ce_observation ".
807
		"	AND dcp.nom_sel IS NOT NULL AND dcp.ce_validateur != ".$id_utilisateur." ".
823
		"	AND dcp.nom_sel IS NOT NULL AND dcp.ce_validateur != ".$id_utilisateur." ".
808
		"	AND dcp.ce_validateur != 0 ".
824
		"	AND dcp.ce_validateur != 0 ".
809
		"	AND dcp.date_validation IS NOT NULL ".
825
		"	AND dcp.date_validation IS NOT NULL ".
810
		"	AND dcp.ce_utilisateur = ".$id_utilisateur." ".
826
		"	AND dcp.ce_utilisateur = ".$id_utilisateur." ".
811
		// quelqu'un vote pour ma proposition ou sur une proposition sur une de mes observations
827
		// quelqu'un vote pour ma proposition ou sur une proposition sur une de mes observations
812
		"LEFT JOIN del_commentaire dcvp ON do.id_observation = dcvp.ce_observation ".
828
		"LEFT JOIN del_commentaire dcvp ON do.id_observation = dcvp.ce_observation ".
813
		"LEFT JOIN del_commentaire_vote dcv ON dcv.ce_proposition = dcvp.id_commentaire ".
829
		"LEFT JOIN del_commentaire_vote dcv ON dcv.ce_proposition = dcvp.id_commentaire ".
814
		"AND (dcvp.ce_utilisateur = $id_utilisateur OR do.ce_utilisateur = $id_utilisateur) ".
830
		"AND (dcvp.ce_utilisateur = $id_utilisateur OR do.ce_utilisateur = $id_utilisateur) ".
815
		"AND dcv.ce_utilisateur != $id_utilisateur ".
831
		"AND dcv.ce_utilisateur != $id_utilisateur ".
816
		"AND dcv.ce_utilisateur != dcvp.ce_utilisateur ".
832
		"AND dcv.ce_utilisateur != dcvp.ce_utilisateur ".
817
		// Quelqu'un répond à l'un de mes commentaires ou commente une de mes propositions
833
		// Quelqu'un répond à l'un de mes commentaires ou commente une de mes propositions
818
		"LEFT JOIN del_commentaire dcpr ON do.id_observation = dcpr.ce_observation ".
834
		"LEFT JOIN del_commentaire dcpr ON do.id_observation = dcpr.ce_observation ".
819
		"AND dcpr.ce_commentaire_parent = dcvp.id_commentaire AND dcvp.ce_utilisateur = $id_utilisateur ";
835
		"AND dcpr.ce_commentaire_parent = dcvp.id_commentaire AND dcvp.ce_utilisateur = $id_utilisateur ";
820
	}
836
	}
821
	
837
	
822
	public function getConditionMonActivite($id_utilisateur, $type = "autres") {
838
	public function getConditionMonActivite($id_utilisateur, $type = "autres") {
823
		//TODO: gérer les cas suivants :
839
		//TODO: gérer les cas suivants :
824
		// demander les activités des autres sur mes obs ou propositions (c'est dejà le cas)
840
		// demander les activités des autres sur mes obs ou propositions (c'est dejà le cas)
825
		// demander mes activités
841
		// demander mes activités
826
		// demander toutes les activités (combinaisons des deux cas ci dessus)
842
		// demander toutes les activités (combinaisons des deux cas ci dessus)
827
		return 	// Vérification que l'évènement me concerne (de près ou ou de loin)
843
		return 	// Vérification que l'évènement me concerne (de près ou ou de loin)
828
		"WHERE (do.ce_utilisateur = $id_utilisateur OR dc.ce_utilisateur = $id_utilisateur ".
844
		"WHERE (do.ce_utilisateur = $id_utilisateur OR dc.ce_utilisateur = $id_utilisateur ".
829
		"OR dcp.ce_utilisateur = $id_utilisateur OR dcv.ce_utilisateur = $id_utilisateur ".
845
		"OR dcp.ce_utilisateur = $id_utilisateur OR dcv.ce_utilisateur = $id_utilisateur ".
830
		"OR dcvp.ce_utilisateur = $id_utilisateur) AND ".
846
		"OR dcvp.ce_utilisateur = $id_utilisateur) AND ".
831
		// mais qu'il y a au moins eu une action de la part d'une autre personne
847
		// mais qu'il y a au moins eu une action de la part d'une autre personne
832
		"(dc.ce_utilisateur IS NOT NULL OR dcp.ce_utilisateur IS NOT NULL OR dcv.ce_utilisateur IS NOT NULL) ";
848
		"(dc.ce_utilisateur IS NOT NULL OR dcp.ce_utilisateur IS NOT NULL OR dcv.ce_utilisateur IS NOT NULL) ";
833
	}
849
	}
834
	
850
	
835
	private function getCombinaisonChampsDateMax() {
851
	private function getCombinaisonChampsDateMax() {
836
		return "GREATEST(IFNULL(dc.date,0), IFNULL(dcv.date,0), IFNULL(do.date_observation,0), IFNULL(dcp.date_validation,0), IFNULL(dcpr.date,0))";
852
		return "GREATEST(IFNULL(dc.date,0), IFNULL(dcv.date,0), IFNULL(do.date_observation,0), IFNULL(dcp.date_validation,0), IFNULL(dcpr.date,0))";
837
	}
853
	}
838
}
854
}