Subversion Repositories eFlore/Projets.eflore-projets

Rev

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

Rev 1151 Rev 1152
1
<?php
1
<?php
2
// declare(encoding='UTF-8');
2
// declare(encoding='UTF-8');
3
/**
3
/**
4
 * Classe permettant d'obtenir le nom et les codes d'une zone administrative à partir de ces coordonnées (latitude et longitude).
4
 * Classe permettant d'obtenir le nom et les codes d'une zone administrative à partir de ces coordonnées (latitude et longitude).
5
 * La latitude et longitude doivent être exprimée par un nombre décimal.
5
 * La latitude et longitude doivent être exprimée par un nombre décimal.
6
 * Ce service fonctionne uniquement pour les zones administratives dont les contours ont été tracés dans OpenStreetMap.
6
 * Ce service fonctionne uniquement pour les zones administratives dont les contours ont été tracés dans OpenStreetMap.
7
 * Source des données : OpenStreetMap <http://wiki.openstreetmap.org>
7
 * Source des données : OpenStreetMap <http://wiki.openstreetmap.org>
8
 * Tag:boundary=administrative : <http://wiki.openstreetmap.org/wiki/Tag:boundary%3Dadministrative>
8
 * Tag:boundary=administrative : <http://wiki.openstreetmap.org/wiki/Tag:boundary%3Dadministrative>
9
 * Paramètres du service :
9
 * Paramètres du service :
10
 *  - lat : latitude
10
 *  - lat : latitude
11
 *  - lon : longitude
11
 *  - lon : longitude
12
 * Exemple :
12
 * Exemple :
13
 * http://localhost/service-test:eflore:0.1/osm/nom-commune?lon=3.83619&lat=44.74231
13
 * http://localhost/service-test:eflore:0.1/osm/nom-commune?lon=3.83619&lat=44.74231
14
 *
14
 *
15
 * @category	php 5.2
15
 * @category	php 5.2
16
 * @package		eFlore
16
 * @package		eFlore
17
 * @subpackage	Services
17
 * @subpackage	Services
18
 * @author		Jean-Pascal MILCENT <jpm@tela-botanica.org>
18
 * @author		Jean-Pascal MILCENT <jpm@tela-botanica.org>
19
 * @author		Mohcen BENMOUNAH <mohcen@tela-botanica.org>
19
 * @author		Mohcen BENMOUNAH <mohcen@tela-botanica.org>
20
 * @copyright	Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org)
20
 * @copyright	Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org)
21
 * @license		CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt>
21
 * @license		CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt>
22
 * @license		GNU-GPL <http://www.gnu.org/licenses/gpl.html>
22
 * @license		GNU-GPL <http://www.gnu.org/licenses/gpl.html>
23
 */
23
 */
