Subversion Repositories eFlore/Applications.cel

Rev

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

Rev 3779 Rev 3781
1
<?php
1
<?php
2
 
2
 
3
/*
3
/*
4
	PHP 7
4
	PHP 7
5
 
5
 
6
	Script used to synchronize PN occ with Flora Data
6
	Script used to synchronize PN occ with Flora Data
7
 
7
 
8
	Écrit en franglish pour une meilleure compréhension (lol)
8
	Écrit en franglish pour une meilleure compréhension (lol)
9
*/
9
*/
10
 
10
 
11
class PullPlantnet extends Script {
11
class PullPlantnet extends Script {
12
 
12
 
13
	protected $bdd;
13
	protected $bdd;
14
 
14
 
15
	protected $debug = false;
15
	protected $debug = false;
16
 
16
 
17
	protected $allowedPartners = ['tb', 'pn'];
17
	protected $allowedPartners = ['tb', 'pn'];
18
 
18
 
19
	// Nom du fichier contenant les correspondances d'ID TB/PN
19
	// Nom du fichier contenant les correspondances d'ID TB/PN
20
	protected $correspondingIdsFilename = '';
20
	protected $correspondingIdsFilename = '';
21
 
21
 
22
	// Cache d'informations utilisateurs provenant de l'annuaire TB
22
	// Cache d'informations utilisateurs provenant de l'annuaire TB
23
	protected $userInfos = [];
23
	protected $userInfos = [];
24
 
24
 
25
	// Cache des obs id PN traitées pendant cette run
25
	// Cache des obs id PN traitées pendant cette run
26
	protected $processedObsId = [];
26
	protected $processedObsId = [];
27
 
27
 
28
	// Paramètre de suivi et de pagination de l'API des obs PN
28
	// Paramètre de suivi et de pagination de l'API des obs PN
29
	protected $currentPage = '';
29
	protected $currentPage = '';
30
	protected $currentProject = '';
30
	protected $currentProject = '';
31
	protected $hasMore = false;
31
	protected $hasMore = false;
32
 
32
 
33
	// Traduction des organes de PN
33
	// Traduction des organes de PN
34
	protected $tagsImageTraduits = [
34
	protected $tagsImageTraduits = [
35
		'flower' => 'fleur',
35
		'flower' => 'fleur',
36
		'fruit' => 'fruit',
36
		'fruit' => 'fruit',
37
		'leaf' => 'feuille',
37
		'leaf' => 'feuille',
38
		'bark' => 'écorce',
38
		'bark' => 'écorce',
39
		'branch' => 'branche',
39
		'branch' => 'branche',
40
		'habit' => 'port',
40
		'habit' => 'port',
41
	];
41
	];
42
 
42
 
43
	// Différents types de lifecle possible pour filtrer les obs
43
	// Différents types de lifecle possible pour filtrer les obs
44
	// Modified renvoi les obs en fonction de leur date de modif
44
	// Modified renvoi les obs en fonction de leur date de modif
45
	// Created, en fonction de la date de création
45
	// Created, en fonction de la date de création
46
	// Deleted, well, you already got it
46
	// Deleted, well, you already got it
47
	protected $lifecycles = [
47
	protected $lifecycles = [
48
		'created',
48
		'created',
49
		'modified',
49
		'modified',
50
		'deleted', // deleted peut être très lent (pas d'index coté PN pour le moment)
50
		'deleted', // deleted peut être très lent (pas d'index coté PN pour le moment)
51
	];
51
	];
52
 
52
 
53
	/**
53
	/**
54
	 * Paramêtres par défaut disponibles pour la ligne de commande
54
	 * Paramêtres par défaut disponibles pour la ligne de commande
55
	 * le tableau se construit de la forme suivante :
55
	 * le tableau se construit de la forme suivante :
56
	 * - clé =  nom du paramêtre '-foo'
56
	 * - clé =  nom du paramêtre '-foo'
57
	 * - value = contient un nouveau tableau composé de cette façon :
57
	 * - value = contient un nouveau tableau composé de cette façon :
58
	 *  - booléen: true si le paramêtre est obligatoire
58
	 *  - booléen: true si le paramêtre est obligatoire
59
	 *  - booléen ou var : true si le paramêtre nécessite un valeur à sa suite ou la valeur par défaut
59
	 *  - booléen ou var : true si le paramêtre nécessite un valeur à sa suite ou la valeur par défaut
60
	 *  - string: description du contenu du paramêtre
60
	 *  - string: description du contenu du paramêtre
61
	 * Les paramêtres optionels devraient être déclaré à la fin du tableau.
61
	 * Les paramêtres optionels devraient être déclaré à la fin du tableau.
62
	 * Le dernier parametre du tableau peut avoir la valeur '...',
62
	 * Le dernier parametre du tableau peut avoir la valeur '...',
63
	 * il contiendra alors l'ensemble des paramêtres suivant trouvés sur la ligne de commande.
63
	 * il contiendra alors l'ensemble des paramêtres suivant trouvés sur la ligne de commande.
64
	 * @var array
64
	 * @var array
65
	 */
65
	 */
66
	protected $parametres_autorises = array(
66
	protected $parametres_autorises = array(
67
		'-startDate' => array(false, true, 'Date de début (parsée par strtotime). Ex: "YYYY:MM:DD HH:II:SS"'),
67
		'-startDate' => array(false, true, 'Date de début (parsée par strtotime). Ex: "YYYY:MM:DD HH:II:SS"'),
68
		'-lifecycle' => array(false, true, 'Par défaut : modified ; Au choix parmi : created/modified/deleted (deleted est lent)'),
68
		'-lifecycle' => array(false, true, 'Par défaut : modified ; Au choix parmi : created/modified/deleted (deleted est lent)'),
69
		'-pnObsId' => array(false, true, "ID de l'obs chez PlantNet"),
69
		'-pnObsId' => array(false, true, "ID de l'obs chez PlantNet"),
70
		'-project' => array(false, true, "projectId de l'obs chez PlantNet"),
70
		'-project' => array(false, true, "projectId de l'obs chez PlantNet"),
71
		'-tbObsId' => array(false, true, "ID de l'obs chez Tela"),
71
		'-tbObsId' => array(false, true, "ID de l'obs chez Tela"),
72
		'-debug' => array(false, false, "Mode débug (ajoute du log) Au choix parmi : debug/log (log est plus verbeux)"),
72
		'-debug' => array(false, false, "Mode débug (ajoute du log) Au choix parmi : debug/log (log est plus verbeux)"),
73
	);
73
	);
74
 
74
 
75
	public function __construct($script_nom, $parametres_cli) {
75
	public function __construct($script_nom, $parametres_cli) {
76
		parent::__construct($script_nom, $parametres_cli);
76
		parent::__construct($script_nom, $parametres_cli);
77
		$this->bdd = new Bdd();
77
		$this->bdd = new Bdd();
78
 
78
 
79
		$this->correspondingIdsFilename = Config::get('correspondingIdsFilename');
79
		$this->correspondingIdsFilename = Config::get('correspondingIdsFilename');
80
 
80
 
81
		$this->debug = $this->getParametre('debug');
81
		$this->debug = $this->getParametre('debug');
82
	}
82
	}
83
 
83
 
84
	public function executer() {
84
	public function executer() {
85
		$cmd = $this->getParametre('a');
85
		$cmd = $this->getParametre('a');
86
 
86
 
87
		switch ($cmd) {
87
		switch ($cmd) {
88
			case 'updateLatest':
88
			case 'updateLatest':
89
				$this->updateLatest($this->getParametre('startDate'), $this->getParametre('lifecycle'));
89
				$this->updateLatest($this->getParametre('startDate'), $this->getParametre('lifecycle'));
90
				break;
90
				break;
91
			case 'updateOnePN':
91
			case 'updateOnePN':
92
				$this->updateOnePN((int)$this->getParametre('pnObsId'), $this->getParametre('project'));
92
				$this->updateOnePN((int)$this->getParametre('pnObsId'), $this->getParametre('project'));
93
				break;
93
				break;
94
			case 'updateOneTB':
94
			case 'updateOneTB':
95
				$this->updateOneTB((int)$this->getParametre('tbObsId'));
95
				$this->updateOneTB((int)$this->getParametre('tbObsId'));
96
				break;
96
				break;
97
			case 'updateCorrespondingIdsTable':
97
			case 'updateCorrespondingIdsTable':
98
				$this->updateCorrespondingIdsTable();
98
				$this->updateCorrespondingIdsTable();
99
				break;
99
				break;
100
			default:
100
			default:
101
				$msg = "Erreur : la commande '$cmd' n'existe pas!\n"
101
				$msg = "Erreur : la commande '$cmd' n'existe pas!\n"
102
						. ', utilisez plutôt :' . "\n"
102
						. ', utilisez plutôt :' . "\n"
103
						. 'php cli.php PullPlantnet -a updateLatest -startDate "YYYY:MM:DD HH:II:SS" [[-lifecycle [modified]/created/deleted]]' . "\n"
103
						. 'php cli.php PullPlantnet -a updateLatest -startDate "YYYY:MM:DD HH:II:SS" [[-lifecycle [modified]/created/deleted]]' . "\n"
104
						. 'php cli.php PullPlantnet -a updateOnePN -pnObsId "1234567890" -project "xxxxxx"' . "\n"
104
						. 'php cli.php PullPlantnet -a updateOnePN -pnObsId "1234567890" -project "xxxxxx"' . "\n"
105
						. 'php cli.php PullPlantnet -a updateOneTB -tbObsId "1234567890"' . "\n"
105
						. 'php cli.php PullPlantnet -a updateOneTB -tbObsId "1234567890"' . "\n"
106
						. 'php cli.php PullPlantnet -a updateCorrespondingIdsTable' . "\n"
106
						. 'php cli.php PullPlantnet -a updateCorrespondingIdsTable' . "\n"
107
						;
107
						;
108
				throw new Exception($msg);
108
				throw new Exception($msg);
109
		}
109
		}
110
	}
110
	}
111
 
111
 
112
	/**
112
	/**
113
	 * Considering all modified pn obs since startDate
113
	 * Considering all modified pn obs since startDate
114
	 * One pn project after an other
114
	 * One pn project after an other
115
	 * Inserting obs in tb db (if new and matching user email)
115
	 * Inserting obs in tb db (if new and matching user email)
116
	 */
116
	 */
117
	private function updateLatest(string $startDate = '1917:03:15 00:00:00', string $lifecycle = 'modified') {
117
	private function updateLatest(string $startDate = '1917:03:15 00:00:00', string $lifecycle = 'modified') {
118
		$startDate = strtotime($startDate) * 1000; // we need a microtimestamp
118
		$startDate = strtotime($startDate) * 1000; // we need a microtimestamp
119
 
119
 
120
		$pnProjects = $this->getProjects(); // refresh projects list
120
		$pnProjects = $this->getProjects(); // refresh projects list
121
		foreach ($pnProjects as $project) {
121
		foreach ($pnProjects as $project) {
122
			do {
122
			do {
123
				$observations_PN = $this->getProjectLatest($project, $startDate, $lifecycle);
123
				$observations_PN = $this->getProjectLatest($project, $startDate, $lifecycle);
124
				$this->updateObs($observations_PN);
124
				$this->updateObs($observations_PN);
125
			} while ($this->hasMore);
125
			} while ($this->hasMore);
126
		}
126
		}
127
	}
127
	}
128
 
128
 
129
	private function getProjectLatest(array $project, int $startDate, string $lifecycle): array {
129
	private function getProjectLatest(array $project, int $startDate, string $lifecycle): array {
130
		$this->currentProject = $project;
130
		$this->currentProject = $project;
131
		$this->refreshBddConnexion();
131
		$this->refreshBddConnexion();
132
 
132
 
133
		if (!$this->currentPage) {
133
		if (!$this->currentPage) {
134
			echo 'Projet ' . $project['name'] . "\n";
134
			echo 'Projet ' . $project['name'] . "\n";
135
 
135
 
136
			// hop, on appelle le service de PN
136
			// hop, on appelle le service de PN
137
			$url_service = str_replace(
137
			$url_service = str_replace(
138
				['{project}', '{token}', '{startDate}', '{lifecycle}'],
138
				['{project}', '{token}', '{startDate}', '{lifecycle}'],
139
				[$project['id'], Config::get('tokenPlantnet'), $startDate, $lifecycle],
139
				[$project['id'], Config::get('tokenPlantnet'), $startDate, $lifecycle],
140
				Config::get('urlPlantnetBase').Config::get('urlPlantnetLatestChanges')
140
				Config::get('urlPlantnetBase').Config::get('urlPlantnetLatestChanges')
141
			);
141
			);
142
 
142
 
143
			$this->debug("URL service derniers changements : $url_service");
143
			$this->debug("URL service derniers changements : $url_service");
144
 
144
 
145
			$this->currentPage = $url_service;
145
			$this->currentPage = $url_service;
146
		}
146
		}
147
 
147
 
148
		$ch = curl_init($this->currentPage);
148
		$ch = curl_init($this->currentPage);
149
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
149
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
150
		$reponse = curl_exec($ch);
150
		$reponse = curl_exec($ch);
151
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
151
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
152
		curl_close($ch);
152
		curl_close($ch);
153
 
153
 
154
		// cool, maintenant on va trier ce qu'on a reçu
154
		// cool, maintenant on va trier ce qu'on a reçu
155
		if (!$reponse) {
155
		if (!$reponse) {
156
			throw new Exception("\nPN ne répond rien à l'adresse {$this->currentPage}\n");
156
			throw new Exception("\nPN ne répond rien à l'adresse {$this->currentPage}\n");
157
		} elseif (200 != $code) {
157
		} elseif (200 != $code) {
158
			// l'api répond avec une 404 quand y'a une date dans le futur ou simplement pas de nouvelle obs...
158
			// l'api répond avec une 404 quand y'a une date dans le futur ou simplement pas de nouvelle obs...
159
			if (404 == $code && strpos($reponse, 'No more results')) {
159
			if (404 == $code && strpos($reponse, 'No more results')) {
160
				$this->log("Pas d'autres résultats");
160
				$this->log("Pas d'autres résultats");
161
				$this->hasMore = false;
161
				$this->hasMore = false;
162
				$this->currentPage = '';
162
				$this->currentPage = '';
163
				return [];
163
				return [];
164
			}
164
			}
165
			throw new Exception("\nPN répond avec une $code à l'adresse {$this->currentPage} : $reponse\n");
165
			throw new Exception("\nPN répond avec une $code à l'adresse {$this->currentPage} : $reponse\n");
166
		}
166
		}
167
		$responseJson = json_decode($reponse, true);
167
		$responseJson = json_decode($reponse, true);
168
		$observations_PN = $responseJson['data'] ?? [];
168
		$observations_PN = $responseJson['data'] ?? [];
169
 
169
 
170
		$this->hasMore = $responseJson['hasMore'];
170
		$this->hasMore = $responseJson['hasMore'];
171
		if ($this->hasMore) {
171
		if ($this->hasMore) {
172
			$this->currentPage = Config::get('urlPlantnetBase').$responseJson['next'];
172
			$this->currentPage = Config::get('urlPlantnetBase').$responseJson['next'];
173
			$this->debug("URL service derniers changements, page suivante : {$this->currentPage}");
173
			$this->debug("URL service derniers changements, page suivante : {$this->currentPage}");
174
		} else {
174
		} else {
175
			$this->currentPage = '';
175
			$this->currentPage = '';
176
		}
176
		}
177
 
177
 
178
		return $observations_PN;
178
		return $observations_PN;
179
	}
179
	}
180
 
180
 
181
	private function getProjects(): array {
181
	private function getProjects(): array {
182
		// get PN projects list
182
		// get PN projects list
183
		$url = str_replace('{token}', Config::get('tokenPlantnet'), Config::get('urlPlantnetBase').Config::get('urlPlantnetProjects'));
183
		$url = str_replace('{token}', Config::get('tokenPlantnet'), Config::get('urlPlantnetBase').Config::get('urlPlantnetProjects'));
184
 
184
 
185
		$this->debug("URL service liste projets : $url");
185
		$this->debug("URL service liste projets : $url");
186
 
186
 
187
		$ch = curl_init($url);
187
		$ch = curl_init($url);
188
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
188
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
189
		$reponse = curl_exec($ch);
189
		$reponse = curl_exec($ch);
190
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
190
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
191
		curl_close($ch);
191
		curl_close($ch);
192
 
192
 
193
		if (!$reponse || 200 != $code) {
193
		if (!$reponse || 200 != $code) {
194
			throw new Exception("\nPN répond avec une $code à l'adresse $url : $reponse\n");
194
			throw new Exception("\nPN répond avec une $code à l'adresse $url : $reponse\n");
195
		}
195
		}
196
		$pnProjects = json_decode($reponse, true);
196
		$pnProjects = json_decode($reponse, true);
197
 
197
 
198
		echo 'Liste de projets récupérée : ' . count($pnProjects) . " projets dans la liste\n";
198
		echo 'Liste de projets récupérée : ' . count($pnProjects) . " projets dans la liste\n";
199
 
199
 
200
		$this->debug("Liste projets : " . json_encode($pnProjects));
200
		$this->debug("Liste projets : " . json_encode($pnProjects));
201
 
201
 
202
		return $pnProjects;
202
		return $pnProjects;
203
	}
203
	}
204
 
204
 
205
	/**
205
	/**
206
	 * For a given bunch of plantnet obs, post new one threw saisie widget service
206
	 * For a given bunch of plantnet obs, post new one threw saisie widget service
207
	 */
207
	 */
208
	private function updateObs(array $observations_PN) {
208
	private function updateObs(array $observations_PN) {
209
 
209
 
210
		$url_cel_widget_saisie = Config::get('urlCelWidgetSaisie');
210
		$url_cel_widget_saisie = Config::get('urlCelWidgetSaisie');
211
 
211
 
212
		foreach ($observations_PN as $obs) {
212
		foreach ($observations_PN as $obs) {
213
			// est-ce qu'on a déjà traité cette obs ? (oui une même obs peut être dans plusieurs projects)
213
			// est-ce qu'on a déjà traité cette obs ? (oui une même obs peut être dans plusieurs projects)
214
			if (in_array($obs['id'], $this->processedObsId)) {
214
			if (in_array($obs['id'], $this->processedObsId)) {
215
				$this->log("Obs {$obs['id']} déjà traitée pendant cette run");
215
				$this->log("Obs {$obs['id']} déjà traitée pendant cette run");
216
				continue;
216
				continue;
217
			} else {
217
			} else {
218
				$this->processedObsId[] = $obs['id'];
218
				$this->processedObsId[] = $obs['id'];
219
				$this->log("Obs {$obs['id']} ajoutée à la liste de cette run");
219
				$this->log("Obs {$obs['id']} ajoutée à la liste de cette run");
220
			}
220
			}
221
 
221
 
222
			// 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
222
			// 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
223
			if (!isset($obs['currentName'])) {
223
			if (!isset($obs['currentName'])) {
224
				$this->log("Obs {$obs['id']} sans nom de taxon, on zap");
224
				$this->log("Obs {$obs['id']} sans nom de taxon, on zap");
225
				continue; // pas de nom de taxon, obs inutile
225
				continue; // pas de nom de taxon, obs inutile
226
			}
226
			}
227
			if (!isset($obs['geo'])) {
227
			if (!isset($obs['geo'])) {
228
				$this->log("Obs {$obs['id']} sans geom, on zap");
228
				$this->log("Obs {$obs['id']} sans geom, on zap");
229
				continue; // pas de position, obs inutile
229
				continue; // pas de position, obs inutile
230
			}
230
			}
231
			if (!isset($obs['dateObs'])) {
231
			if (!isset($obs['dateObs'])) {
232
				$this->log("Obs {$obs['id']} sans date, on zap");
232
				$this->log("Obs {$obs['id']} sans date, on zap");
233
				continue; // pas de date, obs inutile
233
				continue; // pas de date, obs inutile
234
			}
234
			}
235
 
235
 
236
			if (isset($obs['partner']['id']) && 'tela' === $obs['partner']['id']) {
236
			if (isset($obs['partner']['id']) && 'tela' === $obs['partner']['id']) {
237
				// c'est une obs tela
237
				// c'est une obs tela
238
				// si c'est mis à jour récemment coté PN et qu'on l'a pas supprimée chez nous entre temps
238
				// si c'est mis à jour récemment coté PN et qu'on l'a pas supprimée chez nous entre temps
239
					// on update les votes PN
239
					// on update les votes PN
240
					// on update l'identification proposée par PN
240
					// on update l'identification proposée par PN
241
 
241
 
242
				// @TODO
242
				// @TODO
243
				$this->log("Obs {$obs['id']} venant de Tela, mise à jour pas implémentée, on zap");
243
				$this->log("Obs {$obs['id']} venant de Tela, mise à jour pas implémentée, on zap");
244
				continue;
244
				continue;
245
			} elseif (!isset($obs['partner']['id'])) {
245
			} elseif (!isset($obs['partner']['id'])) {
246
				// ce n'est pas une obs d'un partenaire, c'est donc une obs PN
246
				// ce n'est pas une obs d'un partenaire, c'est donc une obs PN
247
				// on récupère l'id utilisateur tela via son mail
247
				// on récupère l'id utilisateur tela via son mail
248
				$email = $obs['author']['email'];
248
				$email = $obs['author']['email'];
249
				$infos_utilisateur = $this->findUserInfo($email);
249
				$infos_utilisateur = $this->findUserInfo($email);
250
				if (!$infos_utilisateur) {
250
				if (!$infos_utilisateur) {
251
					$this->log("Obs {$obs['id']} email $email ne provient pas d'un telabotaniste");
251
					$this->log("Obs {$obs['id']} email $email ne provient pas d'un telabotaniste");
252
					continue; // c'est pas un telabotaniste
252
					continue; // c'est pas un telabotaniste
253
				}
253
				}
254
				$this->log("Obs {$obs['id']} email $email provient d'un telabotaniste");
254
				$this->log("Obs {$obs['id']} email $email provient d'un telabotaniste");
255
				$this->log(json_encode($obs));
255
				$this->log(json_encode($obs));
256
				// die(var_dump($obs));
256
				// die(var_dump($obs));
257
 
257
 
258
				// vérification que l'obs n'a pas déjà été ajoutée à la BdD de Tela
258
				// vérification que l'obs n'a pas déjà été ajoutée à la BdD de Tela
259
				$sql = "SELECT date_maj, id_observation FROM cel_plantnet WHERE id_plantnet = '{$obs['id']}'"
259
				$sql = "SELECT date_maj, id_observation FROM cel_plantnet WHERE id_plantnet = '{$obs['id']}'"
260
						. ' -- ' . __FILE__ . ':' . __LINE__;
260
						. ' -- ' . __FILE__ . ':' . __LINE__;
261
				$res = $this->bdd->recupererTous($sql);
261
				$res = $this->bdd->recupererTous($sql);
262
				// die(var_dump($res));
262
				// die(var_dump($res));
263
				if ($res) {
263
				if ($res) {
264
					// l'obs existe déjà, on vérifie si il faut màj puis on passe à la suite
264
					// l'obs existe déjà, on vérifie si il faut màj puis on passe à la suite
265
					// la date de l'obs est un microtime, donc on coupe les millièmes
265
					// la date de l'obs est un microtime, donc on coupe les millièmes
266
					// die(var_dump((int)($obs['dateUpdated']/1000), strtotime($res[0]['date_maj'])));
266
					// die(var_dump((int)($obs['dateUpdated']/1000), strtotime($res[0]['date_maj'])));
267
					if ((int)($obs['dateUpdated']/1000) > strtotime($res[0]['date_maj'])) {
267
					if ((int)($obs['dateUpdated']/1000) > strtotime($res[0]['date_maj'])) {
268
						echo "Obs déjà en base, mise à jour : ID PN {$obs['id']} ; ID TB {$res[0]['id_observation']} ; utilisateur_tb $email\n";
268
						echo "Obs déjà en base, mise à jour : ID PN {$obs['id']} ; ID TB {$res[0]['id_observation']} ; utilisateur_tb $email\n";
269
						$this->updateFromPN($obs, $res[0]['id_observation']);
269
						$this->updateFromPN($obs, $res[0]['id_observation']);
270
					} else {
270
					} else {
271
						echo "Obs déjà en base, déjà à jour : ID PN {$obs['id']} ; ID TB {$res[0]['id_observation']} ; utilisateur_tb $email\n";
271
						echo "Obs déjà en base, déjà à jour : ID PN {$obs['id']} ; ID TB {$res[0]['id_observation']} ; utilisateur_tb $email\n";
272
					}
272
					}
273
					continue;
273
					continue;
274
				}
274
				}
275
 
275
 
276
				if (isset($obs['deleted']) && (true === $obs['deleted'])) {
276
				if (isset($obs['deleted']) && (true === $obs['deleted'])) {
277
					$this->log("Obs {$obs['id']} supprimée coté PlantNet");
277
					$this->log("Obs {$obs['id']} supprimée coté PlantNet");
278
					continue; // obs supprimée chez PN sans être passée par nos serveurs
278
					continue; // obs supprimée chez PN sans être passée par nos serveurs
279
				}
279
				}
280
 
280
 
281
				$images = [];
281
				$images = [];
282
				$tags_images = [];
282
				$tags_images = [];
283
				$images_size = 0;
283
				$images_size = 0;
284
				foreach ($obs['images'] ?? [] as $i => $image) {
284
				foreach ($obs['images'] ?? [] as $i => $image) {
285
					if ($image['deleted']) {
285
					if ($image['deleted']) {
286
						$this->log("Obs {$obs['id']} image {$image['id']} supprimée coté PlantNet");
286
						$this->log("Obs {$obs['id']} image {$image['id']} supprimée coté PlantNet");
287
						continue;
287
						continue;
288
					}
288
					}
289
 
289
 
290
					// téléchargement de l'image PN
290
					// téléchargement de l'image PN
291
					$img = false;
291
					$img = false;
292
					$retry = 3;
292
					$retry = 3;
293
					do {
293
					do {
294
						$img = file_get_contents($image['o']);
294
						$img = file_get_contents($image['o']);
-
 
295
						if (!$img) {
295
						$retry--;
296
							$retry--;
296
						$this->log("Obs {$obs['id']} lecture image {$image['id']} tentatives restantes : $retry");
297
							$this->log("Obs {$obs['id']} lecture image {$image['id']} tentatives restantes : $retry");
-
 
298
						}
297
					} while (!$img && $retry);
299
					} while (!$img && $retry);
298
 
300
 
299
					if (!$img) {
301
					if (!$img) {
300
						echo "Abandon, image impossible à télécharger : {$image['o']}\n";
302
						echo "Abandon, image impossible à télécharger : {$image['o']}\n";
301
						continue;
303
						continue;
302
					}
304
					}
303
 
305
 
304
					// Écriture dans un fichier temporaire
306
					// Écriture dans un fichier temporaire
305
					$tempfile = tempnam("/tmp", "PullPN_") . ".jpg";
307
					$tempfile = tempnam("/tmp", "PullPN_") . ".jpg";
306
					$handle = fopen($tempfile, "w");
308
					$handle = fopen($tempfile, "w");
307
					fwrite($handle, $img);
309
					fwrite($handle, $img);
308
					fclose($handle);
310
					fclose($handle);
309
					$images_size += filesize($tempfile);
311
					$images_size += filesize($tempfile);
310
 
312
 
311
					$this->log("Obs {$obs['id']} image {$image['id']} créée " . number_format(filesize($tempfile), 0, ',', ' ') . " octets : $tempfile");
313
					$this->log("Obs {$obs['id']} image {$image['id']} créée " . number_format(filesize($tempfile), 0, ',', ' ') . " octets : $tempfile");
312
 
314
 
313
					$params = [
315
					$params = [
314
						'name' => 'image' . $i,
316
						'name' => 'image' . $i,
315
						'fichier' => new CURLFile($tempfile, 'image/jpg')
317
						'fichier' => new CURLFile($tempfile, 'image/jpg')
316
					];
318
					];
317
 
319
 
318
					// envoi de l'image PN à l'api de création
320
					// envoi de l'image PN à l'api de création
319
					$ch = curl_init(Config::get('urlCelUploadImageTemp'));
321
					$ch = curl_init(Config::get('urlCelUploadImageTemp'));
320
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
322
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
321
					curl_setopt($ch, CURLOPT_POST, true);
323
					curl_setopt($ch, CURLOPT_POST, true);
322
					curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
324
					curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
323
					$reponse = curl_exec($ch);
325
					$reponse = curl_exec($ch);
324
					$this->log("Obs {$obs['id']} image {$image['id']} envoyée à l'api de création. Réponse : $reponse");
326
					$this->log("Obs {$obs['id']} image {$image['id']} envoyée à l'api de création. Réponse : $reponse");
325
					$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
327
					$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
326
					curl_close($ch);
328
					curl_close($ch);
327
 
329
 
328
					unlink($tempfile);
330
					unlink($tempfile);
329
 
331
 
330
					$reponse = simplexml_load_string($reponse);
332
					$reponse = simplexml_load_string($reponse);
331
					/* Response format if success:
333
					/* Response format if success:
332
					<?xml version="1.0" encoding="UTF-8"?>
334
					<?xml version="1.0" encoding="UTF-8"?>
333
					<root>
335
					<root>
334
						<miniature-url>https://api-test.tela-botanica.org/tmp/cel/imgtmp/chaflipe_min.jpg</miniature-url>
336
						<miniature-url>https://api-test.tela-botanica.org/tmp/cel/imgtmp/chaflipe_min.jpg</miniature-url>
335
						<image-nom>chaflipe.jpg</image-nom>
337
						<image-nom>chaflipe.jpg</image-nom>
336
						<message></message>
338
						<message></message>
337
						<debogage></debogage>
339
						<debogage></debogage>
338
					</root>
340
					</root>
339
					*/
341
					*/
340
					// var_dump($reponse);
342
					// var_dump($reponse);
341
					if ($reponse && '' == $reponse->message /* && '' != $reponse->{'image-nom'} */) {
343
					if ($reponse && '' == $reponse->message /* && '' != $reponse->{'image-nom'} */) {
342
						$images[] = (string)$reponse->{'image-nom'};
344
						$images[] = (string)$reponse->{'image-nom'};
343
 
345
 
344
						$tag = $this->tagsImageTraduits[$image['organ']] ?? $image['organ'];
346
						$tag = $this->tagsImageTraduits[$image['organ']] ?? $image['organ'];
345
						if (trim($tag)) {
347
						if (trim($tag)) {
346
							$tags_images[] = $tag;
348
							$tags_images[] = $tag;
347
						}
349
						}
348
					}
350
					}
349
				}
351
				}
350
				// var_dump($images, $tags_images);
352
				// var_dump($images, $tags_images);
351
				// die();
353
				// die();
352
 
354
 
353
				$geo = $this->getGeoInfo($obs['geo']);
355
				$geo = $this->getGeoInfo($obs['geo']);
354
				$this->log("Obs {$obs['id']} décodage du geom : " . json_encode($obs['geo']));
356
				$this->log("Obs {$obs['id']} décodage du geom : " . json_encode($obs['geo']));
355
				$this->log("Obs {$obs['id']} geom décodé : " . json_encode($geo));
357
				$this->log("Obs {$obs['id']} geom décodé : " . json_encode($geo));
356
 
358
 
357
				// on insère l'obs via le service CelWidgetSaisie
359
				// on insère l'obs via le service CelWidgetSaisie
358
				$infos_obs = [
360
				$infos_obs = [
359
					'obsId1[date]' => date('d/m/Y', intdiv($obs['dateObs'], 1000)),
361
					'obsId1[date]' => date('d/m/Y', intdiv($obs['dateObs'], 1000)),
360
					'obsId1[latitude]' => $geo['lat'] ?? null,
362
					'obsId1[latitude]' => $geo['lat'] ?? null,
361
					'obsId1[longitude]' => $geo['lon'] ?? null,
363
					'obsId1[longitude]' => $geo['lon'] ?? null,
362
					'obsId1[pays]' => $geo['countryCode'] ?? null,
364
					'obsId1[pays]' => $geo['countryCode'] ?? null,
363
					'obsId1[code_postal]' => $geo['postcode'] ?? null,
365
					'obsId1[code_postal]' => $geo['postcode'] ?? null,
364
					'obsId1[commune_nom]' => $geo['city'] ?? null,
366
					'obsId1[commune_nom]' => $geo['city'] ?? null,
365
					// 'obsId1[commune_code_insee]' => '',
367
					// 'obsId1[commune_code_insee]' => '',
366
					// 'obsId1[lieudit]' => '',
368
					// 'obsId1[lieudit]' => '',
367
					// 'obsId1[milieu]' => '',
369
					// 'obsId1[milieu]' => '',
368
					'obsId1[nom_sel]' => $obs['currentName'],
370
					'obsId1[nom_sel]' => $obs['currentName'],
369
					// 'obsId1[nom_ret]' => '',
371
					// 'obsId1[nom_ret]' => '',
370
					// 'obsId1[famille]' => '',
372
					// 'obsId1[famille]' => '',
371
					'obsId1[certitude]' => 'douteux',
373
					'obsId1[certitude]' => 'douteux',
372
					// 'obsId1[notes]' => '',
374
					// 'obsId1[notes]' => '',
373
					// 'obsId1[num_nom_ret]' => '',
375
					// 'obsId1[num_nom_ret]' => '',
374
					// 'obsId1[num_nom_sel]' => '',
376
					// 'obsId1[num_nom_sel]' => '',
375
					// 'obsId1[num_taxon]' => '',
377
					// 'obsId1[num_taxon]' => '',
376
					'obsId1[referentiel]' => $this->findProbableTaxoRepos($this->currentProject['id']), // @TODO faire une fois et mettre en cache
378
					'obsId1[referentiel]' => $this->findProbableTaxoRepos($this->currentProject['id']), // @TODO faire une fois et mettre en cache
377
					// 'obsId1[station]' => '',
379
					// 'obsId1[station]' => '',
378
					'obsId1[obs_id]' => $obs['id'],
380
					'obsId1[obs_id]' => $obs['id'],
379
					'projet' => 'PlantNet',
381
					'projet' => 'PlantNet',
380
					'tag-img' => implode(', ', $tags_images ?? []),
382
					'tag-img' => implode(', ', $tags_images ?? []),
381
					'tag-obs' => 'plantnet, plantnet-mobile, pn:referentiel-' . $this->currentProject['id'],
383
					'tag-obs' => 'plantnet, plantnet-mobile, pn:referentiel-' . $this->currentProject['id'],
382
					'utilisateur[courriel]' => $email,
384
					'utilisateur[courriel]' => $email,
383
					'utilisateur[id_utilisateur]' => $infos_utilisateur['id'],
385
					'utilisateur[id_utilisateur]' => $infos_utilisateur['id'],
384
					'utilisateur[nom]' => $infos_utilisateur['nom'],
386
					'utilisateur[nom]' => $infos_utilisateur['nom'],
385
					'utilisateur[prenom]' => $infos_utilisateur['prenom'],
387
					'utilisateur[prenom]' => $infos_utilisateur['prenom'],
386
					'origin' => 'pullPlantnet',
388
					'origin' => 'pullPlantnet',
387
				];
389
				];
388
 
390
 
389
				foreach ($images as $i => $image) {
391
				foreach ($images as $i => $image) {
390
					$infos_obs["obsId1[image_nom][$i]"] = $image;
392
					$infos_obs["obsId1[image_nom][$i]"] = $image;
391
				}
393
				}
392
 
394
 
393
				$this->log("Obs {$obs['id']} prête à être insérée : " . json_encode($infos_obs));
395
				$this->log("Obs {$obs['id']} prête à être insérée : " . json_encode($infos_obs));
394
 
396
 
395
				// curl post $infos_obs
397
				// curl post $infos_obs
396
				$ch = curl_init($url_cel_widget_saisie);
398
				$ch = curl_init($url_cel_widget_saisie);
397
				curl_setopt($ch, CURLOPT_POST, true);
399
				curl_setopt($ch, CURLOPT_POST, true);
398
				curl_setopt($ch, CURLOPT_POSTFIELDS, $infos_obs);
400
				curl_setopt($ch, CURLOPT_POSTFIELDS, $infos_obs);
399
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
401
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
400
				$reponse = curl_exec($ch);
402
				$reponse = curl_exec($ch);
401
				$this->log("Obs {$obs['id']} réponse de la requête d'insertion : " . json_encode($reponse));
403
				$this->log("Obs {$obs['id']} réponse de la requête d'insertion : " . json_encode($reponse));
402
				$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
404
				$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
403
				curl_close($ch);
405
				curl_close($ch);
404
 
406
 
405
				if (!$reponse || 200 != $code) {
407
				if (!$reponse || 200 != $code) {
406
					throw new Exception("Ça a pété à l'envoi de l'obs :\n $reponse\n avec l'obs : " . json_encode($infos_obs) . "\n");
408
					throw new Exception("Ça a pété à l'envoi de l'obs :\n $reponse\n avec l'obs : " . json_encode($infos_obs) . "\n");
407
				}
409
				}
408
 
410
 
409
				$id_obs_tb = json_decode($reponse, true)['id'];
411
				$id_obs_tb = json_decode($reponse, true)['id'];
410
				$id_obs_pn = $obs['id'];
412
				$id_obs_pn = $obs['id'];
411
				// on insère les ids de correspondance obsPN obsTB dans la table cel_plantnet
413
				// on insère les ids de correspondance obsPN obsTB dans la table cel_plantnet
412
				$sql = 'INSERT INTO cel_plantnet (id_observation, id_plantnet, date_maj)'
414
				$sql = 'INSERT INTO cel_plantnet (id_observation, id_plantnet, date_maj)'
413
						.' VALUES (%s, %s, NOW())'
415
						.' VALUES (%s, %s, NOW())'
414
						. ' -- ' . __FILE__ . ':' . __LINE__;
416
						. ' -- ' . __FILE__ . ':' . __LINE__;
415
				$sql = sprintf($sql, $this->bdd->proteger($id_obs_tb), $this->bdd->proteger($id_obs_pn));
417
				$sql = sprintf($sql, $this->bdd->proteger($id_obs_tb), $this->bdd->proteger($id_obs_pn));
416
				$this->bdd->requeter($sql);
418
				$this->bdd->requeter($sql);
417
 
419
 
418
				$date = date('d/m/Y H:i:s', intdiv($obs['dateObs'], 1000));
420
				$date = date('d/m/Y H:i:s', intdiv($obs['dateObs'], 1000));
419
				$count_img = count($images);
421
				$count_img = count($images);
420
				$images_size = number_format($images_size, 0, ',', ' ');
422
				$images_size = number_format($images_size, 0, ',', ' ');
421
				echo "Obs insérée en base : ID PN $id_obs_pn ; ID TB $id_obs_tb ; utilisateur_tb $email ; date_obs $date ; images $count_img ; taille_octets $images_size \n";
423
				echo "Obs insérée en base : ID PN $id_obs_pn ; ID TB $id_obs_tb ; utilisateur_tb $email ; date_obs $date ; images $count_img ; taille_octets $images_size \n";
422
			}
424
			}
423
		}
425
		}
424
	}
426
	}
425
 
427
 
426
	/**
428
	/**
427
	 * Return TB taxo repos names for given PN project
429
	 * Return TB taxo repos names for given PN project
428
	 *
430
	 *
429
	 * @return string
431
	 * @return string
430
	 */
432
	 */
431
	private function findProbableTaxoRepos($pnProjectId) {
433
	private function findProbableTaxoRepos($pnProjectId) {
432
		$selectedRepos = [];
434
		$selectedRepos = [];
433
		// Référentiels tela botanica indexés par référentiels PN (version octobre 2019)
435
		// Référentiels tela botanica indexés par référentiels PN (version octobre 2019)
434
		// @TODO à revoir en fonction des nouvelles mises en prod de nouveaux référentiels
436
		// @TODO à revoir en fonction des nouvelles mises en prod de nouveaux référentiels
435
		$tbTaxoRepos = [
437
		$tbTaxoRepos = [
436
			'afn' => [/*'apd', */'isfan'],
438
			'afn' => [/*'apd', */'isfan'],
437
			'aft' => ['apd'],
439
			'aft' => ['apd'],
438
			'antilles' => ['bdtxa', 'taxref'],
440
			'antilles' => ['bdtxa', 'taxref'],
439
			'canada' => ['vascan'],
441
			'canada' => ['vascan'],
440
			'comores' => ['apd'],
442
			'comores' => ['apd'],
441
			'endemia' => ['florical', 'taxref'],
443
			'endemia' => ['florical', 'taxref'],
442
			'taxref	' => ['bdtfx'],
444
			'taxref	' => ['bdtfx'],
443
			'guyane' => ['aublet', 'taxref'],
445
			'guyane' => ['aublet', 'taxref'],
444
			'hawai' => [],
446
			'hawai' => [],
445
			'lapaz' => ['aublet', 'taxref'],
447
			'lapaz' => ['aublet', 'taxref'],
446
			'martinique' => ['bdtxa', 'taxref'],
448
			'martinique' => ['bdtxa', 'taxref'],
447
			'maurice' => ['apd'],
449
			'maurice' => ['apd'],
448
			'medor' => ['lbf'],
450
			'medor' => ['lbf'],
449
			'namerica' => [],
451
			'namerica' => [],
450
			'polynesiefr' => ['taxref'],
452
			'polynesiefr' => ['taxref'],
451
			'prosea' => ['asia'],
453
			'prosea' => ['asia'],
452
			'prota' => ['isfan', 'apd'],
454
			'prota' => ['isfan', 'apd'],
453
			'provence' => ['bdtfx', 'taxref'],
455
			'provence' => ['bdtfx', 'taxref'],
454
			'reunion' => ['bdtre', 'taxref'],
456
			'reunion' => ['bdtre', 'taxref'],
455
			'salad' => ['bdtfx', 'taxref'],
457
			'salad' => ['bdtfx', 'taxref'],
456
			'useful' => [],
458
			'useful' => [],
457
			'weurope' => ['bdtfx'],
459
			'weurope' => ['bdtfx'],
458
			'the-plant-list' => [],
460
			'the-plant-list' => [],
459
			'iscantree' => ['apd'],
461
			'iscantree' => ['apd'],
460
			'central-america' => [],
462
			'central-america' => [],
461
			'invasion' => ['bdtfx'],
463
			'invasion' => ['bdtfx'],
462
			'weeds' => ['bdtfx'],
464
			'weeds' => ['bdtfx'],
463
			'malaysia' => [],
465
			'malaysia' => [],
464
		];
466
		];
465
 
467
 
466
		if (array_key_exists($pnProjectId, $tbTaxoRepos)) {
468
		if (array_key_exists($pnProjectId, $tbTaxoRepos)) {
467
			array_map(function($repo) use ($selectedRepos) {
469
			array_map(function($repo) use ($selectedRepos) {
468
				$selectedRepos[] = $repo;
470
				$selectedRepos[] = $repo;
469
			}, $tbTaxoRepos[$pnProjectId]);
471
			}, $tbTaxoRepos[$pnProjectId]);
470
		}
472
		}
471
 
473
 
472
		// @TODO chercher le nom dans plusieurs référentiels avant d'envoyer l'obs
474
		// @TODO chercher le nom dans plusieurs référentiels avant d'envoyer l'obs
473
		// prendre "enrichirDonneesTaxonomiques" du service de saisie et le coller ici
475
		// prendre "enrichirDonneesTaxonomiques" du service de saisie et le coller ici
474
		// en attendant on envoi juste le premier référentiel trouvé
476
		// en attendant on envoi juste le premier référentiel trouvé
475
		return $selectedRepos[0] ?? '';
477
		return $selectedRepos[0] ?? '';
476
	}
478
	}
477
 
479
 
478
	/*
480
	/*
479
	 * Retrouve les infos d'un utilisateur tela à partir de son email
481
	 * Retrouve les infos d'un utilisateur tela à partir de son email
480
	 * @param string $email User email
482
	 * @param string $email User email
481
	 * @return mixed 		Tableau des infos de l'utilisateur
483
	 * @return mixed 		Tableau des infos de l'utilisateur
482
	 *						False si l'email n'est pas trouvé dans l'annuaire
484
	 *						False si l'email n'est pas trouvé dans l'annuaire
483
	 */
485
	 */
484
	private function findUserInfo($email) {
486
	private function findUserInfo($email) {
485
		// cherche dans le cache
487
		// cherche dans le cache
486
		if (array_key_exists($email, $this->userInfos)) {
488
		if (array_key_exists($email, $this->userInfos)) {
487
			$infosUtilisateur = $this->userInfos[$email];
489
			$infosUtilisateur = $this->userInfos[$email];
488
			// echo("Email in cache : $email\n");
490
			// echo("Email in cache : $email\n");
489
		} else {
491
		} else {
490
			$infosUtilisateur = false;
492
			$infosUtilisateur = false;
491
			$urlInfosUtilisateur = str_replace('{email}', $email, Config::get('urlAnnuaireIdParEmail'));
493
			$urlInfosUtilisateur = str_replace('{email}', $email, Config::get('urlAnnuaireIdParEmail'));
-
 
494
 
-
 
495
			$reponse = false;
-
 
496
			$retry = 3;
492
 
497
			do {
493
			$ch = curl_init($urlInfosUtilisateur);
498
				$ch = curl_init($urlInfosUtilisateur);
494
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
499
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
495
			$reponse = curl_exec($ch);
500
				$reponse = curl_exec($ch);
496
			$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
501
				$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
-
 
502
				curl_close($ch);
-
 
503
				$retry--;
-
 
504
				if (!$reponse) {
-
 
505
					sleep(1);
-
 
506
					$this->log("Echec annuaire pour la requête $urlInfosUtilisateur tentatives restantes : $retry");
-
 
507
				}
-
 
508
			} while (!$reponse && $retry);
-
 
509
 
-
 
510
			if (!$reponse) {
-
 
511
				echo "Abandon, l'annuaire semble injoignable, impossible à télécharger : $urlInfosUtilisateur\n";
-
 
512
				return false;
497
			curl_close($ch);
513
			}
498
 
514
 
499
			// on peut pas tester le code de réponse de cette api, si l'utilisateur n'est pas trouvé ça fait une 500 >_<
515
			// on peut pas tester le code de réponse de cette api, si l'utilisateur n'est pas trouvé ça fait une 500 >_<
500
			// une bonne réponse ressemble à ça :
516
			// une bonne réponse ressemble à ça :
501
			// {"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"}}
517
			// {"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"}}
502
			$reponse = json_decode($reponse, true);
518
			$reponse = json_decode($reponse, true);
503
			if (!isset($reponse)) {
519
			if (!isset($reponse)) {
504
				throw new Exception("\nL'annuaire n'a pas répondu avec du json : code $code à l'adresse $urlInfosUtilisateur : $reponse\n");
520
				throw new Exception("\nL'annuaire n'a pas répondu avec du json : code $code à l'adresse $urlInfosUtilisateur : $reponse\n");
505
			}
521
			}
506
 
522
 
507
			if (!isset($reponse['error'])) {
523
			if (!isset($reponse['error'])) {
508
				$infosUtilisateur = array_shift($reponse);
524
				$infosUtilisateur = array_shift($reponse);
509
			}
525
			}
510
 
526
 
511
			// met en cache
527
			// met en cache
512
			$this->userInfos[$email] = $infosUtilisateur;
528
			$this->userInfos[$email] = $infosUtilisateur;
513
			// echo("Email cached : $email\n");
529
			// echo("Email cached : $email\n");
514
		}
530
		}
515
 
531
 
516
		return $infosUtilisateur;
532
		return $infosUtilisateur;
517
	}
533
	}
518
 
534
 
519
	private function getGeoInfo($obs) {
535
	private function getGeoInfo($obs) {
520
		$geo = [];
536
		$geo = [];
521
		if (!isset($obs['lat']) && !isset($obs['lon'])) {
537
		if (!isset($obs['lat']) && !isset($obs['lon'])) {
522
			return $geo;
538
			return $geo;
523
		}
539
		}
524
 
540
 
525
		// $data = [
541
		// $data = [
526
		// 	'hitsPerPage' => 1,
542
		// 	'hitsPerPage' => 1,
527
		// 	'aroundLatLng' => "{$obs['lat']},{$obs['lon']}"
543
		// 	'aroundLatLng' => "{$obs['lat']},{$obs['lon']}"
528
		// ];
544
		// ];
529
		$headers = [
545
		$headers = [
530
			'X-Algolia-Application-Id' => Config::get('algoliaApplicationId'),
546
			'X-Algolia-Application-Id' => Config::get('algoliaApplicationId'),
531
			'X-Algolia-API-Key' => Config::get('algoliaAPIKey'),
547
			'X-Algolia-API-Key' => Config::get('algoliaAPIKey'),
532
		];
548
		];
533
 
549
 
534
		$lat = number_format($obs['lat'], 6, '.', '');
550
		$lat = number_format($obs['lat'], 6, '.', '');
535
		$lon = number_format($obs['lon'], 6, '.', '');
551
		$lon = number_format($obs['lon'], 6, '.', '');
536
 
552
 
537
		$ch = curl_init(Config::get('urlReverseGeocodingLatLng')."$lat,$lon");
553
		$ch = curl_init(Config::get('urlReverseGeocodingLatLng')."$lat,$lon");
538
		curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
554
		curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
539
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
555
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
540
		$reponse = curl_exec($ch);
556
		$reponse = curl_exec($ch);
541
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
557
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
542
		curl_close($ch);
558
		curl_close($ch);
543
 
559
 
544
		if ($reponse) {
560
		if ($reponse) {
545
			$reponse = json_decode($reponse, true);
561
			$reponse = json_decode($reponse, true);
546
			// die(var_dump($reponse));
562
			// die(var_dump($reponse));
547
			$infos = $reponse['hits'][0];
563
			$infos = $reponse['hits'][0];
548
 
564
 
549
			$geo = [
565
			$geo = [
550
				'lat' => (string) $obs['lat'],
566
				'lat' => (string) $obs['lat'],
551
				'lon' => (string) $obs['lon'],
567
				'lon' => (string) $obs['lon'],
552
				'country' => $infos['country']['fr'] ?? $infos['country']['default'],
568
				'country' => $infos['country']['fr'] ?? $infos['country']['default'],
553
				'city' => $infos['city']['default'][0] ?? null,
569
				'city' => $infos['city']['default'][0] ?? null,
554
				'postcode' => $infos['postcode'][0] ?? null,
570
				'postcode' => $infos['postcode'][0] ?? null,
555
				'countryCode' => strtoupper($infos['country_code']),
571
				'countryCode' => strtoupper($infos['country_code']),
556
			];
572
			];
557
		}
573
		}
558
 
574
 
559
		return $geo;
575
		return $geo;
560
	}
576
	}
561
 
577
 
562
	private function updateFromPN(array $pnObs, string $tbObsId) {
578
	private function updateFromPN(array $pnObs, string $tbObsId) {
563
		if (!is_array($pnObs) || !is_string($tbObsId)) {
579
		if (!is_array($pnObs) || !is_string($tbObsId)) {
564
			// die(var_dump($pnObs, $tbObsId));
580
			// die(var_dump($pnObs, $tbObsId));
565
			throw new Exception("\nBad params types, give me an array and an integer plz\n");
581
			throw new Exception("\nBad params types, give me an array and an integer plz\n");
566
		}
582
		}
567
		// die(var_dump($pnObs));
583
		// die(var_dump($pnObs));
568
 
584
 
569
		// log update date to cel_plantnet
585
		// log update date to cel_plantnet
570
		$sql = "UPDATE cel_plantnet SET date_maj = NOW() WHERE id_observation = $tbObsId"
586
		$sql = "UPDATE cel_plantnet SET date_maj = NOW() WHERE id_observation = $tbObsId"
571
				. ' -- ' . __FILE__ . ':' . __LINE__;
587
				. ' -- ' . __FILE__ . ':' . __LINE__;
572
		$this->bdd->requeter($sql);
588
		$this->bdd->requeter($sql);
573
 
589
 
574
		// check for deleted
590
		// check for deleted
575
		if (isset($pnObs['deleted']) && (true === $pnObs['deleted'])) {
591
		if (isset($pnObs['deleted']) && (true === $pnObs['deleted'])) {
576
			// est-ce une obs issue de PN ?
592
			// est-ce une obs issue de PN ?
577
			//// faut regarder le champ input_source == PlantNet
593
			//// faut regarder le champ input_source == PlantNet
578
			$sql = "SELECT input_source FROM occurrence WHERE id = '$tbObsId'"
594
			$sql = "SELECT input_source FROM occurrence WHERE id = '$tbObsId'"
579
					. ' -- ' . __FILE__ . ':' . __LINE__;
595
					. ' -- ' . __FILE__ . ':' . __LINE__;
580
			$res = $this->bdd->recupererTous($sql);
596
			$res = $this->bdd->recupererTous($sql);
581
 
597
 
582
			if (isset($res[0]) && ('PlantNet' === $res[0]['input_source'])) {
598
			if (isset($res[0]) && ('PlantNet' === $res[0]['input_source'])) {
583
				// oui ? alors supprimer obs !
599
				// oui ? alors supprimer obs !
584
				echo "Obs supprimée coté PN, suppression : ID PN {$obs['id']} ; ID TB {$res[0]['id_observation']}\n";
600
				echo "Obs supprimée coté PN, suppression : ID PN {$pnObs['id']} ; ID TB {$res[0]['id_observation']}\n";
585
 
601
 
586
				$sql = "UPDATE photos SET occurrence_id = NULL WHERE occurrence_id = '$tbObsId'"
602
				$sql = "UPDATE photo SET occurrence_id = NULL WHERE occurrence_id = '$tbObsId'"
587
						. ' -- ' . __FILE__ . ':' . __LINE__;
603
						. ' -- ' . __FILE__ . ':' . __LINE__;
588
				$this->bdd->requeter($sql);
604
				$this->bdd->requeter($sql);
589
 
605
 
590
				$sql = "DELETE FROM occurrence WHERE id = '$tbObsId'"
606
				$sql = "DELETE FROM occurrence WHERE id = '$tbObsId'"
591
						. ' -- ' . __FILE__ . ':' . __LINE__;
607
						. ' -- ' . __FILE__ . ':' . __LINE__;
592
				$this->bdd->requeter($sql);
608
				$this->bdd->requeter($sql);
593
			}
609
			}
594
		}
610
		}
595
 
611
 
596
		// check for deleted images
612
		// check for deleted images
597
		foreach ($pnObs['images'] as $image) {
613
		foreach ($pnObs['images'] as $image) {
598
			if ($image['deleted']) {
614
			if ($image['deleted']) {
599
				// no idea
615
				// no idea
600
				// y'a pas encore de lien tangible entre les images PN et les notres
616
				// y'a pas encore de lien tangible entre les images PN et les notres
601
			}
617
			}
602
		}
618
		}
603
 
619
 
604
		// @TODO : finir la comparaison des proposition entre celles de Tela et celles PN
620
		// @TODO : finir la comparaison des proposition entre celles de Tela et celles PN
605
		// // check for votes (notes et taxon)
621
		// // check for votes (notes et taxon)
606
		// $names = [];
622
		// $names = [];
607
		// foreach ($pnObs['computed']['votes'] as $vote) {
623
		// foreach ($pnObs['computed']['votes'] as $vote) {
608
		// 	echo($vote['name']);
624
		// 	echo($vote['name']);
609
		// 	echo($vote['score']['pn']);
625
		// 	echo($vote['score']['pn']);
610
		// 	echo($vote['score']['total']);
626
		// 	echo($vote['score']['total']);
611
 
627
 
612
		// 	$names[$vote['score']['pn']] = $vote['name'];
628
		// 	$names[$vote['score']['pn']] = $vote['name'];
613
		// }
629
		// }
614
		// ksort($names, SORT_NUMERIC); // votes sorted by score asc
630
		// ksort($names, SORT_NUMERIC); // votes sorted by score asc
615
		// $pn_sorted_votes = array_reverse($names, true); // desc
631
		// $pn_sorted_votes = array_reverse($names, true); // desc
616
 
632
 
617
		// // get existing votes
633
		// // get existing votes
618
		// $sql = "SELECT id_commentaire, nom_sel, nom_sel_nn, nom_referentiel, nom_referentiel, utilisateur_courriel, proposition_initiale, proposition_retenue"
634
		// $sql = "SELECT id_commentaire, nom_sel, nom_sel_nn, nom_referentiel, nom_referentiel, utilisateur_courriel, proposition_initiale, proposition_retenue"
619
		// 		. "WHERE ce_observation = '$tbObsId' AND ce_commentaire_parent = 0"
635
		// 		. "WHERE ce_observation = '$tbObsId' AND ce_commentaire_parent = 0"
620
		// 		. ' -- ' . __FILE__ . ':' . __LINE__;
636
		// 		. ' -- ' . __FILE__ . ':' . __LINE__;
621
		// $existing_votes = $this->bdd->recupererTous($sql);
637
		// $existing_votes = $this->bdd->recupererTous($sql);
622
 
638
 
623
		// // @TODO : compare votes
639
		// // @TODO : compare votes
624
		// // insert_new_votes($pn_sorted_votes, $existing_votes);
640
		// // insert_new_votes($pn_sorted_votes, $existing_votes);
625
	}
641
	}
626
 
642
 
627
	private function updateOnePN($pnObsId, $pnProjectId) {
643
	private function updateOnePN($pnObsId, $pnProjectId) {
628
		if (!is_int($pnObsId) || !is_string($pnProjectId)) {
644
		if (!is_int($pnObsId) || !is_string($pnProjectId)) {
629
			die(var_dump($pnObsId, $pnProjectId));
645
			die(var_dump($pnObsId, $pnProjectId));
630
			throw new Exception("\nBad params types, give me an integer and a string plz\n");
646
			throw new Exception("\nBad params types, give me an integer and a string plz\n");
631
		}
647
		}
632
		// get PN project list
648
		// get PN project list
633
		$list = [];
649
		$list = [];
634
		$pnProjects = $this->getProjects(); // refresh projects list
650
		$pnProjects = $this->getProjects(); // refresh projects list
635
		foreach ($pnProjects as $project) {
651
		foreach ($pnProjects as $project) {
636
			$list[$project['id']] = $project['name'];
652
			$list[$project['id']] = $project['name'];
637
		}
653
		}
638
 
654
 
639
		// if project not in list display list
655
		// if project not in list display list
640
		if (!array_key_exists($pnProjectId, $list)) {
656
		if (!array_key_exists($pnProjectId, $list)) {
641
			echo "Available projects:\n";
657
			echo "Available projects:\n";
642
			foreach ($list as $projectId => $projectName) {
658
			foreach ($list as $projectId => $projectName) {
643
				echo " - $projectId ($projectName)\n";
659
				echo " - $projectId ($projectName)\n";
644
			}
660
			}
645
			throw new Exception("Project $pnProjectId does not exist\n");
661
			throw new Exception("Project $pnProjectId does not exist\n");
646
		} else {
662
		} else {
647
			$this->currentProject = [
663
			$this->currentProject = [
648
				'id' => $pnProjectId,
664
				'id' => $pnProjectId,
649
				'name' => $list[$pnProjectId],
665
				'name' => $list[$pnProjectId],
650
			];
666
			];
651
		}
667
		}
652
 
668
 
653
		// get PN obs
669
		// get PN obs
654
		$urlInfosObs = str_replace(
670
		$urlInfosObs = str_replace(
655
			['{token}', '{project}', '{id}'],
671
			['{token}', '{project}', '{id}'],
656
			[Config::get('tokenPlantnet'), $pnProjectId, $pnObsId],
672
			[Config::get('tokenPlantnet'), $pnProjectId, $pnObsId],
657
			Config::get('urlPlantnetBase').Config::get('urlPlantnetObsById')
673
			Config::get('urlPlantnetBase').Config::get('urlPlantnetObsById')
658
		);
674
		);
659
		$ch = curl_init($urlInfosObs);
675
		$ch = curl_init($urlInfosObs);
660
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
676
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
661
		$response = curl_exec($ch);
677
		$response = curl_exec($ch);
662
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
678
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
663
		curl_close($ch);
679
		curl_close($ch);
664
 
680
 
665
		if (!$response || 200 != $code) {
681
		if (!$response || 200 != $code) {
666
			throw new Exception("\nPlantnet api ($urlInfosObs) replied with code $code : $response\n");
682
			throw new Exception("\nPlantnet api ($urlInfosObs) replied with code $code : $response\n");
667
		}
683
		}
668
 
684
 
669
		// change last modification date to force update
685
		// change last modification date to force update
670
		$obs = json_decode($response, true);
686
		$obs = json_decode($response, true);
671
		$date = new DateTime();
687
		$date = new DateTime();
672
		$date->setTimestamp(intdiv($obs['dateUpdated'], 1000) - 1);
688
		$date->setTimestamp(intdiv($obs['dateUpdated'], 1000) - 1);
673
		$date = $this->bdd->proteger($date->format('Y-m-d H:i:s'));
689
		$date = $this->bdd->proteger($date->format('Y-m-d H:i:s'));
674
		$sql = "UPDATE cel_plantnet SET date_maj = $date WHERE id_plantnet = '$pnObsId'"
690
		$sql = "UPDATE cel_plantnet SET date_maj = $date WHERE id_plantnet = '$pnObsId'"
675
				. ' -- ' . __FILE__ . ':' . __LINE__;
691
				. ' -- ' . __FILE__ . ':' . __LINE__;
676
		$this->bdd->requeter($sql);
692
		$this->bdd->requeter($sql);
677
 
693
 
678
		$this->updateObs([$obs]);
694
		$this->updateObs([$obs]);
679
	}
695
	}
680
 
696
 
681
	private function updateOneTB($id) {
697
	private function updateOneTB($id) {
682
		$corres = $this->findMatchingPartnerId($id, 'tb');
698
		$corres = $this->findMatchingPartnerId($id, 'tb');
683
		echo "L'obs tela avec l'id $id a été trouvée chez plantnet avec l'id : " .$corres['pn'] . "\n";
699
		echo "L'obs tela avec l'id $id a été trouvée chez plantnet avec l'id : " .$corres['pn'] . "\n";
684
		echo "La suite n'a pas été implémentée.\n";
700
		echo "La suite n'a pas été implémentée.\n";
685
	}
701
	}
686
 
702
 
687
	/*
703
	/*
688
	 * Trouve les ids d'une obs chez les partenaires
704
	 * Trouve les ids d'une obs chez les partenaires
689
	 * Il faut lancer updateMatchingPartnersIds pour obtenir une liste fraiche
705
	 * Il faut lancer updateMatchingPartnersIds pour obtenir une liste fraiche
690
	 *
706
	 *
691
	 * @param 	string $id			L'id de l'obs
707
	 * @param 	string $id			L'id de l'obs
692
	 * @param 	string $partner		Le partenaire correspondant à l'id de l'obs
708
	 * @param 	string $partner		Le partenaire correspondant à l'id de l'obs
693
	 *
709
	 *
694
	 * @return  mixed 				Le tableau de correspondances d'ids
710
	 * @return  mixed 				Le tableau de correspondances d'ids
695
	 *								False si l'id n'est pas trouvé
711
	 *								False si l'id n'est pas trouvé
696
	 */
712
	 */
697
	private function findMatchingPartnerId($id, $partner) {
713
	private function findMatchingPartnerId($id, $partner) {
698
		if (!in_array($partner, $this->allowedPartners)) {
714
		if (!in_array($partner, $this->allowedPartners)) {
699
			throw new Exception("\nUnknown partner : $partner. Available Partners : " . implode(', ', $this->allowedPartners) . "\n");
715
			throw new Exception("\nUnknown partner : $partner. Available Partners : " . implode(', ', $this->allowedPartners) . "\n");
700
		}
716
		}
701
 
717
 
702
		// le json ressemble à ça :
718
		// le json ressemble à ça :
703
		// {"tb":"2369732","pn":"1001020199"}, {"tb":"2369733","pn":"1001020176"}, ...
719
		// {"tb":"2369732","pn":"1001020199"}, {"tb":"2369733","pn":"1001020176"}, ...
704
		$ids = json_decode(file_get_contents($this->correspondingIdsFilename), true);
720
		$ids = json_decode(file_get_contents($this->correspondingIdsFilename), true);
705
		// extrait la colonne du partenaire recherché du tableau multidimensionnel fraichement décodé
721
		// extrait la colonne du partenaire recherché du tableau multidimensionnel fraichement décodé
706
		$partnerColumn = array_column($ids, $partner);
722
		$partnerColumn = array_column($ids, $partner);
707
		// cherche l'index de l'id recherché
723
		// cherche l'index de l'id recherché
708
		$index = array_search($id, $partnerColumn);
724
		$index = array_search($id, $partnerColumn);
709
 
725
 
710
		return $index ? $ids[$index] : false;
726
		return $index ? $ids[$index] : false;
711
	}
727
	}
712
 
728
 
713
	private function updateCorrespondingIdsTable() {
729
	private function updateCorrespondingIdsTable() {
714
		// first update cache file if necessary
730
		// first update cache file if necessary
715
		if (!file_exists($this->correspondingIdsFilename) || time() > (filemtime($this->correspondingIdsFilename) + (24 * 3600))) {
731
		if (!file_exists($this->correspondingIdsFilename) || time() > (filemtime($this->correspondingIdsFilename) + (24 * 3600))) {
716
			$this->updateMatchingPartnersIds();
732
			$this->updateMatchingPartnersIds();
717
		}
733
		}
718
 
734
 
719
		$data = file_get_contents($this->correspondingIdsFilename);
735
		$data = file_get_contents($this->correspondingIdsFilename);
720
		$data = json_decode($data, true);
736
		$data = json_decode($data, true);
721
 
737
 
722
		$now = new DateTime;
738
		$now = new DateTime;
723
		$now = $this->bdd->proteger($now->format('Y-m-d H:i:s'));
739
		$now = $this->bdd->proteger($now->format('Y-m-d H:i:s'));
724
 
740
 
725
		$sqlInsert = 'INSERT INTO cel_plantnet (id_observation, id_plantnet, date_maj)'
741
		$sqlInsert = 'INSERT INTO cel_plantnet (id_observation, id_plantnet, date_maj)'
726
					. ' VALUES %s'
742
					. ' VALUES %s'
727
					. ' ON DUPLICATE KEY UPDATE id_observation=VALUES(id_observation), id_plantnet=VALUES(id_plantnet)'
743
					. ' ON DUPLICATE KEY UPDATE id_observation=VALUES(id_observation), id_plantnet=VALUES(id_plantnet)'
728
					. ' -- ' . __FILE__ . ':' . __LINE__;
744
					. ' -- ' . __FILE__ . ':' . __LINE__;
729
		$values = '';
745
		$values = '';
730
 
746
 
731
		echo "Updating matching partners ids table\n";
747
		echo "Updating matching partners ids table\n";
732
		foreach ($data as $id => $corres) {
748
		foreach ($data as $id => $corres) {
733
			$id_obs_tb = $this->bdd->proteger($corres['tb']);
749
			$id_obs_tb = $this->bdd->proteger($corres['tb']);
734
			$id_obs_pn = $this->bdd->proteger($corres['pn']);
750
			$id_obs_pn = $this->bdd->proteger($corres['pn']);
735
			// on insère les ids de correspondance obsPN obsTB dans la table cel_plantnet
751
			// on insère les ids de correspondance obsPN obsTB dans la table cel_plantnet
736
			$values .= " ($id_obs_tb, $id_obs_pn, $now),";
752
			$values .= " ($id_obs_tb, $id_obs_pn, $now),";
737
 
753
 
738
			if (0 === $id % 100) {
754
			if (0 === $id % 100) {
739
				$values = substr($values, 0, -1); // retire la dernière virgule
755
				$values = substr($values, 0, -1); // retire la dernière virgule
740
				$sql = sprintf($sqlInsert, $values);
756
				$sql = sprintf($sqlInsert, $values);
741
				// var_dump($sql);
757
				// var_dump($sql);
742
				$this->bdd->requeter($sql);
758
				$this->bdd->requeter($sql);
743
				$values = '';
759
				$values = '';
744
			}
760
			}
745
		}
761
		}
746
		// Faut envoyer les dernières données qui sont pas passées dans le modulo
762
		// Faut envoyer les dernières données qui sont pas passées dans le modulo
747
		$values = substr($values, 0, -1); // retire la dernière virgule
763
		$values = substr($values, 0, -1); // retire la dernière virgule
748
		$sql = sprintf($sqlInsert, $values);
764
		$sql = sprintf($sqlInsert, $values);
749
		// var_dump($sql);
765
		// var_dump($sql);
750
		$this->bdd->requeter($sql);
766
		$this->bdd->requeter($sql);
751
 
767
 
752
		$count = count($data);
768
		$count = count($data);
753
		echo "Success: #$count updated\n";
769
		echo "Success: #$count updated\n";
754
	}
770
	}
755
 
771
 
756
	private function updateMatchingPartnersIds() {
772
	private function updateMatchingPartnersIds() {
757
		// curl -X GET --header 'Accept: application/json' 'https://bourbonnais.cirad.fr:8081/v1/edi/observations/partnerids?token=f0ca433febe320675c24ee2ddfab8b82f65d556b' > partnerids.txt
773
		// curl -X GET --header 'Accept: application/json' 'https://bourbonnais.cirad.fr:8081/v1/edi/observations/partnerids?token=f0ca433febe320675c24ee2ddfab8b82f65d556b' > partnerids.txt
758
		$matchingPartnersIdsServiceUrl = str_replace(
774
		$matchingPartnersIdsServiceUrl = str_replace(
759
			'{token}',
775
			'{token}',
760
			Config::get('tokenPlantnet'),
776
			Config::get('tokenPlantnet'),
761
			Config::get('urlPlantnetBase').Config::get('urlPlantnetMatchingPartner')
777
			Config::get('urlPlantnetBase').Config::get('urlPlantnetMatchingPartner')
762
		);
778
		);
763
		$ch = curl_init($matchingPartnersIdsServiceUrl);
779
		$ch = curl_init($matchingPartnersIdsServiceUrl);
764
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
780
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
765
 
781
 
766
		echo "Updating matching partners ids...\n";
782
		echo "Updating matching partners ids...\n";
767
		$reponse = curl_exec($ch);
783
		$reponse = curl_exec($ch);
768
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
784
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
769
		curl_close($ch);
785
		curl_close($ch);
770
 
786
 
771
 
787
 
772
		if (!$reponse || 200 != $code) {
788
		if (!$reponse || 200 != $code) {
773
			throw new Exception("\nError updating partners ids, http error code \"$code\" whith url \"$matchingPartnersIdsServiceUrl\"...\n");
789
			throw new Exception("\nError updating partners ids, http error code \"$code\" whith url \"$matchingPartnersIdsServiceUrl\"...\n");
774
		}
790
		}
775
		echo "Response data from PN api gathered, know computing...\n";
791
		echo "Response data from PN api gathered, know computing...\n";
776
 
792
 
777
		if (!file_put_contents($this->correspondingIdsFilename, $reponse)) {
793
		if (!file_put_contents($this->correspondingIdsFilename, $reponse)) {
778
			throw new Exception("\nError writing correspondingIdsFilename with path : " . $this->correspondingIdsFilename . "\n");
794
			throw new Exception("\nError writing correspondingIdsFilename with path : " . $this->correspondingIdsFilename . "\n");
779
		}
795
		}
780
		echo "Matching partners ids saved!";
796
		echo "Matching partners ids saved!";
781
	}
797
	}
782
 
798
 
783
	private function debug($text) {
799
	private function debug($text) {
784
		if ($this->debug) {
800
		if ($this->debug) {
785
			echo 'DEBUG - ' . $text . "\n";
801
			echo 'DEBUG - ' . $text . "\n";
786
		}
802
		}
787
	}
803
	}
788
 
804
 
789
	private function log($text) {
805
	private function log($text) {
790
		if ('log' == $this->debug) {
806
		if ('log' == $this->debug) {
791
			echo 'LOG - ' . $text . "\n";
807
			echo 'LOG - ' . $text . "\n";
792
		}
808
		}
793
	}
809
	}
794
 
810
 
795
	private function refreshBddConnexion() {
811
	private function refreshBddConnexion() {
796
		$this->bdd = null;
812
		$this->bdd = null;
797
		$this->log("Fermeture et création d'une nouvelle connexion à la BdD");
813
		$this->log("Fermeture et création d'une nouvelle connexion à la BdD");
798
		$this->bdd = new Bdd();
814
		$this->bdd = new Bdd();
799
	}
815
	}
800
}
816
}