Subversion Repositories eFlore/Applications.del

Rev

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

Rev 1855 Rev 1871
1
<?php
1
<?php
2
// declare(encoding='UTF-8');
2
// declare(encoding='UTF-8');
3
/**
3
/**
4
 * Web service récupèrant toutes les observations et, pour chacune d'elle, les images qui lui sont associées.
4
 * Web service récupèrant toutes les observations et, pour chacune d'elle, les images qui lui sont associées.
5
 *
5
 *
6
 * ATTENTION : le web service commence par récupérer seulement les id des obs (1er requete SQL), puis dans une
6
 * ATTENTION : le web service commence par récupérer seulement les id des obs (1er requete SQL), puis dans une
7
 * deuxième requête SQL récupère les informations complémentaires. Il s'avère qu'en procédant ainsi le web service
7
 * deuxième requête SQL récupère les informations complémentaires. Il s'avère qu'en procédant ainsi le web service
8
 * est 3 fois plus rapide !
8
 * est 3 fois plus rapide !
9
 *
9
 *
10
 * @category   DEL
10
 * @category   DEL
11
 * @package    Services
11
 * @package    Services
12
 * @subpackage Observations
12
 * @subpackage Observations
13
 * @version    0.1
13
 * @version    0.1
14
 * @author     Mathias CHOUET <mathias@tela-botanica.org>
14
 * @author     Mathias CHOUET <mathias@tela-botanica.org>
15
 * @author     Jean-Pascal MILCENT <jpm@tela-botanica.org>
15
 * @author     Jean-Pascal MILCENT <jpm@tela-botanica.org>
16
 * @author     Aurelien PERONNET <aurelien@tela-botanica.org>
16
 * @author     Aurelien PERONNET <aurelien@tela-botanica.org>
17
 * @license    GPL v3 <http://www.gnu.org/licenses/gpl.txt>
17
 * @license    GPL v3 <http://www.gnu.org/licenses/gpl.txt>
18
 * @license    CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
18
 * @license    CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
19
 * @copyright  1999-2014 Tela Botanica <accueil@tela-botanica.org>
19
 * @copyright  1999-2014 Tela Botanica <accueil@tela-botanica.org>
20
 */
20
 */
