Subversion Repositories eFlore/Applications.cel

Rev

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

Rev 3756 Rev 3758
1
<?php
1
<?php
2
 
2
 
3
/*
3
/*
4
	PHP 7
4
	PHP 7
5
 
5
 
6
	Script used to synchronize PN occ with CEL
6
	Script used to synchronize PN occ with CEL
7
*/
7
*/
8
 
8
 
9
class PullPlantnet extends Script {
9
class PullPlantnet extends Script {
10
 
10
 
11
	protected $bdd;
11
	protected $bdd;
12
 
12
 
13
	protected $allowedPartners = ['tb', 'pn'];
13
	protected $allowedPartners = ['tb', 'pn'];
14
 
14
 
15
	// Nom du fichier contenant les correspondances d'ID TB/PN
15
	// Nom du fichier contenant les correspondances d'ID TB/PN
16
	protected $correspondingIdsFilename = '';
16
	protected $correspondingIdsFilename = '';
17
 
17
 
18
	// Cache d'informations utilisateurs provenant de l'annuaire TB
18
	// Cache d'informations utilisateurs provenant de l'annuaire TB
19
	protected $userInfos = [];
19
	protected $userInfos = [];
-
 
20
 
-
 
21
	// Cache des obs id PN traitées pendant cette run
-
 
22
	protected $processedObsId = [];
20
 
23
 
21
	// Paramètre de suivi et de pagination de l'API des obs PN
24
	// Paramètre de suivi et de pagination de l'API des obs PN
22
	protected $startDate = '';
25
	protected $startDate = '';
23
	protected $currentPage = '';
26
	protected $currentPage = '';
24
	protected $currentProject = '';
27
	protected $currentProject = '';
25
	protected $hasMore = false;
28
	protected $hasMore = false;
26
	protected $count = 0;
29
	protected $count = 0;
27
 
30
 
28
	// Traduction des organes de PN
31
	// Traduction des organes de PN
29
	protected $tagsImageTraduits = [
32
	protected $tagsImageTraduits = [
30
		'flower' => 'fleur',
33
		'flower' => 'fleur',
31
		'fruit' => 'fruit',
34
		'fruit' => 'fruit',
32
		'leaf' => 'feuille',
35
		'leaf' => 'feuille',
33
		'bark' => 'écorce',
36
		'bark' => 'écorce',
34
		'branch' => 'branche',
37
		'branch' => 'branche',
35
		'habit' => 'port',
38
		'habit' => 'port',
36
	];
39
	];
37
 
40
 
38
	/**
41
	/**
39
	 * Paramêtres par défaut disponibles pour la ligne de commande
42
	 * Paramêtres par défaut disponibles pour la ligne de commande
40
	 * le tableau se construit de la forme suivante :
43
	 * le tableau se construit de la forme suivante :
41
	 * - clé =  nom du paramêtre '-foo'
44
	 * - clé =  nom du paramêtre '-foo'
42
	 * - value = contient un nouveau tableau composé de cette façon :
45
	 * - value = contient un nouveau tableau composé de cette façon :
43
	 *  - booléen: true si le paramêtre est obligatoire
46
	 *  - booléen: true si le paramêtre est obligatoire
44
	 *  - booléen ou var : true si le paramêtre nécessite un valeur à sa suite ou la valeur par défaut
47
	 *  - booléen ou var : true si le paramêtre nécessite un valeur à sa suite ou la valeur par défaut
45
	 *  - string: description du contenu du paramêtre
48
	 *  - string: description du contenu du paramêtre
46
	 * Les paramêtres optionels devraient être déclaré à la fin du tableau.
49
	 * Les paramêtres optionels devraient être déclaré à la fin du tableau.
47
	 * Le dernier parametre du tableau peut avoir la valeur '...',
50
	 * Le dernier parametre du tableau peut avoir la valeur '...',
48
	 * il contiendra alors l'ensemble des paramêtres suivant trouvés sur la ligne de commande.
51
	 * il contiendra alors l'ensemble des paramêtres suivant trouvés sur la ligne de commande.
49
	 * @var array
52
	 * @var array
50
	 */
53
	 */
51
	protected $parametres_autorises = array(
54
	protected $parametres_autorises = array(
52
		'-startDate' => array(false, '1', 'Date de début (parsée par strtotime). Ex: "YYYY:MM:DD HH:II:SS"'),
55
		'-startDate' => array(false, '1', 'Date de début (parsée par strtotime). Ex: "YYYY:MM:DD HH:II:SS"'),
53
		'-pnObsId' => array(false, true, "ID de l'obs chez PlantNet"),
56
		'-pnObsId' => array(false, true, "ID de l'obs chez PlantNet"),
54
		'-tbObsId' => array(false, true, "ID de l'obs chez Tela"),
57
		'-tbObsId' => array(false, true, "ID de l'obs chez Tela"),
55
	);
58
	);
56
 
59
 
57
	public function __construct($script_nom, $parametres_cli) {
60
	public function __construct($script_nom, $parametres_cli) {
58
		parent::__construct($script_nom, $parametres_cli);
61
		parent::__construct($script_nom, $parametres_cli);
59
		$this->bdd = new Bdd();
62
		$this->bdd = new Bdd();
60
 
63
 
61
		$this->correspondingIdsFilename = Config::get('correspondingIdsFilename');
64
		$this->correspondingIdsFilename = Config::get('correspondingIdsFilename');
62
	}
65
	}
63
 
66
 
64
	public function executer() {
67
	public function executer() {
65
		$cmd = $this->getParametre('a');
68
		$cmd = $this->getParametre('a');
66
 
69
 
67
		switch ($cmd) {
70
		switch ($cmd) {
68
			case 'updateLatest':
71
			case 'updateLatest':
69
				$this->updateLatest($this->getParametre('startDate'));
72
				$this->updateLatest($this->getParametre('startDate'));
70
				break;
73
				break;
71
			case 'updateOnePN':
74
			case 'updateOnePN':
72
				$this->updateOne($this->getParametre('pnObsId'));
75
				$this->updateOne($this->getParametre('pnObsId'));
73
				break;
76
				break;
74
			case 'updateOneTB':
77
			case 'updateOneTB':
75
				$this->updateOneTB($this->getParametre('tbObsId'));
78
				$this->updateOneTB($this->getParametre('tbObsId'));
76
				break;
79
				break;
77
			case 'updateCorrespondingIdsTable':
80
			case 'updateCorrespondingIdsTable':
78
				$this->updateCorrespondingIdsTable();
81
				$this->updateCorrespondingIdsTable();
79
				break;
82
				break;
80
			default:
83
			default:
81
				$msg = "Erreur : la commande '$cmd' n'existe pas!\n"
84
				$msg = "Erreur : la commande '$cmd' n'existe pas!\n"
82
						. ', utilisez plutôt :' . "\n"
85
						. ', utilisez plutôt :' . "\n"
83
						. 'php cli.php PullPlantnet -a updateLatest -startDate "YYYY:MM:DD HH:II:SS"' . "\n"
86
						. 'php cli.php PullPlantnet -a updateLatest -startDate "YYYY:MM:DD HH:II:SS"' . "\n"
84
						. 'php cli.php PullPlantnet -a updateOnePN -pnObsId "xxxxxx"' . "\n"
87
						. 'php cli.php PullPlantnet -a updateOnePN -pnObsId "xxxxxx"' . "\n"
85
						. 'php cli.php PullPlantnet -a updateOneTB -tbObsId "xxxxxx"' . "\n"
88
						. 'php cli.php PullPlantnet -a updateOneTB -tbObsId "xxxxxx"' . "\n"
86
						. 'php cli.php PullPlantnet -a updateCorrespondingIdsTable' . "\n"
89
						. 'php cli.php PullPlantnet -a updateCorrespondingIdsTable' . "\n"
87
						;
90
						;
88
				throw new Exception($msg);
91
				throw new Exception($msg);
89
		}
92
		}
90
	}
93
	}
91
 
94
 
92
	/**
95
	/**
93
	 * Considering all modified pn obs since startDate
96
	 * Considering all modified pn obs since startDate
94
	 * One pn project after an other
97
	 * One pn project after an other
95
	 * Inserting obs in tb db (if new and matching user email)
98
	 * Inserting obs in tb db (if new and matching user email)
96
	 */
99
	 */
97
	private function updateLatest(string $startDate = '1917:03:15 00:00:00') {
100
	private function updateLatest(string $startDate = '1917:03:15 00:00:00') {
98
		$this->startDate = strtotime($startDate) * 1000; // we need a microtimestamp
101
		$this->startDate = strtotime($startDate) * 1000; // we need a microtimestamp
99
 
102
 
100
		$pnProjects = $this->getProjects(); // refresh projects list
103
		$pnProjects = $this->getProjects(); // refresh projects list
101
		foreach ($pnProjects as $project) {
104
		foreach ($pnProjects as $project) {
102
			do {
105
			do {
103
				$observations_PN = $this->getProjectLatest($project);
106
				$observations_PN = $this->getProjectLatest($project);
104
				$this->updateObs($observations_PN);
107
				$this->updateObs($observations_PN);
105
			} while ($this->hasMore);
108
			} while ($this->hasMore);
106
		}
109
		}
107
	}
110
	}
108
 
111
 
109
	private function getProjectLatest(array $project): array {
112
	private function getProjectLatest(array $project): array {
110
		$this->currentProject = $project;
113
		$this->currentProject = $project;
111
 
114
 
112
		if (!$this->currentPage) {
115
		if (!$this->currentPage) {
113
			echo 'Projet ' . $project['name'] . "\n";
116
			echo 'Projet ' . $project['name'] . "\n";
114
 
117
 
115
			// hop, on appelle le service de PN
118
			// hop, on appelle le service de PN
116
			$url_service = str_replace(
119
			$url_service = str_replace(
117
				['{project}', '{token}', '{startDate}'],
120
				['{project}', '{token}', '{startDate}'],
118
				[$project['id'], Config::get('tokenPlantnet'), $this->startDate],
121
				[$project['id'], Config::get('tokenPlantnet'), $this->startDate],
119
				Config::get('urlPlantnetBase').Config::get('urlPlantnetLatestChanges')
122
				Config::get('urlPlantnetBase').Config::get('urlPlantnetLatestChanges')
120
			);
123
			);
121
			// die(var_dump($url_service));
124
			// die(var_dump($url_service));
122
			$this->currentPage = $url_service;
125
			$this->currentPage = $url_service;
123
		}
126
		}
124
 
127
 
125
		$ch = curl_init($this->currentPage);
128
		$ch = curl_init($this->currentPage);
126
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
129
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
127
		$reponse = curl_exec($ch);
130
		$reponse = curl_exec($ch);
128
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
131
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
129
		curl_close($ch);
132
		curl_close($ch);
130
 
133
 
131
		// cool, maintenant on va trier ce qu'on a reçu
134
		// cool, maintenant on va trier ce qu'on a reçu
132
		if (!$reponse) {
135
		if (!$reponse) {
133
			throw new Exception("\nPN ne répond rien à l'adresse {$this->currentPage}\n");
136
			throw new Exception("\nPN ne répond rien à l'adresse {$this->currentPage}\n");
134
		} elseif (200 != $code) {
137
		} elseif (200 != $code) {
135
			// l'api répond avec une 404 quand y'a une date dans le futur ou simplement pas de nouvelle obs...
138
			// l'api répond avec une 404 quand y'a une date dans le futur ou simplement pas de nouvelle obs...
136
			if (404 == $code && strpos($reponse, 'No more results')) {
139
			if (404 == $code && strpos($reponse, 'No more results')) {
137
				$this->hasMore = false;
140
				$this->hasMore = false;
138
				$this->currentPage = '';
141
				$this->currentPage = '';
139
				return [];
142
				return [];
140
			}
143
			}
141
			throw new Exception("\nPN répond avec une $code à l'adresse {$this->currentPage} : $reponse\n");
144
			throw new Exception("\nPN répond avec une $code à l'adresse {$this->currentPage} : $reponse\n");
142
		}
145
		}
143
		$responseJson = json_decode($reponse, true);
146
		$responseJson = json_decode($reponse, true);
144
		$observations_PN = $responseJson['data'] ?? [];
147
		$observations_PN = $responseJson['data'] ?? [];
145
 
148
 
146
		$this->hasMore = $responseJson['hasMore'];
149
		$this->hasMore = $responseJson['hasMore'];
147
		if ($this->hasMore) {
150
		if ($this->hasMore) {
148
			$this->count += count($observations_PN);
151
			$this->count += count($observations_PN);
149
			$this->currentPage = Config::get('urlPlantnetBase').$responseJson['next'].$this->count;
152
			$this->currentPage = Config::get('urlPlantnetBase').$responseJson['next'].$this->count;
150
		} else {
153
		} else {
151
			$this->currentPage = '';
154
			$this->currentPage = '';
152
			$this->count = 0;
155
			$this->count = 0;
153
		}
156
		}
154
 
157
 
155
		return $observations_PN;
158
		return $observations_PN;
156
	}
159
	}
157
 
160
 
158
	private function getProjects(): array {
161
	private function getProjects(): array {
159
		// get PN projects list
162
		// get PN projects list
160
		$url = str_replace('{token}', Config::get('tokenPlantnet'), Config::get('urlPlantnetBase').Config::get('urlPlantnetProjects'));
163
		$url = str_replace('{token}', Config::get('tokenPlantnet'), Config::get('urlPlantnetBase').Config::get('urlPlantnetProjects'));
161
 
164
 
162
		$ch = curl_init($url);
165
		$ch = curl_init($url);
163
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
166
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
164
		$reponse = curl_exec($ch);
167
		$reponse = curl_exec($ch);
165
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
168
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
166
		curl_close($ch);
169
		curl_close($ch);
167
 
170
 
168
		if (!$reponse || 200 != $code) {
171
		if (!$reponse || 200 != $code) {
169
			throw new Exception("\nPN répond avec une $code à l'adresse $url_service : $reponse\n");
172
			throw new Exception("\nPN répond avec une $code à l'adresse $url_service : $reponse\n");
170
		}
173
		}
171
		$pnProjects = json_decode($reponse, true);
174
		$pnProjects = json_decode($reponse, true);
172
 
175
 
173
		echo 'Liste de projets récupérée : ' . count($pnProjects) . " projets dans la liste\n";
176
		echo 'Liste de projets récupérée : ' . count($pnProjects) . " projets dans la liste\n";
174
 
177
 
175
		return $pnProjects;
178
		return $pnProjects;
176
	}
179
	}
177
 
180
 
178
	/**
181
	/**
179
	 * For a given bunch of plantnet obs, post new one threw saisie widget service
182
	 * For a given bunch of plantnet obs, post new one threw saisie widget service
180
	 */
183
	 */
181
	private function updateObs(array $observations_PN) {
184
	private function updateObs(array $observations_PN) {
182
 
185
 
183
		$url_cel_widget_saisie = Config::get('urlCelWidgetSaisie');
186
		$url_cel_widget_saisie = Config::get('urlCelWidgetSaisie');
184
 
187
 
185
		foreach ($observations_PN as $obs) {
188
		foreach ($observations_PN as $obs) {
-
 
189
			// est-ce qu'on a déjà traité cette obs ? (oui une même obs peut être dans plusieurs projects)
-
 
190
			if (in_array($obs['id'], $this->processedObsId)) {
-
 
191
				continue;
-
 
192
			} else {
-
 
193
				$this->processedObsId[] = $obs['id'];
-
 
194
			}
-
 
195
 
186
			// on ne teste pas la suppression de l'obs ici, faut le faire après avoir vérifié si on l'a déjà synchro
196
			// on ne teste pas la suppression de l'obs ici, faut le faire après avoir vérifié si on l'a déjà synchro
187
			if (!isset($obs['currentName'])) {
197
			if (!isset($obs['currentName'])) {
188
				continue; // pas de nom de taxon, obs inutile
198
				continue; // pas de nom de taxon, obs inutile
189
			}
199
			}
190
			if (!isset($obs['geo'])) {
200
			if (!isset($obs['geo'])) {
191
				continue; // pas de position, obs inutile
201
				continue; // pas de position, obs inutile
192
			}
202
			}
193
			if (!isset($obs['dateObs'])) {
203
			if (!isset($obs['dateObs'])) {
194
				continue; // pas de date, obs inutile
204
				continue; // pas de date, obs inutile
195
			}
205
			}
196
 
206
 
197
			if (isset($obs['partner']['id']) && 'tela' === $obs['partner']['id']) {
207
			if (isset($obs['partner']['id']) && 'tela' === $obs['partner']['id']) {
198
				// c'est une obs tela
208
				// c'est une obs tela
199
				// si c'est mis à jour récemment coté PN et qu'on l'a pas supprimée chez nous entre temps
209
				// si c'est mis à jour récemment coté PN et qu'on l'a pas supprimée chez nous entre temps
200
					// on update les votes PN
210
					// on update les votes PN
201
					// on update l'identification proposée par PN
211
					// on update l'identification proposée par PN
202
 
212
 
203
				// @TODO
213
				// @TODO
204
				continue;
214
				continue;
205
			} elseif (!isset($obs['partner']['id'])) {
215
			} elseif (!isset($obs['partner']['id'])) {
206
				// ce n'est pas une obs d'un partenaire, c'est donc une obs PN
216
				// ce n'est pas une obs d'un partenaire, c'est donc une obs PN
207
				// on récupère l'id utilisateur tela via son mail
217
				// on récupère l'id utilisateur tela via son mail
208
				$email = $obs['author']['email'];
218
				$email = $obs['author']['email'];
209
				$infos_utilisateur = $this->findUserInfo($email);
219
				$infos_utilisateur = $this->findUserInfo($email);
210
				if (!$infos_utilisateur) {
220
				if (!$infos_utilisateur) {
211
					continue; // c'est pas un telabotaniste
221
					continue; // c'est pas un telabotaniste
212
				}
222
				}
213
				echo "Synchro d'une obs d'un telabotaniste : $email\n";
223
				echo "Synchro d'une obs d'un telabotaniste : $email\n";
214
				// echo json_encode($obs);
224
				// echo json_encode($obs);
215
				// die(var_dump($obs));
225
				// die(var_dump($obs));
216
 
226
 
217
				// vérification que l'obs n'a pas déjà été ajoutée à la BdD de Tela
227
				// vérification que l'obs n'a pas déjà été ajoutée à la BdD de Tela
218
				$sql = "SELECT date_maj, id_observation FROM cel_plantnet WHERE id_plantnet = '{$obs['id']}'"
228
				$sql = "SELECT date_maj, id_observation FROM cel_plantnet WHERE id_plantnet = '{$obs['id']}'"
219
						. ' -- ' . __FILE__ . ':' . __LINE__;
229
						. ' -- ' . __FILE__ . ':' . __LINE__;
220
				$res = $this->bdd->recupererTous($sql);
230
				$res = $this->bdd->recupererTous($sql);
221
				// die(var_dump($res));
231
				// die(var_dump($res));
222
				if ($res) {
232
				if ($res) {
223
					// l'obs existe déjà, on vérifie si il faut màj puis on passe à la suite
233
					// l'obs existe déjà, on vérifie si il faut màj puis on passe à la suite
224
					// la date de l'obs est un microtime, donc on coupe les millièmes
234
					// la date de l'obs est un microtime, donc on coupe les millièmes
225
					// die(var_dump((int)($obs['dateUpdated']/1000), strtotime($res[0]['date_maj'])));
235
					// die(var_dump((int)($obs['dateUpdated']/1000), strtotime($res[0]['date_maj'])));
226
					if ((int)($obs['dateUpdated']/1000) > strtotime($res[0]['date_maj'])) {
236
					if ((int)($obs['dateUpdated']/1000) > strtotime($res[0]['date_maj'])) {
227
						echo "Obs déjà en base, mise à jour (TB {$res[0]['id_observation']})\n";
237
						echo "Obs déjà en base, mise à jour (TB {$res[0]['id_observation']})\n";
228
						$this->updateFromPN($obs, $res[0]['id_observation']);
238
						$this->updateFromPN($obs, $res[0]['id_observation']);
229
					} else {
239
					} else {
230
						echo "Obs déjà en base : ID PN {$obs['id']}, ID TB {$res[0]['id_observation']}\n";
240
						echo "Obs déjà en base : ID PN {$obs['id']}, ID TB {$res[0]['id_observation']}\n";
231
					}
241
					}
232
					continue;
242
					continue;
233
				}
243
				}
234
 
244
 
235
				if (isset($obs['deleted']) && (true === $obs['deleted'])) {
245
				if (isset($obs['deleted']) && (true === $obs['deleted'])) {
236
					continue; // obs supprimée chez PN sans être passée par nos serveurs
246
					continue; // obs supprimée chez PN sans être passée par nos serveurs
237
				}
247
				}
238
 
248
 
239
				$images = [];
249
				$images = [];
240
				$tags_images = [];
250
				$tags_images = [];
241
				foreach ($obs['images'] ?? [] as $i => $image) {
251
				foreach ($obs['images'] ?? [] as $i => $image) {
242
					if ($image['deleted']) {
252
					if ($image['deleted']) {
243
						continue;
253
						continue;
244
					}
254
					}
245
 
255
 
246
					// téléchargement de l'image PN
256
					// téléchargement de l'image PN
247
					$tempfile = tempnam("/tmp", "PullPN_") . ".jpg";
257
					$tempfile = tempnam("/tmp", "PullPN_") . ".jpg";
248
					$handle = fopen($tempfile, "w");
258
					$handle = fopen($tempfile, "w");
249
					fwrite($handle, file_get_contents($image['o']));
259
					fwrite($handle, file_get_contents($image['o']));
250
					fclose($handle);
260
					fclose($handle);
251
 
261
 
252
					echo "cool on a fait un fichier de " . filesize($tempfile) . " octets là : $tempfile\n";
262
					echo "cool on a fait un fichier de " . filesize($tempfile) . " octets là : $tempfile\n";
253
 
263
 
254
					$params = [
264
					$params = [
255
						'name' => 'image' . $i,
265
						'name' => 'image' . $i,
256
						'fichier' => new CURLFile($tempfile, 'image/jpg')
266
						'fichier' => new CURLFile($tempfile, 'image/jpg')
257
					];
267
					];
258
 
268
 
259
					// envoi de l'image PN à l'api de création
269
					// envoi de l'image PN à l'api de création
260
					$ch = curl_init(Config::get('urlCelUploadImageTemp'));
270
					$ch = curl_init(Config::get('urlCelUploadImageTemp'));
261
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
271
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
262
					curl_setopt($ch, CURLOPT_POST, true);
272
					curl_setopt($ch, CURLOPT_POST, true);
263
					curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
273
					curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
264
					$reponse = curl_exec($ch);
274
					$reponse = curl_exec($ch);
265
					// var_dump($reponse);
275
					// var_dump($reponse);
266
					$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
276
					$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
267
					curl_close($ch);
277
					curl_close($ch);
268
 
278
 
269
					unlink($tempfile);
279
					unlink($tempfile);
270
 
280
 
271
					$reponse = simplexml_load_string($reponse);
281
					$reponse = simplexml_load_string($reponse);
272
					/* Response format if success:
282
					/* Response format if success:
273
					<?xml version="1.0" encoding="UTF-8"?>
283
					<?xml version="1.0" encoding="UTF-8"?>
274
					<root>
284
					<root>
275
						<miniature-url>https://api-test.tela-botanica.org/tmp/cel/imgtmp/chaflipe_min.jpg</miniature-url>
285
						<miniature-url>https://api-test.tela-botanica.org/tmp/cel/imgtmp/chaflipe_min.jpg</miniature-url>
276
						<image-nom>chaflipe.jpg</image-nom>
286
						<image-nom>chaflipe.jpg</image-nom>
277
						<message></message>
287
						<message></message>
278
						<debogage></debogage>
288
						<debogage></debogage>
279
					</root>
289
					</root>
280
					*/
290
					*/
281
					// var_dump($reponse);
291
					// var_dump($reponse);
282
					if ($reponse && '' == $reponse->message /* && '' != $reponse->{'image-nom'} */) {
292
					if ($reponse && '' == $reponse->message /* && '' != $reponse->{'image-nom'} */) {
283
						$images[] = (string)$reponse->{'image-nom'};
293
						$images[] = (string)$reponse->{'image-nom'};
284
						$tags_images[] = $this->tagsImageTraduits[$image['organ']] ?? ''; // @TODO translate
294
						$tags_images[] = $this->tagsImageTraduits[$image['organ']] ?? ''; // @TODO translate
285
					}
295
					}
286
				}
296
				}
287
				// var_dump($images, $tags_images);
297
				// var_dump($images, $tags_images);
288
				// die();
298
				// die();
289
 
299
 
290
				// on insère l'obs via le service CelWidgetSaisie
300
				// on insère l'obs via le service CelWidgetSaisie
291
				$infos_obs = [
301
				$infos_obs = [
292
					// 'obsId1[commune_code_insee]' => '',
302
					// 'obsId1[commune_code_insee]' => '',
293
					'obsId1[commune_nom]' => $obs['geo']['place'] ?? '',
303
					'obsId1[commune_nom]' => $obs['geo']['place'] ?? '',
294
					'obsId1[date]' => date('d/m/Y', intdiv($obs['dateObs'], 1000)),
304
					'obsId1[date]' => date('d/m/Y', intdiv($obs['dateObs'], 1000)),
295
					// 'obsId1[famille]' => '',
305
					// 'obsId1[famille]' => '',
296
					'obsId1[latitude]' => (string)$obs['geo']['lat'] ?? '',
306
					'obsId1[latitude]' => (string)$obs['geo']['lat'] ?? '',
297
					// 'obsId1[lieudit]' => '',
307
					// 'obsId1[lieudit]' => '',
298
					'obsId1[longitude]' => (string)$obs['geo']['lon'] ?? '',
308
					'obsId1[longitude]' => (string)$obs['geo']['lon'] ?? '',
299
					// 'obsId1[milieu]' => '',
309
					// 'obsId1[milieu]' => '',
300
					// 'obsId1[nom_ret]' => '',
310
					// 'obsId1[nom_ret]' => '',
301
					'obsId1[nom_sel]' => $obs['currentName'],
311
					'obsId1[nom_sel]' => $obs['currentName'],
302
					'obsId1[certitude]' => 'douteux',
312
					'obsId1[certitude]' => 'douteux',
303
					// 'obsId1[notes]' => '',
313
					// 'obsId1[notes]' => '',
304
					// 'obsId1[num_nom_ret]' => '',
314
					// 'obsId1[num_nom_ret]' => '',
305
					// 'obsId1[num_nom_sel]' => '',
315
					// 'obsId1[num_nom_sel]' => '',
306
					// 'obsId1[num_taxon]' => '',
316
					// 'obsId1[num_taxon]' => '',
307
					'obsId1[referentiel]' => $this->findProbableTaxoRepos($this->currentProject['id']),
317
					'obsId1[referentiel]' => $this->findProbableTaxoRepos($this->currentProject['id']),
308
					// 'obsId1[station]' => '',
318
					// 'obsId1[station]' => '',
309
					'obsId1[obs_id]' => $obs['id'],
319
					'obsId1[obs_id]' => $obs['id'],
310
					'projet' => 'PlantNet',
320
					'projet' => 'PlantNet',
311
					'tag-img' => implode(', ', $tags_images ?? []),
321
					'tag-img' => implode(', ', $tags_images ?? []),
312
					'tag-obs' => 'plantnet, plantnet-mobile, pn:referentiel-' . $this->currentProject['id'],
322
					'tag-obs' => 'plantnet, plantnet-mobile, pn:referentiel-' . $this->currentProject['id'],
313
					'utilisateur[courriel]' => $email,
323
					'utilisateur[courriel]' => $email,
314
					'utilisateur[id_utilisateur]' => $infos_utilisateur['id'],
324
					'utilisateur[id_utilisateur]' => $infos_utilisateur['id'],
315
					'utilisateur[nom]' => $infos_utilisateur['nom'],
325
					'utilisateur[nom]' => $infos_utilisateur['nom'],
316
					'utilisateur[prenom]' => $infos_utilisateur['prenom'],
326
					'utilisateur[prenom]' => $infos_utilisateur['prenom'],
317
					'origin' => 'pullPlantnet',
327
					'origin' => 'pullPlantnet',
318
				];
328
				];
319
 
329
 
320
				foreach ($images as $i => $image) {
330
				foreach ($images as $i => $image) {
321
					$infos_obs["obsId1[image_nom][$i]"] = $image;
331
					$infos_obs["obsId1[image_nom][$i]"] = $image;
322
				}
332
				}
323
				// die(var_dump($infos_obs));
333
				// die(var_dump($infos_obs));
324
 
334
 
325
				// curl post $infos_obs
335
				// curl post $infos_obs
326
				$ch = curl_init($url_cel_widget_saisie);
336
				$ch = curl_init($url_cel_widget_saisie);
327
				curl_setopt($ch, CURLOPT_POST, true);
337
				curl_setopt($ch, CURLOPT_POST, true);
328
				curl_setopt($ch, CURLOPT_POSTFIELDS, $infos_obs);
338
				curl_setopt($ch, CURLOPT_POSTFIELDS, $infos_obs);
329
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
339
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
330
				$reponse = curl_exec($ch);
340
				$reponse = curl_exec($ch);
331
				$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
341
				$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
332
				curl_close($ch);
342
				curl_close($ch);
333
 
343
 
334
				if (!$reponse || 200 != $code) {
344
				if (!$reponse || 200 != $code) {
335
					throw new Exception("Ça a pété à l'envoi de l'obs :\n $reponse\n avec l'obs : " . json_encode($infos_obs) . "\n");
345
					throw new Exception("Ça a pété à l'envoi de l'obs :\n $reponse\n avec l'obs : " . json_encode($infos_obs) . "\n");
336
				}
346
				}
337
 
347
 
338
				// var_dump($reponse);
348
				// var_dump($reponse);
339
				$id_obs_tb = $this->bdd->proteger(json_decode($reponse, true)['id']);
349
				$id_obs_tb = $this->bdd->proteger(json_decode($reponse, true)['id']);
340
				$id_obs_pn = $this->bdd->proteger($obs['id']);
350
				$id_obs_pn = $this->bdd->proteger($obs['id']);
341
				// on insère les ids de correspondance obsPN obsTB dans la table cel_plantnet
351
				// on insère les ids de correspondance obsPN obsTB dans la table cel_plantnet
342
				$sql = 'INSERT INTO cel_plantnet (id_observation, id_plantnet, date_maj)'
352
				$sql = 'INSERT INTO cel_plantnet (id_observation, id_plantnet, date_maj)'
343
						.' VALUES (%s, %s, NOW())'
353
						.' VALUES (%s, %s, NOW())'
344
						. ' -- ' . __FILE__ . ':' . __LINE__;
354
						. ' -- ' . __FILE__ . ':' . __LINE__;
345
				$sql = sprintf($sql, $id_obs_tb, $id_obs_pn);
355
				$sql = sprintf($sql, $id_obs_tb, $id_obs_pn);
346
				$this->bdd->requeter($sql);
356
				$this->bdd->requeter($sql);
347
			}
357
			}
348
		}
358
		}
349
	}
359
	}
350
 
360
 
351
	/**
361
	/**
352
	 * Return TB taxo repos names for given PN project
362
	 * Return TB taxo repos names for given PN project
353
	 *
363
	 *
354
	 * @return string
364
	 * @return string
355
	 */
365
	 */
356
	private function findProbableTaxoRepos($pnProjectId) {
366
	private function findProbableTaxoRepos($pnProjectId) {
357
		$selectedRepos = [];
367
		$selectedRepos = [];
358
		// Référentiels tela botanica indexés par référentiels PN (version octobre 2019)
368
		// Référentiels tela botanica indexés par référentiels PN (version octobre 2019)
359
		// @TODO à revoir en fonction des nouvelles mises en prod de nouveaux référentiels
369
		// @TODO à revoir en fonction des nouvelles mises en prod de nouveaux référentiels
360
		$tbTaxoRepos = [
370
		$tbTaxoRepos = [
361
			'afn' => [/*'apd', */'isfan'],
371
			'afn' => [/*'apd', */'isfan'],
362
			'aft' => ['apd'],
372
			'aft' => ['apd'],
363
			'antilles' => ['bdtxa', 'taxref'],
373
			'antilles' => ['bdtxa', 'taxref'],
364
			'canada' => ['vascan'],
374
			'canada' => ['vascan'],
365
			'comores' => ['apd'],
375
			'comores' => ['apd'],
366
			'endemia' => ['florical', 'taxref'],
376
			'endemia' => ['florical', 'taxref'],
367
			'taxref	' => ['bdtfx'],
377
			'taxref	' => ['bdtfx'],
368
			'guyane' => ['aublet', 'taxref'],
378
			'guyane' => ['aublet', 'taxref'],
369
			'hawai' => [],
379
			'hawai' => [],
370
			'lapaz' => ['aublet', 'taxref'],
380
			'lapaz' => ['aublet', 'taxref'],
371
			'martinique' => ['bdtxa', 'taxref'],
381
			'martinique' => ['bdtxa', 'taxref'],
372
			'maurice' => ['apd'],
382
			'maurice' => ['apd'],
373
			'medor' => ['lbf'],
383
			'medor' => ['lbf'],
374
			'namerica' => [],
384
			'namerica' => [],
375
			'polynesiefr' => ['taxref'],
385
			'polynesiefr' => ['taxref'],
376
			'prosea' => ['asia'],
386
			'prosea' => ['asia'],
377
			'prota' => ['isfan', 'apd'],
387
			'prota' => ['isfan', 'apd'],
378
			'provence' => ['bdtfx', 'taxref'],
388
			'provence' => ['bdtfx', 'taxref'],
379
			'reunion' => ['bdtre', 'taxref'],
389
			'reunion' => ['bdtre', 'taxref'],
380
			'salad' => ['bdtfx', 'taxref'],
390
			'salad' => ['bdtfx', 'taxref'],
381
			'useful' => [],
391
			'useful' => [],
382
			'weurope' => ['bdtfx'],
392
			'weurope' => ['bdtfx'],
383
			'the-plant-list' => [],
393
			'the-plant-list' => [],
384
			'iscantree' => ['apd'],
394
			'iscantree' => ['apd'],
385
			'central-america' => [],
395
			'central-america' => [],
386
			'invasion' => ['bdtfx'],
396
			'invasion' => ['bdtfx'],
387
			'weeds' => ['bdtfx'],
397
			'weeds' => ['bdtfx'],
388
			'malaysia' => [],
398
			'malaysia' => [],
389
		];
399
		];
390
 
400
 
391
		if (array_key_exists($pnProjectId, $tbTaxoRepos)) {
401
		if (array_key_exists($pnProjectId, $tbTaxoRepos)) {
392
			array_map(function($repo) use ($selectedRepos) {
402
			array_map(function($repo) use ($selectedRepos) {
393
				$selectedRepos[] = $repo;
403
				$selectedRepos[] = $repo;
394
			}, $tbTaxoRepos[$pnProjectId]);
404
			}, $tbTaxoRepos[$pnProjectId]);
395
		}
405
		}
396
 
406
 
397
		// @TODO chercher le nom dans plusieurs référentiels avant d'envoyer l'obs
407
		// @TODO chercher le nom dans plusieurs référentiels avant d'envoyer l'obs
398
		// prendre "enrichirDonneesTaxonomiques" du service de saisie et le coller ici
408
		// prendre "enrichirDonneesTaxonomiques" du service de saisie et le coller ici
399
		// en attendant on envoi juste le premier référentiel trouvé
409
		// en attendant on envoi juste le premier référentiel trouvé
400
		return $selectedRepos[0] ?? '';
410
		return $selectedRepos[0] ?? '';
401
	}
411
	}
402
 
412
 
403
	/*
413
	/*
404
	 * Retrouve les infos d'un utilisateur tela à partir de son email
414
	 * Retrouve les infos d'un utilisateur tela à partir de son email
405
	 * @param string $email User email
415
	 * @param string $email User email
406
	 * @return mixed 		Tableau des infos de l'utilisateur
416
	 * @return mixed 		Tableau des infos de l'utilisateur
407
	 *						False si l'email n'est pas trouvé dans l'annuaire
417
	 *						False si l'email n'est pas trouvé dans l'annuaire
408
	 */
418
	 */
409
	private function findUserInfo($email) {
419
	private function findUserInfo($email) {
410
		// cherche dans le cache
420
		// cherche dans le cache
411
		if (array_key_exists($email, $this->userInfos)) {
421
		if (array_key_exists($email, $this->userInfos)) {
412
			$infosUtilisateur = $this->userInfos[$email];
422
			$infosUtilisateur = $this->userInfos[$email];
413
			// echo("Email in cache : $email\n");
423
			// echo("Email in cache : $email\n");
414
		} else {
424
		} else {
415
			$infosUtilisateur = false;
425
			$infosUtilisateur = false;
416
			$urlInfosUtilisateur = str_replace('{email}', $email, Config::get('urlAnnuaireIdParEmail'));
426
			$urlInfosUtilisateur = str_replace('{email}', $email, Config::get('urlAnnuaireIdParEmail'));
417
 
427
 
418
			$ch = curl_init($urlInfosUtilisateur);
428
			$ch = curl_init($urlInfosUtilisateur);
419
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
429
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
420
			$reponse = curl_exec($ch);
430
			$reponse = curl_exec($ch);
421
			$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
431
			$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
422
			curl_close($ch);
432
			curl_close($ch);
423
 
433
 
424
			// on peut pas tester le code de réponse de cette api, si l'utilisateur n'est pas trouvé ça fait une 500 >_<
434
			// on peut pas tester le code de réponse de cette api, si l'utilisateur n'est pas trouvé ça fait une 500 >_<
425
			// une bonne réponse ressemble à ça :
435
			// une bonne réponse ressemble à ça :
426
			// {"killian@tela-botanica.org":{"id":"30489","prenom":"Killian","nom":"Stefanini","pseudo":"Killian Stefanini","pseudoUtilise":true,"intitule":"Killian Stefanini","avatar":"\/\/www.gravatar.com\/avatar\/a9b9b8484076540924c03af816c77fc8?s=50&r=g&d=mm","groupes":{"19226":"adm","18943":"","23152":"","21684":"","21598":"adm","23184":"","23516":""},"permissions":["editor"],"nomWiki":"KillianStefanini"}}
436
			// {"killian@tela-botanica.org":{"id":"30489","prenom":"Killian","nom":"Stefanini","pseudo":"Killian Stefanini","pseudoUtilise":true,"intitule":"Killian Stefanini","avatar":"\/\/www.gravatar.com\/avatar\/a9b9b8484076540924c03af816c77fc8?s=50&r=g&d=mm","groupes":{"19226":"adm","18943":"","23152":"","21684":"","21598":"adm","23184":"","23516":""},"permissions":["editor"],"nomWiki":"KillianStefanini"}}
427
			$reponse = json_decode($reponse, true);
437
			$reponse = json_decode($reponse, true);
428
			if (!isset($reponse)) {
438
			if (!isset($reponse)) {
429
				throw new Exception("\nL'annuaire n'a pas répondu avec du json : code $code à l'adresse $urlInfosUtilisateur : $reponse\n");
439
				throw new Exception("\nL'annuaire n'a pas répondu avec du json : code $code à l'adresse $urlInfosUtilisateur : $reponse\n");
430
			}
440
			}
431
 
441
 
432
			if (!isset($reponse['error'])) {
442
			if (!isset($reponse['error'])) {
433
				$infosUtilisateur = array_shift($reponse);
443
				$infosUtilisateur = array_shift($reponse);
434
			}
444
			}
435
 
445
 
436
			// met en cache
446
			// met en cache
437
			$this->userInfos[$email] = $infosUtilisateur;
447
			$this->userInfos[$email] = $infosUtilisateur;
438
			// echo("Email cached : $email\n");
448
			// echo("Email cached : $email\n");
439
		}
449
		}
440
 
450
 
441
		return $infosUtilisateur;
451
		return $infosUtilisateur;
442
	}
452
	}
443
 
453
 
444
	private function updateFromPN(array $pnObs, string $tbObsId) {
454
	private function updateFromPN(array $pnObs, string $tbObsId) {
445
		if (!is_array($pnObs) || !is_string($tbObsId)) {
455
		if (!is_array($pnObs) || !is_string($tbObsId)) {
446
			// die(var_dump($pnObs, $tbObsId));
456
			// die(var_dump($pnObs, $tbObsId));
447
			throw new Exception("\nBad params types\n");
457
			throw new Exception("\nBad params types\n");
448
		}
458
		}
449
		// die(var_dump($pnObs));
459
		// die(var_dump($pnObs));
450
 
460
 
451
		// check for deleted
461
		// check for deleted
452
		if (isset($pnObs['deleted']) && (true === $pnObs['deleted'])) {
462
		if (isset($pnObs['deleted']) && (true === $pnObs['deleted'])) {
453
			// est-ce une obs issue de PN ?
463
			// est-ce une obs issue de PN ?
454
			//// faut regarder le champ input_source == PlantNet
464
			//// faut regarder le champ input_source == PlantNet
455
			$sql = "SELECT input_source FROM occurrence WHERE id = '$tbObsId'"
465
			$sql = "SELECT input_source FROM occurrence WHERE id = '$tbObsId'"
456
					. ' -- ' . __FILE__ . ':' . __LINE__;
466
					. ' -- ' . __FILE__ . ':' . __LINE__;
457
			$res = $this->bdd->recupererTous($sql);
467
			$res = $this->bdd->recupererTous($sql);
458
			die(var_dump($res));
468
			die(var_dump($res));
459
			if (isset($res[0]) && ('PlantNet' === $res[0]['input_source'])) {
469
			if (isset($res[0]) && ('PlantNet' === $res[0]['input_source'])) {
460
				// oui ? alors supprimer obs !
470
				// oui ? alors supprimer obs !
461
				echo("obs à supprimer\n");
471
				echo("obs à supprimer\n");
462
				$sql = "DELETE FROM occurrence WHERE id = '$tbObsId'"
472
				$sql = "DELETE FROM occurrence WHERE id = '$tbObsId'"
463
						. ' -- ' . __FILE__ . ':' . __LINE__;
473
						. ' -- ' . __FILE__ . ':' . __LINE__;
464
				$this->bdd->requeter($sql);
474
				$this->bdd->requeter($sql);
465
				$sql = "UPDATE photos SET occurrence_id = NULL WHERE occurrence_id = '$tbObsId'"
475
				$sql = "UPDATE photos SET occurrence_id = NULL WHERE occurrence_id = '$tbObsId'"
466
						. ' -- ' . __FILE__ . ':' . __LINE__;
476
						. ' -- ' . __FILE__ . ':' . __LINE__;
467
				$this->bdd->requeter($sql);
477
				$this->bdd->requeter($sql);
468
			}
478
			}
469
		}
479
		}
470
 
480
 
471
		// check for deleted images
481
		// check for deleted images
472
		foreach ($pnObs['images'] as $image) {
482
		foreach ($pnObs['images'] as $image) {
473
			if ($image['deleted']) {
483
			if ($image['deleted']) {
474
				// no idea
484
				// no idea
475
				// y'a pas encore de lien tangible entre les images PN et les notres
485
				// y'a pas encore de lien tangible entre les images PN et les notres
476
			}
486
			}
477
		}
487
		}
478
 
488
 
479
		// @TODO : finir la comparaison des proposition entre celles de Tela et celles PN
489
		// @TODO : finir la comparaison des proposition entre celles de Tela et celles PN
480
		// // check for votes (notes et taxon)
490
		// // check for votes (notes et taxon)
481
		// $names = [];
491
		// $names = [];
482
		// foreach ($pnObs['computed']['votes'] as $vote) {
492
		// foreach ($pnObs['computed']['votes'] as $vote) {
483
		// 	echo($vote['name']);
493
		// 	echo($vote['name']);
484
		// 	echo($vote['score']['pn']);
494
		// 	echo($vote['score']['pn']);
485
		// 	echo($vote['score']['total']);
495
		// 	echo($vote['score']['total']);
486
 
496
 
487
		// 	$names[$vote['score']['pn']] = $vote['name'];
497
		// 	$names[$vote['score']['pn']] = $vote['name'];
488
		// }
498
		// }
489
		// ksort($names, SORT_NUMERIC); // votes sorted by score asc
499
		// ksort($names, SORT_NUMERIC); // votes sorted by score asc
490
		// $pn_sorted_votes = array_reverse($names, true); // desc
500
		// $pn_sorted_votes = array_reverse($names, true); // desc
491
 
501
 
492
		// // get existing votes
502
		// // get existing votes
493
		// $sql = "SELECT id_commentaire, nom_sel, nom_sel_nn, nom_referentiel, nom_referentiel, utilisateur_courriel, proposition_initiale, proposition_retenue"
503
		// $sql = "SELECT id_commentaire, nom_sel, nom_sel_nn, nom_referentiel, nom_referentiel, utilisateur_courriel, proposition_initiale, proposition_retenue"
494
		// 		. "WHERE ce_observation = '$tbObsId' AND ce_commentaire_parent = 0"
504
		// 		. "WHERE ce_observation = '$tbObsId' AND ce_commentaire_parent = 0"
495
		// 		. ' -- ' . __FILE__ . ':' . __LINE__;
505
		// 		. ' -- ' . __FILE__ . ':' . __LINE__;
496
		// $existing_votes = $this->bdd->recupererTous($sql);
506
		// $existing_votes = $this->bdd->recupererTous($sql);
497
 
507
 
498
		// // @TODO : compare votes
508
		// // @TODO : compare votes
499
		// // insert_new_votes($pn_sorted_votes, $existing_votes);
509
		// // insert_new_votes($pn_sorted_votes, $existing_votes);
500
	}
510
	}
501
 
511
 
502
	private function updateOnePN($id) {
512
	private function updateOnePN($id) {
503
		// vérification que l'obs est bien dans la BdD de Tela
513
		// vérification que l'obs est bien dans la BdD de Tela
504
		$sql = "SELECT date_maj, id_observation FROM cel_plantnet WHERE id_plantnet = '$id'"
514
		$sql = "SELECT date_maj, id_observation FROM cel_plantnet WHERE id_plantnet = '$id'"
505
					. ' -- ' . __FILE__ . ':' . __LINE__;
515
					. ' -- ' . __FILE__ . ':' . __LINE__;
506
		$res = $this->bdd->recupererTous($sql);
516
		$res = $this->bdd->recupererTous($sql);
507
		// die(var_dump($res));
517
		// die(var_dump($res));
508
		if (!$res) {
518
		if (!$res) {
509
			throw new Exception("\nPlantnet occurrence id ($id) doesn't exist in tela db. \n");
519
			throw new Exception("\nPlantnet occurrence id ($id) doesn't exist in tela db. \n");
510
		}
520
		}
511
 
521
 
512
		// l'obs existe déjà à Tela, on vérifie si il faut màj
522
		// l'obs existe déjà à Tela, on vérifie si il faut màj
513
		$urlInfosObs = str_replace(
523
		$urlInfosObs = str_replace(
514
			['{token}', '{ids}'],
524
			['{token}', '{ids}'],
515
			[Config::get('tokenPlantnet'), $id],
525
			[Config::get('tokenPlantnet'), $id],
516
			Config::get('urlPlantnetBase').Config::get('urlPlantnetObsById')
526
			Config::get('urlPlantnetBase').Config::get('urlPlantnetObsById')
517
		);
527
		);
518
		$ch = curl_init($urlInfosObs);
528
		$ch = curl_init($urlInfosObs);
519
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
529
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
520
		$reponse = curl_exec($ch);
530
		$reponse = curl_exec($ch);
521
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
531
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
522
		curl_close($ch);
532
		curl_close($ch);
523
 
533
 
524
		if (!$reponse || 200 != $code) {
534
		if (!$reponse || 200 != $code) {
525
			throw new Exception("\nPlantnet api ($urlInfosObs) replied with code $code : $reponse\n");
535
			throw new Exception("\nPlantnet api ($urlInfosObs) replied with code $code : $reponse\n");
526
		}
536
		}
527
 
537
 
528
		echo "La suite n'a pas été implémentée.\n";
538
		echo "La suite n'a pas été implémentée.\n";
529
		die(var_dump($reponse));
539
		die(var_dump($reponse));
530
	}
540
	}
531
 
541
 
532
	private function updateOneTB($id) {
542
	private function updateOneTB($id) {
533
		$corres = $this->findMatchingPartnerId($id, 'tb');
543
		$corres = $this->findMatchingPartnerId($id, 'tb');
534
		echo "L'obs tela avec l'id $id a été trouvée chez plantnet avec l'id : " .$corres['pn'] . "\n";
544
		echo "L'obs tela avec l'id $id a été trouvée chez plantnet avec l'id : " .$corres['pn'] . "\n";
535
		echo "La suite n'a pas été implémentée.\n";
545
		echo "La suite n'a pas été implémentée.\n";
536
	}
546
	}
537
 
547
 
538
	/*
548
	/*
539
	 * Trouve les ids d'une obs chez les partenaires
549
	 * Trouve les ids d'une obs chez les partenaires
540
	 * Il faut lancer updateMatchingPartnersIds pour obtenir une liste fraiche
550
	 * Il faut lancer updateMatchingPartnersIds pour obtenir une liste fraiche
541
	 *
551
	 *
542
	 * @param 	string $id			L'id de l'obs
552
	 * @param 	string $id			L'id de l'obs
543
	 * @param 	string $partner		Le partenaire correspondant à l'id de l'obs
553
	 * @param 	string $partner		Le partenaire correspondant à l'id de l'obs
544
	 *
554
	 *
545
	 * @return  mixed 				Le tableau de correspondances d'ids
555
	 * @return  mixed 				Le tableau de correspondances d'ids
546
	 *								False si l'id n'est pas trouvé
556
	 *								False si l'id n'est pas trouvé
547
	 */
557
	 */
548
	private function findMatchingPartnerId($id, $partner) {
558
	private function findMatchingPartnerId($id, $partner) {
549
		if (!in_array($partner, $this->allowedPartners)) {
559
		if (!in_array($partner, $this->allowedPartners)) {
550
			throw new Exception("\nUnknown partner : $partner. Available Partners : " . implode(', ', $this->allowedPartners) . "\n");
560
			throw new Exception("\nUnknown partner : $partner. Available Partners : " . implode(', ', $this->allowedPartners) . "\n");
551
		}
561
		}
552
 
562
 
553
		// le json ressemble à ça :
563
		// le json ressemble à ça :
554
		// {"tb":"2369732","pn":"1001020199"}, {"tb":"2369733","pn":"1001020176"}, ...
564
		// {"tb":"2369732","pn":"1001020199"}, {"tb":"2369733","pn":"1001020176"}, ...
555
		$ids = json_decode(file_get_contents($this->correspondingIdsFilename), true);
565
		$ids = json_decode(file_get_contents($this->correspondingIdsFilename), true);
556
		// extrait la colonne du partenaire recherché du tableau multidimensionnel fraichement décodé
566
		// extrait la colonne du partenaire recherché du tableau multidimensionnel fraichement décodé
557
		$partnerColumn = array_column($ids, $partner);
567
		$partnerColumn = array_column($ids, $partner);
558
		// cherche l'index de l'id recherché
568
		// cherche l'index de l'id recherché
559
		$index = array_search($id, $partnerColumn);
569
		$index = array_search($id, $partnerColumn);
560
 
570
 
561
		return $index ? $ids[$index] : false;
571
		return $index ? $ids[$index] : false;
562
	}
572
	}
563
 
573
 
564
	private function updateCorrespondingIdsTable() {
574
	private function updateCorrespondingIdsTable() {
565
		// first update cache file if necessary
575
		// first update cache file if necessary
566
		if (!file_exists($this->correspondingIdsFilename) || time() > (filemtime($this->correspondingIdsFilename) + (24 * 3600))) {
576
		if (!file_exists($this->correspondingIdsFilename) || time() > (filemtime($this->correspondingIdsFilename) + (24 * 3600))) {
567
			$this->updateMatchingPartnersIds();
577
			$this->updateMatchingPartnersIds();
568
		}
578
		}
569
 
579
 
570
		$data = file_get_contents($this->correspondingIdsFilename);
580
		$data = file_get_contents($this->correspondingIdsFilename);
571
		$data = json_decode($data, true);
581
		$data = json_decode($data, true);
572
 
582
 
573
		$now = new DateTime;
583
		$now = new DateTime;
574
		$now = $this->bdd->proteger($now->format('Y-m-d H:i:s'));
584
		$now = $this->bdd->proteger($now->format('Y-m-d H:i:s'));
575
 
585
 
576
		$sqlInsert = 'INSERT INTO cel_plantnet (id_observation, id_plantnet, date_maj)'
586
		$sqlInsert = 'INSERT INTO cel_plantnet (id_observation, id_plantnet, date_maj)'
577
					. ' VALUES %s'
587
					. ' VALUES %s'
578
					. ' ON DUPLICATE KEY UPDATE id_observation=VALUES(id_observation), id_plantnet=VALUES(id_plantnet)'
588
					. ' ON DUPLICATE KEY UPDATE id_observation=VALUES(id_observation), id_plantnet=VALUES(id_plantnet)'
579
					. ' -- ' . __FILE__ . ':' . __LINE__;
589
					. ' -- ' . __FILE__ . ':' . __LINE__;
580
		$values = '';
590
		$values = '';
581
 
591
 
582
		foreach ($data as $id => $corres) {
592
		foreach ($data as $id => $corres) {
583
			$id_obs_tb = $this->bdd->proteger($corres['tb']);
593
			$id_obs_tb = $this->bdd->proteger($corres['tb']);
584
			$id_obs_pn = $this->bdd->proteger($corres['pn']);
594
			$id_obs_pn = $this->bdd->proteger($corres['pn']);
585
			// on insère les ids de correspondance obsPN obsTB dans la table cel_plantnet
595
			// on insère les ids de correspondance obsPN obsTB dans la table cel_plantnet
586
			$values .= " ($id_obs_tb, $id_obs_pn, $now),";
596
			$values .= " ($id_obs_tb, $id_obs_pn, $now),";
587
 
597
 
588
			if (0 === $id % 100) {
598
			if (0 === $id % 100) {
589
				$values = substr($values, 0, -1); // retire la dernière virgule
599
				$values = substr($values, 0, -1); // retire la dernière virgule
590
				$sql = sprintf($sqlInsert, $values);
600
				$sql = sprintf($sqlInsert, $values);
591
				// var_dump($sql);
601
				// var_dump($sql);
592
				$this->bdd->requeter($sql);
602
				$this->bdd->requeter($sql);
593
				$values = '';
603
				$values = '';
594
			}
604
			}
595
		}
605
		}
596
		// Faut envoyer les dernières données qui sont pas passées dans le modulo
606
		// Faut envoyer les dernières données qui sont pas passées dans le modulo
597
		$values = substr($values, 0, -1); // retire la dernière virgule
607
		$values = substr($values, 0, -1); // retire la dernière virgule
598
		$sql = sprintf($sqlInsert, $values);
608
		$sql = sprintf($sqlInsert, $values);
599
		// var_dump($sql);
609
		// var_dump($sql);
600
		$this->bdd->requeter($sql);
610
		$this->bdd->requeter($sql);
601
 
611
 
602
	}
612
	}
603
 
613
 
604
	private function updateMatchingPartnersIds() {
614
	private function updateMatchingPartnersIds() {
605
		// curl -X GET --header 'Accept: application/json' 'https://bourbonnais.cirad.fr:8081/v1/edi/observations/partnerids?token=f0ca433febe320675c24ee2ddfab8b82f65d556b' > partnerids.txt
615
		// curl -X GET --header 'Accept: application/json' 'https://bourbonnais.cirad.fr:8081/v1/edi/observations/partnerids?token=f0ca433febe320675c24ee2ddfab8b82f65d556b' > partnerids.txt
606
		$matchingPartnersIdsServiceUrl = str_replace(
616
		$matchingPartnersIdsServiceUrl = str_replace(
607
			'{token}',
617
			'{token}',
608
			Config::get('tokenPlantnet'),
618
			Config::get('tokenPlantnet'),
609
			Config::get('urlPlantnetBase').Config::get('urlPlantnetMatchingPartner')
619
			Config::get('urlPlantnetBase').Config::get('urlPlantnetMatchingPartner')
610
		);
620
		);
611
		$ch = curl_init($matchingPartnersIdsServiceUrl);
621
		$ch = curl_init($matchingPartnersIdsServiceUrl);
612
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
622
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
613
 
623
 
614
		echo "Updating matching partners ids...\n";
624
		echo "Updating matching partners ids...\n";
615
		$reponse = curl_exec($ch);
625
		$reponse = curl_exec($ch);
616
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
626
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
617
		curl_close($ch);
627
		curl_close($ch);
618
 
628
 
619
 
629
 
620
		if (!$reponse || 200 != $code) {
630
		if (!$reponse || 200 != $code) {
621
			throw new Exception("\nError updating partners ids, http error code \"$code\" whith url \"$matchingPartnersIdsServiceUrl\"...\n");
631
			throw new Exception("\nError updating partners ids, http error code \"$code\" whith url \"$matchingPartnersIdsServiceUrl\"...\n");
622
		}
632
		}
623
		echo "Response data from PN api gathered, know computing...\n";
633
		echo "Response data from PN api gathered, know computing...\n";
624
 
634
 
625
		if (!file_put_contents($this->correspondingIdsFilename, $reponse)) {
635
		if (!file_put_contents($this->correspondingIdsFilename, $reponse)) {
626
			throw new Exception("\nError writing correspondingIdsFilename with path : " . $this->correspondingIdsFilename . "\n");
636
			throw new Exception("\nError writing correspondingIdsFilename with path : " . $this->correspondingIdsFilename . "\n");
627
		}
637
		}
628
		echo "Matching partners ids saved!";
638
		echo "Matching partners ids saved!";
629
	}
639
	}
630
}
640
}