24
class ZoneADmin {
24
class ZoneADmin {
25
 
25
 
26
	const PATTERN_LAT = '/^[-]?[0-9]+(?:[.][0-9]+|)$/';
26
	const PATTERN_LAT = '/^[-]?[0-9]+(?:[.][0-9]+|)$/';
27
	const PATTERN_LON = '/^[-]?[0-9]+(?:[.][0-9]+|)$/';
27
	const PATTERN_LON = '/^[-]?[0-9]+(?:[.][0-9]+|)$/';
28
	const MIME_JSON = 'application/json';
28
	const MIME_JSON = 'application/json';
29
 
29
 
30
	private $parametres = array();
30
	private $parametres = array();
31
	private $bdd = null;
31
	private $bdd = null;
32
 
32
 
33
	private $lat = null;
33
	private $lat = null;
34
	private $lon = null;
34
	private $lon = null;
35
	private $zone = null;
35
	private $zone = null;
36
	private $niveaux = null;
36
	private $niveaux = null;
37
	private $pays = null;
37
	private $pays = null;
38
	
38
	
39
	private $masque = null;
39
	private $masque = null;
40
	private $limite = 1;
40
	private $limite = 1;
41
 
41
 
42
	public function __construct(Bdd $bdd) {
42
	public function __construct(Bdd $bdd) {
43
		$this->bdd = $bdd;
43
		$this->bdd = $bdd;
44
	}
44
	}
45
 
45
 
46
	public function consulter($ressources, $parametres) {
46
	public function consulter($ressources, $parametres) {
47
		$this->parametres = $parametres;
47
		$this->parametres = $parametres;
48
		$this->verifierParametres();
48
		$this->verifierParametres();
49
		$this->masque = isset($this->parametres['masque']) ? $this->parametres['masque'] : null;
49
		$this->masque = isset($this->parametres['masque']) ? $this->parametres['masque'] : null;
50
		$this->limite = isset($this->parametres['limite']) ? intval($this->parametres['limite']) : $this->limite;
50
		$this->limite = isset($this->parametres['limite']) ? intval($this->parametres['limite']) : $this->limite;
51
		$this->lat = isset($this->parametres['lat']) ? $this->parametres['lat'] : null;
51
		$this->lat = isset($this->parametres['lat']) ? $this->parametres['lat'] : null;
52
		$this->lon = isset($this->parametres['lon']) ? $this->parametres['lon'] : null;
52
		$this->lon = isset($this->parametres['lon']) ? $this->parametres['lon'] : null;
53
		$this->zone = isset($this->parametres['zone']) ? $this->parametres['zone'] : null;
53
		$this->zone = isset($this->parametres['zone']) ? $this->parametres['zone'] : null;
54
		$this->niveaux = isset($this->parametres['niveau']) ? explode(',', $this->parametres['niveau']) : null;
54
		$this->niveaux = isset($this->parametres['niveau']) ? explode(',', $this->parametres['niveau']) : null;
55
		$this->pays = isset($this->parametres['pays']) ? $this->parametres['pays'] : null;
55
		$this->pays = isset($this->parametres['pays']) ? $this->parametres['pays'] : null;
56
		
56
		
57
		if($this->masque != null) {
57
		if($this->masque != null) {
58
			$corps = $this->rechercherZoneGeoParNom($this->masque, $this->niveaux, $this->limite, $this->pays);
58
			$corps = $this->rechercherZoneGeoParNom($this->masque, $this->niveaux, $this->limite, $this->pays);
59
		} else {
59
		} else {
60
			$zoneTrouveeInfos = $this->localiserPointLatLon();
60
			$zoneTrouveeInfos = $this->localiserPointLatLon();
61
			$corps = $this->formaterResultats($zoneTrouveeInfos);
61
			$corps = $this->formaterResultats($zoneTrouveeInfos);
62
		}
62
		}
63
 
63
 
64
		$resultat = new ResultatService();
64
		$resultat = new ResultatService();
65
		$resultat->mime = self::MIME_JSON;
65
		$resultat->mime = self::MIME_JSON;
66
		$resultat->corps = $corps;
66
		$resultat->corps = $corps;
67
		return $resultat;
67
		return $resultat;
68
	}
68
	}
69
 
69
 
70
	private function verifierParametres() {
70
	private function verifierParametres() {
71
		extract($this->parametres);
71
		extract($this->parametres);
72
		$messages = array();
72
		$messages = array();
73
		
73
		
74
		if(array_key_exists('masque', $this->parametres)) {
74
		if(array_key_exists('masque', $this->parametres)) {
75
			if (empty($masque)) {
75
			if (empty($masque)) {
76
				$messages[] = "S'il est présent le paramètre recherche ne peut pas être vide";
76
				$messages[] = "S'il est présent le paramètre recherche ne peut pas être vide";
77
			}
77
			}
78
		} else {	
78
		} else {	
79
			if (! array_key_exists('lat', $this->parametres)) {
79
			if (! array_key_exists('lat', $this->parametres)) {
80
				$messages[] = "Vous devez indiquer une latitude en degré décimal à l'aide du paramètres d'url : lat";
80
				$messages[] = "Vous devez indiquer une latitude en degré décimal à l'aide du paramètres d'url : lat";
81
			} else if (!preg_match(self::PATTERN_LAT, $lat)) {
81
			} else if (!preg_match(self::PATTERN_LAT, $lat)) {
82
				$messages[] = "La valeur de latitude doit être un nombre décimal dont le séparateur décimal est un point. Ex. : 44 ou 43.03";
82
				$messages[] = "La valeur de latitude doit être un nombre décimal dont le séparateur décimal est un point. Ex. : 44 ou 43.03";
83
			}
83
			}
84
			if (! array_key_exists('lon', $this->parametres)) {
84
			if (! array_key_exists('lon', $this->parametres)) {
85
				$messages[] = "Vous devez indiquer une longitude en degré décimal à l'aide du paramètres d'url : lon";
85
				$messages[] = "Vous devez indiquer une longitude en degré décimal à l'aide du paramètres d'url : lon";
86
			} else if (!preg_match(self::PATTERN_LON, $lon)) {
86
			} else if (!preg_match(self::PATTERN_LON, $lon)) {
87
				$messages[] = "La valeur de longitude doit être un nombre décimal dont le séparateur décimal est un point. Ex. : -4.03 ou 3.256";
87
				$messages[] = "La valeur de longitude doit être un nombre décimal dont le séparateur décimal est un point. Ex. : -4.03 ou 3.256";
88
			}
88
			}
89
		}
89
		}
90
		if (count($messages) != 0) {
90
		if (count($messages) != 0) {
91
			$message = implode('<br />', $messages);
91
			$message = implode('<br />', $messages);
92
			$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
92
			$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
93
			throw new Exception($message, $code);
93
			throw new Exception($message, $code);
94
		}
94
		}
95
	}
95
	}
96
 
96
 
97
	private function formaterResultats($zonesTrouveesInfos) {
97
	private function formaterResultats($zonesTrouveesInfos) {
98
		$retour = array();
98
		$retour = array();
99
		foreach ($zonesTrouveesInfos as $infos) {
99
		foreach ($zonesTrouveesInfos as $infos) {
100
			$donnees = array();
100
			$donnees = array();
101
			foreach ($infos as $champ => $valeur) {
101
			foreach ($infos as $champ => $valeur) {
102
				if ($valeur != '' && $champ != 'niveau') {
102
				if ($valeur != '' && $champ != 'niveau') {
103
					if ($champ == 'wikipedia') {
103
					if ($champ == 'wikipedia') {
104
						$valeur = $this->formaterUrlWikipedia($valeur);
104
						$valeur = $this->formaterUrlWikipedia($valeur);
105
					}
105
					}
106
					$donnees[$champ] = $valeur;
106
					$donnees[$champ] = $valeur;
107
				}
107
				}
108
			}
108
			}
109
			$retour[$infos['niveau']] = $donnees;
109
			$retour[$infos['niveau']] = $donnees;
110
		}
110
		}
111
		ksort($retour);
111
		ksort($retour);
112
		return $retour;
112
		return $retour;
113
	}
113
	}
114
 
114
 
115
	private function localiserPointLatLon() {
115
	private function localiserPointLatLon() {
116
		$osmIdsInClause = $this->getOsmIdsDesCentresAProximites();
116
		$osmIdsInClause = $this->getOsmIdsDesCentresAProximites();
117
		$zone = isset($this->zone) ? $this->bdd->proteger($this->zone) : null;
117
		$zone = isset($this->zone) ? $this->bdd->proteger($this->zone) : null;
118
 
118
 
119
		$requete = 'SELECT id_zone_geo AS codeZoneGeo, intitule, code_iso_3166_1 AS codeIso31661, '.
119
		$requete = 'SELECT id_zone_geo AS codeZoneGeo, intitule, code_iso_3166_1 AS codeIso31661, '.
120
			'code_iso_3166_2 AS codeIso31662, code_insee AS codeInsee, code_nuts as codeNuts, '.
120
			'code_iso_3166_2 AS codeIso31662, code_insee AS codeInsee, code_nuts as codeNuts, '.
121
			'nom_en AS nomEn, nom_es AS nomEs, wikipedia, niveau '.
121
			'nom_en AS nomEn, nom_es AS nomEs, wikipedia, niveau '.
122
			'FROM osm_zones_admin '.
122
			'FROM osm_zones_admin '.
123
			"WHERE st_within(GEOMFROMTEXT('POINT($this->lon $this->lat)'), polygone) = 1 ".
123
			"WHERE st_within(GEOMFROMTEXT('POINT($this->lon $this->lat)'), polygone) = 1 ".
124
			(isset($zone) ? "AND zone = $zone " : '').
124
			(isset($zone) ? "AND zone = $zone " : '').
125
			"AND osm_id IN ($osmIdsInClause) ".
125
			"AND osm_id IN ($osmIdsInClause) ".
126
			' -- '.__FILE__.' : '.__LINE__;
126
			' -- '.__FILE__.' : '.__LINE__;
127
		
127
		
128
		$resultat = $this->bdd->recupererTous($requete);
128
		$resultat = $this->bdd->recupererTous($requete);
129
		if ($resultat === false) {
129
		if ($resultat === false) {
130
			$msgTpl = "Service '%s' : aucune zone correspondant aux coordonnées : %s, %s.";
130
			$msgTpl = "Service '%s' : aucune zone correspondant aux coordonnées : %s, %s.";
131
			$msg = sprintf($msgTpl, get_class($this), $this->lat, $this->lon);
131
			$msg = sprintf($msgTpl, get_class($this), $this->lat, $this->lon);
132
			throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
132
			throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
133
		}
133
		}
134
		return $resultat;
134
		return $resultat;
135
	}
135
	}
136
 
136
 
137
	private function getOsmIdsDesCentresAProximites() {
137
	private function getOsmIdsDesCentresAProximites() {
138
		$requete = $this->construireRequeteUnion();
138
		$requete = $this->construireRequeteUnion();
139
		$resultats = $this->bdd->recupererTous($requete);
139
		$resultats = $this->bdd->recupererTous($requete);
140
		if ($resultats === false) {
140
		if ($resultats === false) {
141
			$msgTpl = "Service '%s' : aucun centroïde correspondant aux coordonnées : %s, %s.";
141
			$msgTpl = "Service '%s' : aucun centroïde correspondant aux coordonnées : %s, %s.";
142
			$msg = sprintf($msgTpl, get_class($this), $this->lat, $this->lon);
142
			$msg = sprintf($msgTpl, get_class($this), $this->lat, $this->lon);
143
			throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
143
			throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
144
		}
144
		}
145
		$osmIds = array();
145
		$osmIds = array();
146
		foreach ($resultats as $info) {
146
		foreach ($resultats as $info) {
147
			$osmIds[] = $info['osm_id'];
147
			$osmIds[] = $info['osm_id'];
148
		}
148
		}
149
		$osmIdsInClause = implode(',', $this->bdd->proteger($osmIds));
149
		$osmIdsInClause = implode(',', $this->bdd->proteger($osmIds));
150
		return $osmIdsInClause;
150
		return $osmIdsInClause;
151
	}
151
	}
152
 
152
 
153
	private function construireRequeteUnion() {
153
	private function construireRequeteUnion() {
154
		$zone = isset($this->zone) ? $this->bdd->proteger($this->zone) : null;
154
		$zone = isset($this->zone) ? $this->bdd->proteger($this->zone) : null;
155
		$niveaux = isset($this->niveaux) ? $this->niveaux : null;
155
		$niveaux = isset($this->niveaux) ? $this->niveaux : null;
156
		
156
		
157
		$requeteTpl = 'SELECT osm_id, '.
157
		$requeteTpl = 'SELECT osm_id, '.
158
			"(($this->lon - centre_lng) * ($this->lon -centre_lng) + ($this->lat - centre_lat) * ($this->lat - centre_lat)) AS distance ".
158
			"(($this->lon - centre_lng) * ($this->lon -centre_lng) + ($this->lat - centre_lat) * ($this->lat - centre_lat)) AS distance ".
159
			'FROM osm_zones_admin '.
159
			'FROM osm_zones_admin '.
160
			'WHERE niveau = %s '.
160
			'WHERE niveau = %s '.
161
			(isset($zone) ? "AND zone = $zone " : '').
161
			(isset($zone) ? "AND zone = $zone " : '').
162
			'ORDER BY distance ASC '.
162
			'ORDER BY distance ASC '.
163
			"LIMIT %s ";
163
			"LIMIT %s ";
164
		$niveaux = isset($niveaux) ? $niveaux : array(2,3,4,5,6,7,8);
164
		$niveaux = isset($niveaux) ? $niveaux : array(2,3,4,5,6,7,8);
165
		$requetesAUnir = array();
165
		$requetesAUnir = array();
166
		foreach ($niveaux as $niveau) {
166
		foreach ($niveaux as $niveau) {
167
			$requetesAUnir[] = sprintf($requeteTpl, $this->bdd->proteger($niveau), ($niveau * 2));
167
			$requetesAUnir[] = sprintf($requeteTpl, $this->bdd->proteger($niveau), ($niveau * 2));
168
		}
168
		}
169
		$requete = '('.implode(') UNION (', $requetesAUnir).') -- '.__FILE__.' : '.__LINE__;
169
		$requete = '('.implode(') UNION (', $requetesAUnir).') -- '.__FILE__.' : '.__LINE__;
170
		return $requete;
170
		return $requete;
171
	}
171
	}
172
 
172
 
173
	private function formaterUrlWikipedia($infoWikipedia) {
173
	private function formaterUrlWikipedia($infoWikipedia) {
174
		list($lang, $page) = explode(':', $infoWikipedia);
174
		list($lang, $page) = explode(':', $infoWikipedia);
175
		$pageEncode = rawurlencode($page);
175
		$pageEncode = rawurlencode($page);
176
		$urlTpl = 'https://%s.wikipedia.org/wiki/%s';
176
		$urlTpl = 'https://%s.wikipedia.org/wiki/%s';
177
		return sprintf($urlTpl, $lang, $pageEncode);
177
		return sprintf($urlTpl, $lang, $pageEncode);
178
	}
178
	}
179
	
179
	
180
	public function rechercherZoneGeoParNom($masque, $niveaux = null, $limite = 1, $pays = null) {
180
	public function rechercherZoneGeoParNom($masque, $niveaux = null, $limite = 1, $pays = null) {
181
		$masque_fmt = str_replace(array(' ', '-'), '_', $masque);
181
		$masque_fmt = str_replace(array(' ', '-'), '_', $masque);
182
		// Cas d'une recherche pour autocompletion
182
		// Cas d'une recherche pour autocompletion
183
		$masque_fmt = ($limite > 1) ? $masque_fmt.'%' : $masque_fmt;
183
		$masque_fmt = ($limite > 1) ? $masque_fmt.'%' : $masque_fmt;
184
		
184
		
185
		$champs = 'id_zone_geo, osm_id, intitule, centre_lat, centre_lng, '.
185
		$champs = 'id_zone_geo, osm_id, intitule, centre_lat, centre_lng, '.
186
					'zone, niveau, code_iso_3166_1 AS codeIso31661, code_iso_3166_2 AS codeIso31662, code_insee, '.
186
					'zone, niveau, code_iso_3166_1 AS codeIso31661, code_iso_3166_2 AS codeIso31662, code_insee, '.
187
					'nom, nom_fr, nom_en, nom_es, wikipedia';
187
					'nom, nom_fr, nom_en, nom_es, wikipedia';
188
		
188
		
189
		$champs_tri = 'IF(ISNULL(nom_fr), 0, 1) as nom_fr_present, '.
189
		$champs_tri = 'IF(ISNULL(nom_fr), 0, 1) as nom_fr_present, '.
190
				'IF(ISNULL(nom_en), 0, 1) as nom_en_present, '.
190
				'IF(ISNULL(nom_en), 0, 1) as nom_en_present, '.
191
				'IF(ISNULL(nom_es), 0, 1) as nom_es_present, '.
191
				'IF(ISNULL(nom_es), 0, 1) as nom_es_present, '.
192
				'IF(ISNULL(intitule), 0, 1) as intitule_present, '.
192
				'IF(ISNULL(intitule), 0, 1) as intitule_present, '.
193
				'IF(ISNULL(nom), 0, 1) as nom_present ';
193
				'IF(ISNULL(nom), 0, 1) as nom_present ';
194
		
194
		
195
		$ordre = 'nom_present DESC, nom_fr_present DESC, nom_fr_present DESC, '.
195
		$ordre = 'nom_present DESC, nom_fr_present DESC, nom_fr_present DESC, '.
196
				 'nom_es_present DESC, intitule_present DESC, niveau DESC';
196
				 'nom_es_present DESC, intitule_present DESC, niveau ASC';
197
		
197
		
198
		$niveau_str = array();
198
		$niveau_str = array();
199
		if($niveaux != null) {
199
		if($niveaux != null) {
200
			foreach ($niveaux as $niveau) {
200
			foreach ($niveaux as $niveau) {
201
				$niveau_str[] = $this->bdd->proteger($niveau);
201
				$niveau_str[] = $this->bdd->proteger($niveau);
202
			}
202
			}
203
		}
203
		}
204
		
204
		
205
		$pays_str = '';
205
		$pays_str = '';
206
		if($pays != null) {
206
		if($pays != null) {
207
			$pays_str = '(code_iso_3166_1 = '.$this->bdd->proteger($pays).' OR  '.
207
			$pays_str = '(code_iso_3166_1 = '.$this->bdd->proteger($pays).' OR  '.
208
			'code_iso_3166_2 LIKE '.$this->bdd->proteger($pays."%").')';
208
			'code_iso_3166_2 LIKE '.$this->bdd->proteger($pays."%").')';
209
		}
209
		}
210
		
210
		
211
		$requete = "SELECT $champs, $champs_tri FROM osm_zones_admin ".
211
		$requete = "SELECT $champs, $champs_tri FROM osm_zones_admin ".
212
					"WHERE ".
212
					"WHERE ".
213
						(!empty($niveau_str) ? ("niveau IN (".implode(',', $niveau_str).") AND ") : "").
213
						(!empty($niveau_str) ? ("niveau IN (".implode(',', $niveau_str).") AND ") : "").
214
						(!empty($pays_str) ? $pays_str.' AND ' : ""). 
214
						(!empty($pays_str) ? $pays_str.' AND ' : ""). 
215
						"(nom LIKE ".$this->bdd->proteger($masque_fmt).' OR '.
215
						"(nom LIKE ".$this->bdd->proteger($masque_fmt).' OR '.
216
						"intitule LIKE ".$this->bdd->proteger($masque_fmt).' OR '.
216
						"intitule LIKE ".$this->bdd->proteger($masque_fmt).' OR '.
217
						"nom_fr LIKE ".$this->bdd->proteger($masque_fmt).' OR '.
217
						"nom_fr LIKE ".$this->bdd->proteger($masque_fmt).' OR '.
218
						"nom_en LIKE ".$this->bdd->proteger($masque_fmt).' OR '.
218
						"nom_en LIKE ".$this->bdd->proteger($masque_fmt).' OR '.
219
						"nom_es LIKE ".$this->bdd->proteger($masque_fmt).') AND '.	
219
						"nom_es LIKE ".$this->bdd->proteger($masque_fmt).') '.	
220
			"ORDER BY ".$ordre." LIMIT ".$limite;
220
			"ORDER BY ".$ordre." LIMIT ".$limite;
221
 
221
 
222
		$resultat = $this->bdd->recupererTous($requete);
222
		$resultat = $this->bdd->recupererTous($requete);
223
		if (empty($resultat)) {
223
		if (empty($resultat)) {
224
			$msgTpl = "Service '%s' : aucune zone correspondant au nom : %s .";
224
			$msgTpl = "Service '%s' : aucune zone correspondant au nom : %s .";
225
			$msg = sprintf($msgTpl, get_class($this), $masque);
225
			$msg = sprintf($msgTpl, get_class($this), $masque);
226
			throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
226
			throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
227
		} else {
227
		} else {
228
			$resultat = ($limite == 1) ? $resultat[0] : $resultat;
228
			$resultat = ($limite == 1) ? $resultat[0] : $resultat;
229
		}
229
		}
230
		
230
		
231
		return $resultat;
231
		return $resultat;
232
	}
232
	}
233
}
233
}