21
class ListeObservations {
21
class ListeObservations {
22
 
22
 
23
	private $conteneur;
23
	private $conteneur;
24
	private $bdd;
24
	private $bdd;
25
	private $navigation;
25
	private $navigation;
26
	private $filtrage;
26
	private $filtrage;
27
	private $sql;
27
	private $sql;
28
	private $mappings = array();
28
	private $mappings = array();
29
	private $paramsFiltres = array();
29
	private $paramsFiltres = array();
30
 
30
 
31
 
31
 
32
	public function __construct(Conteneur $conteneur) {
32
	public function __construct(Conteneur $conteneur) {
33
		$this->conteneur = $conteneur;
33
		$this->conteneur = $conteneur;
34
		$this->conteneur->chargerConfiguration('config_departements_bruts.ini');
34
		$this->conteneur->chargerConfiguration('config_departements_bruts.ini');
35
 
35
 
36
		$this->bdd = $this->conteneur->getBdd();
36
		$this->bdd = $this->conteneur->getBdd();
37
		$this->filtrage = $this->conteneur->getParametresFiltrage();
37
		$this->filtrage = $this->conteneur->getParametresFiltrage();
38
		$this->sql = $this->conteneur->getSql();
38
		$this->sql = $this->conteneur->getSql();
39
		$this->navigation = $this->conteneur->getNavigation();
39
		$this->navigation = $this->conteneur->getNavigation();
40
 
40
 
41
		$this->mappings['votes'] = $this->conteneur->getParametreTableau('votes.mapping');
41
		$this->mappings['votes'] = $this->conteneur->getParametreTableau('votes.mapping');
42
		$this->mappings['commentaires'] = $this->conteneur->getParametreTableau('commentaires.mapping');
42
		$this->mappings['commentaires'] = $this->conteneur->getParametreTableau('commentaires.mapping');
43
	}
43
	}
44
 
44
 
45
	public function consulter($ressources, $parametres) {
45
	public function consulter($ressources, $parametres) {
46
		$this->paramsFiltres = $this->filtrage->filtrerUrlParamsAppliObs();
46
		$this->paramsFiltres = $this->filtrage->filtrerUrlParamsAppliObs();
-
 
47
		$this->sql->setAppli(Sql::APPLI_OBS);
47
		$this->sql->setParametres($this->paramsFiltres);
48
		$this->sql->setParametres($this->paramsFiltres);
48
		$this->sql->ajouterContraintes();
49
		$this->sql->ajouterContraintes();
49
		$this->sql->ajouterConstrainteAppliObs();
50
		$this->sql->ajouterConstrainteAppliObs();
50
		$this->sql->definirOrdreSqlAppliObs();
51
		$this->sql->definirOrdreSqlAppliObs();
51
 
52
 
52
		$idObs = $this->getIdObs();
53
		$idObs = $this->getIdObs();
53
		$this->navigation->setTotal($this->sql->getTotalLignesTrouvees());
54
		$this->navigation->setTotal($this->sql->getTotalLignesTrouvees());
54
 
55
 
55
		// Ce n'est pas la peine de continuer s'il n'y a pas eu de résultats
56
		// Ce n'est pas la peine de continuer s'il n'y a pas eu de résultats
56
		$resultat = new ResultatService();
57
		$resultat = new ResultatService();
57
		$resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => array());
58
		$resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => array());
58
		if (count($idObs) > 0) {
59
		if (count($idObs) > 0) {
59
 
60
 
60
			// 2) récupération des données nécessaires pour ces observations (obs + images)
61
			// 2) récupération des données nécessaires pour ces observations (obs + images)
61
			// ici les champs récupérés sont issus de self::$sql_fields_liaisons mais sans préfixes
62
			// ici les champs récupérés sont issus de self::$sql_fields_liaisons mais sans préfixes
62
			// car tout provient de v_del_image
63
			// car tout provient de v_del_image
63
			$obs_unfmt = $this->getInfos($idObs);
64
			$obs_unfmt = $this->getInfos($idObs);
64
 
65
 
65
			// 3) suppression, merge des données en tableau assez représentatif du futur JSON en output
66
			// 3) suppression, merge des données en tableau assez représentatif du futur JSON en output
66
			$observations = $this->formaterObservations($obs_unfmt);
67
			$observations = $this->formaterObservations($obs_unfmt);
67
 
68
 
68
			// 4) récupération des données nécessaires pour ces observations (commentaires + votes)
69
			// 4) récupération des données nécessaires pour ces observations (commentaires + votes)
69
			// modifie $observations
70
			// modifie $observations
70
			$this->chargerDeterminations($observations, $idObs);
71
			$this->chargerDeterminations($observations, $idObs);
71
 
72
 
72
			// 5) restauration de l'ordre souhaité initialement
73
			// 5) restauration de l'ordre souhaité initialement
73
			$observations = $this->ordonnerObservations($observations, $idObs);
74
			$observations = $this->ordonnerObservations($observations, $idObs);
74
 
75
 
75
			$resultat->corps = array(
76
			$resultat->corps = array(
76
				'entete' => $this->navigation->getEntete(),
77
				'entete' => $this->navigation->getEntete(),
77
				'resultats' => $observations);
78
				'resultats' => $observations);
78
		}
79
		}
79
		return $resultat;
80
		return $resultat;
80
	}
81
	}
81
 
82
 
82
	// SQL helpers
83
	// SQL helpers
83
	/*
84
	/*
84
	 * Retourne une liste ordonnée d'id d'observation correspondant aux critères
85
	 * Retourne une liste ordonnée d'id d'observation correspondant aux critères
85
	 * passés dans p et aux clauses where/join présentes dans le tableau $req
86
	 * passés dans p et aux clauses where/join présentes dans le tableau $req
86
	 *
87
	 *
87
	 * @param p: $params (filtrés sauf escape-string)
88
	 * @param p: $params (filtrés sauf escape-string)
88
	 * @param req: le tableau représentant les composants de la requete SQL
89
	 * @param req: le tableau représentant les composants de la requete SQL
89
	 * @param db: l'instance de db
90
	 * @param db: l'instance de db
90
	 */
91
	 */
91
	private function getIdObs() {
92
	private function getIdObs() {
92
		$requete = 'SELECT SQL_CALC_FOUND_ROWS id_observation '.
93
		$requete = 'SELECT SQL_CALC_FOUND_ROWS id_observation '.
93
			'FROM v_del_image AS vdi '.
94
			'FROM del_observation AS do '.
94
			$this->sql->getJoin().
95
			$this->sql->getJoin().
95
			'WHERE '.$this->sql->getWhere().
96
			'WHERE '.$this->sql->getWhere().
96
			$this->sql->getGroupBy().
97
			$this->sql->getGroupBy().
97
			$this->sql->getOrderBy().
98
			$this->sql->getOrderBy().
98
			$this->sql->getLimit().
99
			$this->sql->getLimit().
99
			' -- '.__FILE__.':'.__LINE__;
100
			' -- '.__FILE__.':'.__LINE__;
100
 
-
 
-
 
101
		//Debug::printr($requete);
101
		$resultats = $this->bdd->recupererTous($requete);
102
		$resultats = $this->bdd->recupererTous($requete);
102
 
103
 
103
		$idObs = array();
104
		$idObs = array();
104
		if ($resultats !== false ) {
105
		if ($resultats !== false ) {
105
			foreach ($resultats as $resultat) {
106
			foreach ($resultats as $resultat) {
106
				$idObs[] = $resultat['id_observation'];
107
				$idObs[] = $resultat['id_observation'];
107
			}
108
			}
108
		}
109
		}
109
		return $idObs;
110
		return $idObs;
110
	}
111
	}
111
 
112
 
112
	/**
113
	/**
113
	 * Après avoir récupérer seulement les ids dans une première requête, nous récupérons maintenant les infos.
114
	 * Après avoir récupérer seulement les ids dans une première requête, nous récupérons maintenant les infos.
114
	 * Le web service est ainsi 3 fois plus rapide.
115
	 * Le web service est ainsi 3 fois plus rapide.
115
	 */
116
	 */
116
	private function getInfos($idObs) {
117
	private function getInfos($idObs) {
117
		$idsObsConcat = implode(',', $idObs);
118
		$idsObsConcat = implode(',', $idObs);
118
		$requete = "SELECT id_observation, nom_sel AS `determination.ns`, nt AS `determination.nt`, ".
119
		$requete = "SELECT id_observation, nom_sel AS `determination.ns`, nt AS `determination.nt`, ".
119
			'nom_sel_nn AS `determination.nn`, famille AS `determination.famille`, '.
120
			'nom_sel_nn AS `determination.nn`, famille AS `determination.famille`, '.
120
			'nom_referentiel AS `determination.referentiel`, ce_zone_geo AS id_zone_geo, '.
121
			'nom_referentiel AS `determination.referentiel`, ce_zone_geo AS id_zone_geo, '.
121
			'zone_geo, lieudit, station, milieu, date_observation, mots_cles_texte, '.
122
			'zone_geo, lieudit, station, milieu, date_observation, do.mots_cles_texte, '.
122
			'date_transmission, commentaire, '.
123
			'do.date_transmission, do.commentaire, '.
123
			'ce_utilisateur AS `auteur.id`, prenom_utilisateur AS `auteur.prenom`, '.
124
			'do.ce_utilisateur AS `auteur.id`, do.prenom_utilisateur AS `auteur.prenom`, '.
124
			'nom_utilisateur AS `auteur.nom`, courriel_utilisateur AS `auteur.courriel`, '.
125
			'do.nom_utilisateur AS `auteur.nom`, do.courriel_utilisateur AS `auteur.courriel`, '.
125
			'id_image, date_prise_de_vue AS `date`, hauteur, largeur, nom_original '.
126
			'id_image, date_prise_de_vue AS `date`, hauteur, largeur, nom_original '.
126
			'FROM v_del_image AS vdi '.
127
			'FROM del_observation AS do '.
-
 
128
			'	LEFT JOIN del_image AS di ON (do.id_observation = di.ce_observation) '.
127
			"WHERE id_observation IN ($idsObsConcat) ".
129
			"WHERE id_observation IN ($idsObsConcat) ".
128
			' -- '.__FILE__.':'.__LINE__;
130
			' -- '.__FILE__.':'.__LINE__;
129
		return $this->bdd->recupererTous($requete);
131
		return $this->bdd->recupererTous($requete);
130
	}
132
	}
131
 
133
 
132
	/**
134
	/**
133
	 * Les informations étant extraites d'une vue dont les infos des obs sont dupliquées pour chaque image,
135
	 * Les informations étant extraites d'une vue dont les infos des obs sont dupliquées pour chaque image,
134
	 * il nous faut maintenant récupérer qu'une seule fois les données d'observations et y intégrer les données
136
	 * il nous faut maintenant récupérer qu'une seule fois les données d'observations et y intégrer les données
135
	 * des images.
137
	 * des images.
136
	 */
138
	 */
137
	private function formaterObservations($observations) {
139
	private function formaterObservations($observations) {
138
		$observations = array_map('array_filter', $observations);
140
		$observations = array_map('array_filter', $observations);
139
		$obsFormatees = array();
141
		$obsFormatees = array();
140
		foreach ($observations as $obs) {
142
		foreach ($observations as $obs) {
141
			$this->nettoyerAuteur($obs);
143
			$this->nettoyerAuteur($obs);
142
			$image = $this->extraireInfosImage($obs);
144
			$image = $this->extraireInfosImage($obs);
143
 
145
 
144
			$id = 'idx-'.$obs['id_observation'];
146
			$id = 'idx-'.$obs['id_observation'];
145
			if (!isset($obsFormatees[$id])) {
147
			if (!isset($obsFormatees[$id])) {
146
				$obsFormatees[$id] = $obs;
148
				$obsFormatees[$id] = $obs;
147
			}
149
			}
148
			$obsFormatees[$id]['images'][] = $image;
150
			$obsFormatees[$id]['images'][] = $image;
149
		}
151
		}
150
		return $obsFormatees;
152
		return $obsFormatees;
151
	}
153
	}
152
 
154
 
153
	private function nettoyerAuteur(&$obs) {
155
	private function nettoyerAuteur(&$obs) {
154
		// car auteur.id peut être un email, un hash, ou un annuaire_tela.U_ID
156
		// car auteur.id peut être un email, un hash, ou un annuaire_tela.U_ID
155
		// mais dans les deux premiers cas SELECT courriel AS observateur fait déjà l'affaire
157
		// mais dans les deux premiers cas SELECT courriel AS observateur fait déjà l'affaire
156
		if (!isset($obs['auteur.id']) || !is_numeric($obs['auteur.id'])) {
158
		if (!isset($obs['auteur.id']) || !is_numeric($obs['auteur.id'])) {
157
			$obs['auteur.id'] = "0";
159
			$obs['auteur.id'] = "0";
158
		}
160
		}
159
		if (!isset($obs['auteur.nom'])) {
161
		if (!isset($obs['auteur.nom'])) {
160
			$obs['auteur.nom'] = '[inconnu]';
162
			$obs['auteur.nom'] = '[inconnu]';
161
		}
163
		}
162
	}
164
	}
163
 
165
 
164
	private function extraireInfosImage(&$obs) {
166
	private function extraireInfosImage(&$obs) {
165
		$champsImageAffichables = array('id_image', 'date', 'hauteur' , 'largeur', 'nom_original');
167
		$champsImageAffichables = array('id_image', 'date', 'hauteur' , 'largeur', 'nom_original');
166
		$image = array_intersect_key($obs, array_flip($champsImageAffichables));
168
		$image = array_intersect_key($obs, array_flip($champsImageAffichables));
167
 
-
 
168
		$urlImgTpl = $this->conteneur->getParametre('cel_img_url_tpl');
169
		$urlImgTpl = $this->conteneur->getParametre('cel_img_url_tpl');
169
		$image['binaire.href'] = sprintf($urlImgTpl, $image['id_image'], 'XL');
170
		$image['binaire.href'] = sprintf($urlImgTpl, $image['id_image'], 'XL');
170
 
171
 
171
		unset($obs['id_image'], $obs['date'], $obs['hauteur'], $obs['largeur'], $obs['nom_original']);
172
		unset($obs['id_image'], $obs['date'], $obs['hauteur'], $obs['largeur'], $obs['nom_original']);
172
		return $image;
173
		return $image;
173
	}
174
	}
174
 
175
 
175
	private function ordonnerObservations($observations, $ordreDesObs) {
176
	private function ordonnerObservations($observations, $ordreDesObs) {
176
		$obsOrdonnees = array();
177
		$obsOrdonnees = array();
177
		foreach ($ordreDesObs as $id) {
178
		foreach ($ordreDesObs as $id) {
178
			if (array_key_exists("idx-$id", $observations)) {
179
			if (array_key_exists("idx-$id", $observations)) {
179
				$obsOrdonnees["idx-$id"] = $observations["idx-$id"];
180
				$obsOrdonnees["idx-$id"] = $observations["idx-$id"];
180
				unset($observations["idx-$id"]);
181
				unset($observations["idx-$id"]);
181
			}
182
			}
182
		}
183
		}
183
		return $obsOrdonnees + $observations;
184
		return $obsOrdonnees + $observations;
184
	}
185
	}
185
 
186
 
186
	/**
187
	/**
187
	 * Récupérer toutes les déterminations et le nombre de commentaire au total
188
	 * Récupérer toutes les déterminations et le nombre de commentaire au total
188
	 * @param array $observations la liste des observations à mettre à jour
189
	 * @param array $observations la liste des observations à mettre à jour
189
	 */
190
	 */
190
	private function chargerDeterminations(&$observations, $idObs) {
191
	private function chargerDeterminations(&$observations, $idObs) {
191
		$idObsConcat = implode(',', $idObs);
192
		$idObsConcat = implode(',', $idObs);
192
		$requete = 'SELECT * '.
193
		$requete = 'SELECT * '.
193
			'FROM del_commentaire AS dc '.
194
			'FROM del_commentaire AS dc '.
194
			'WHERE dc.nom_sel IS NOT NULL '.
195
			'WHERE dc.nom_sel IS NOT NULL '.
195
			"AND ce_observation IN ($idObsConcat) ".
196
			"AND ce_observation IN ($idObsConcat) ".
196
			'-- '.__FILE__.':'.__LINE__;
197
			'-- '.__FILE__.':'.__LINE__;
197
 
198
 
198
		$propositions = $this->bdd->recupererTous($requete);
199
		$propositions = $this->bdd->recupererTous($requete);
199
		if ($propositions) {
200
		if ($propositions) {
200
			foreach ($propositions as $proposition) {
201
			foreach ($propositions as $proposition) {
201
				$idObs = $proposition['ce_observation'];
202
				$idObs = $proposition['ce_observation'];
202
				$idComment = $proposition['id_commentaire'];
203
				$idComment = $proposition['id_commentaire'];
203
				$comment = $this->formaterDetermination($idComment, $proposition);
204
				$comment = $this->formaterDetermination($idComment, $proposition);
204
				if ($comment) {
205
				if ($comment) {
205
					$observations["idx-$idObs"]['commentaires'][$idComment] = $comment;
206
					$observations["idx-$idObs"]['commentaires'][$idComment] = $comment;
206
				}
207
				}
207
			}
208
			}
208
		}
209
		}
209
	}
210
	}
210
 
211
 
211
	private function formaterDetermination($propositionId, $propositionInfos) {
212
	private function formaterDetermination($propositionId, $propositionInfos) {
212
		if (!$propositionInfos) return NULL;
213
		if (!$propositionInfos) return NULL;
213
 
214
 
214
		$propositionFormatee = array();
215
		$propositionFormatee = array();
215
		foreach ($this->mappings['commentaires'] as $nomChamp => $nomAttributJson) {
216
		foreach ($this->mappings['commentaires'] as $nomChamp => $nomAttributJson) {
216
			if (isset($propositionInfos[$nomChamp])) {
217
			if (isset($propositionInfos[$nomChamp])) {
217
				$propositionFormatee[$nomAttributJson] = $propositionInfos[$nomChamp];
218
				$propositionFormatee[$nomAttributJson] = $propositionInfos[$nomChamp];
218
			}
219
			}
219
		}
220
		}
220
 
221
 
221
		// Charger les votes sur les déterminations
222
		// Charger les votes sur les déterminations
222
		$requete = "SELECT * FROM del_commentaire_vote WHERE ce_proposition = $propositionId".
223
		$requete = "SELECT * FROM del_commentaire_vote WHERE ce_proposition = $propositionId".
223
			'-- '.__FILE__.':'.__LINE__;
224
			'-- '.__FILE__.':'.__LINE__;
224
		$resultatsVotes = $this->bdd->recupererTous($requete);
225
		$resultatsVotes = $this->bdd->recupererTous($requete);
225
		foreach ($resultatsVotes as $vote) {
226
		foreach ($resultatsVotes as $vote) {
226
			$propositionFormatee['votes'][$vote['id_vote']] = $this->formaterVote($vote);
227
			$propositionFormatee['votes'][$vote['id_vote']] = $this->formaterVote($vote);
227
		}
228
		}
228
 
229
 
229
		$propositionFormatee['nb_commentaires'] = $this->chargerNombreCommentaire($propositionId);
230
		$propositionFormatee['nb_commentaires'] = $this->chargerNombreCommentaire($propositionId);
230
 
231
 
231
		return $propositionFormatee;
232
		return $propositionFormatee;
232
	}
233
	}
233
 
234
 
234
	/**
235
	/**
235
	 * Formater un vote en fonction du fichier de configuration config_votes.ini
236
	 * Formater un vote en fonction du fichier de configuration config_votes.ini
236
	 * @param $votes array()
237
	 * @param $votes array()
237
	 */
238
	 */
238
	private function formaterVote($vote) {
239
	private function formaterVote($vote) {
239
		$voteFormate = array();
240
		$voteFormate = array();
240
		foreach ($vote as $nomChamp => $valeur) {
241
		foreach ($vote as $nomChamp => $valeur) {
241
			$voteFormate[$this->mappings['votes'][$nomChamp]] = $valeur;
242
			$voteFormate[$this->mappings['votes'][$nomChamp]] = $valeur;
242
		}
243
		}
243
		return $voteFormate;
244
		return $voteFormate;
244
	}
245
	}
245
 
246
 
246
	private function chargerNombreCommentaire($propositionId) {
247
	private function chargerNombreCommentaire($propositionId) {
247
		$requete = 'SELECT COUNT( id_commentaire ) AS nb '.
248
		$requete = 'SELECT COUNT( id_commentaire ) AS nb '.
248
			'FROM del_commentaire '.
249
			'FROM del_commentaire '.
249
			"WHERE ce_proposition = $propositionId ".
250
			"WHERE ce_proposition = $propositionId ".
250
			'GROUP BY ce_proposition '.
251
			'GROUP BY ce_proposition '.
251
			'-- '.__FILE__.':'.__LINE__;
252
			'-- '.__FILE__.':'.__LINE__;
252
		$commentaires = $this->bdd->recuperer($requete);
253
		$commentaires = $this->bdd->recuperer($requete);
253
		return $commentaires ? $commentaires['nb'] : 0;
254
		return $commentaires ? $commentaires['nb'] : 0;
254
	}
255
	}
255
}
256
}