* @author Jean-Pascal MILCENT * @author Aurelien PERONNET * @license GPL v3 * @license CECILL v2 * @copyright 1999-2014 Tela Botanica */ class AlerteMailADeterminer { private $conteneur; private $testeurCourriel = null; private $recapitulatifAdmin = []; private $messageRecapitulatif = null; private $dateRenvoi = null; private $observations_concernees = array(); private $messageHtml = null; private $messageTxt = null; private $utilisateursInfos = array(); public function __construct($conteneur) { $this->conteneur = $conteneur; } public function executer() { try { $this->verifierModeUtilisation(); $this->verifierDateRenvoi(); $observations = $this->chargerObsADeterminer(); if (!empty($observations)) { $this->formaterObservations($observations); $this->genererMessage(); $this->envoyerMessageAuxDestinataires(); } } catch (Exception $e) { $this->traiterErreur($e->getMessage()); } } protected function traiterErreur($msg) { echo "ERREUR: $msg\n"; } private function verifierModeUtilisation() { $testeurCourriel = $this->conteneur->getParametre('t'); if ($testeurCourriel) { if (filter_var($testeurCourriel, FILTER_VALIDATE_EMAIL)) { $this->testeurCourriel = $testeurCourriel; } else { $msg = "Veuillez indiquer une adresse de courriel valide à la suite du paramètre «-t»."; new Exception($msg); } } } private function verifierDateRenvoi() { $dateRenvoi = $this->conteneur->getParametre('d'); if ($dateRenvoi) { if (preg_match('/^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$/', $dateRenvoi)) { $this->dateRenvoi = $dateRenvoi; } else { $msg = "Veuillez indiquer une date au format yyyy-mm-dd valide à la suite du paramètre «-d»."; new Exception($msg); } } } protected function chargerObsADeterminer() { //TODO: optimiser la requête si beaucoup de mails sont envoyés $date = ($this->dateRenvoi == null) ? 'CURDATE()' : "'$this->dateRenvoi'"; $requete = 'SELECT id_observation, do.courriel_utilisateur, '. ' date_observation, nom_ret, nom_sel, '. ' ce_zone_geo, zone_geo, lieudit, station '. 'FROM del_observation AS do '. 'WHERE do.ce_utilisateur != 0 '. ' AND do.ce_utilisateur IS NOT NULL '. " AND (do.mots_cles_texte LIKE '%aDeterminer%' ". " OR (do.certitude = 'aDeterminer' OR do.certitude = 'A déterminer' OR do.certitude = 'douteux') ". " OR nom_sel IS NULL OR nom_sel = '' ". " OR nom_ret IS NULL OR nom_ret = '') ". ' AND ('. " TO_DAYS($date) - TO_DAYS(do.date_transmission) IN (0, 1) ". " OR TO_DAYS($date) - TO_DAYS(do.date_creation) IN (0, 1) ". " OR TO_DAYS($date) - TO_DAYS(do.date_modification) IN (0, 1) ". ' ) '. "ORDER BY do.id_observation "; $obs = $this->conteneur->getBdd()->recupererTous($requete); return $obs; } private function formaterObservations($liste_obs) { // lister les courriels $courriels = array(); foreach ($liste_obs as $obs) { $courriels[] = $obs['courriel_utilisateur']; } $courriels = array_unique($courriels); $courriels = array_filter($courriels); // récupérer les pseudos $identites = TelaBotanica\Del\Commun\Utilisateurs::identiteUtilisateurs($courriels, $this->conteneur->getParametre('url_service_utilisateur')); // emboîter tout foreach ($liste_obs as $obs) { // identité de l'utilisateur : pseudo, nom-prénom ou courriel tronqué $identiteUtil = $obs['courriel_utilisateur']; // sera tronqué si rien de mieux n'a été trouvé if (isset($identites[$obs['courriel_utilisateur']])) { $identiteUtil = $identites[$obs['courriel_utilisateur']]; } $identiteUtil = TelaBotanica\Del\Commun\Utilisateurs::identiteAAfficher($identiteUtil); $id_obs = $obs['id_observation']; $infos = array(); $infos['id'] = $id_obs; $infos['date'] = $this->formaterDateObs($obs['date_observation']); $infos['nom_propose'] = $this->formaterNomSci($obs); $infos['lien'] = $this->obtenirLienFicheObs($id_obs); $infos['lieu'] = $this->formaterLieu($obs); $infos['auteur'] = $identiteUtil; $this->observations_concernees[$id_obs] = $infos; } } private function formaterDateObs($date) { $dateFmt = '(date inconnue)'; if ($date != '0000-00-00 00:00:00') { $time = strtotime($date); $dateFmt = date('d/m/Y', $time); } return $dateFmt; } private function formaterNomSci($obs) { $nom = 'Espèce indéterminée'; if ($obs['nom_ret'] != '') { $nom = $obs['nom_ret']; } else if($obs['nom_sel'] != '') { $nom = $obs['nom_sel']; } return $nom; } private function obtenirLienFicheObs($id_obs) { return sprintf($this->conteneur->getParametre('url_fiche_observation'), $id_obs); } private function formaterLieu($obs) { $lieuInfos = []; $champsLieu = ['zone_geo', 'lieudit', 'station']; foreach ($champsLieu as $champ) { if (trim($obs[$champ]) == '') { continue; } $lieuIntitule = $obs[$champ]; if ($champ == 'zone_geo') { $codeDept = $this->convertirCodeZoneGeoVersDepartement($obs['ce_zone_geo']); $lieuIntitule .= empty($codeDept) ? '' : " ($codeDept)"; } $lieuInfos[] = $lieuIntitule; } $lieu = (count($lieuInfos) > 0) ? implode(' > ', $lieuInfos) : '(lieu inconnu)'; return $lieu; } private function convertirCodeZoneGeoVersDepartement($code_zone_geo) { $code_departement = ''; if (preg_match('/^INSEE-C:([0-9]{2})[0-9]{3}$/', $code_zone_geo, $match)) { $code_departement = $match[1]; } return $code_departement; } private function genererMessage() { if ($this->messageHtml == null && $this->messageTxt == null) { $donnees = array(); $donnees['liste_observations'] = $this->observations_concernees; $squelettePhp = $this->conteneur->getSquelettePhp(); $messageHtmlTpl = dirname(__FILE__).DS.'squelettes'.DS.'aDeterminer.tpl.html'; $this->messageHtml = $squelettePhp->analyser($messageHtmlTpl, $donnees); $messageTxtTpl = dirname(__FILE__).DS.'squelettes'.DS.'aDeterminer.tpl.txt'; $this->messageTxt = $squelettePhp->analyser($messageTxtTpl, $donnees); } } private function envoyerMessageAuxDestinataires() { if ($this->testeurCourriel == null) { $this->envoyerMessageAuxUtilisateurs(); $this->envoyerMessageListeDetermination(); $this->envoyerMessageRecap(); } else { $this->envoyerMessageTesteur(); } } private function envoyerMessageAuxUtilisateurs() { $utilisateurs = $this->obtenirDestinatairesMailsRecapitulatif(); foreach ($utilisateurs as $idUtilisateur) { $this->envoyerMessage($idUtilisateur); } } private function obtenirDestinatairesMailsRecapitulatif() { if (count($this->recapitulatifAdmin) == 0) { $preference = $this->conteneur->getBdd()->proteger('%"mail_notification_toutes_obs":"1"%'); $requete = "SELECT id_utilisateur ". "FROM del_utilisateur_infos ". "WHERE preferences LIKE $preference "; $utilisateurs = $this->conteneur->getBdd()->recupererTous($requete); foreach ($utilisateurs as $utilisateur) { $this->recapitulatifAdmin[] = $utilisateur['id_utilisateur']; } } return $this->recapitulatifAdmin; } /** * Appelle le web service message de l'annuaire afin d'envoyer un mail à l'utilisateur dont l'identifiant est donné * en paramètre * Enter description here ... * @param string $message * @param int $id_destinataire */ private function envoyerMessage($id_destinataire) { $url = sprintf($this->conteneur->getParametre('url_service_messagerie'), $id_destinataire); $dateFmt = $this->formaterDateCourante(); $sujet = sprintf($this->conteneur->getParametre('titre_message_recapitulatif_obs'), $dateFmt); $donnees = array( 'utilisateur_courriel' => $this->conteneur->getParametre('adresse_expediteur_recapitulatif'), 'format' => 'html', 'sujet' => $sujet, 'message' => $this->messageHtml, 'message_txt' => $this->messageTxt ); $clientRest = $this->conteneur->getRestClient(); $clientRest->modifier($url, $donnees); } private function formaterDateCourante() { $date = ($this->dateRenvoi == null) ? time() : strtotime($this->dateRenvoi); $dateFmt = date('d-m-Y', $date); return $dateFmt; } /** La liste détermination n'étant pas un membre de tela botanica, * on lui envoie un message directement * @return boolean true ou false suivant le succès ou non de l'envoi */ private function envoyerMessageListeDetermination() { $destinataires = $this->conteneur->getParametre('adresse_destinataire_recapitulatif_determination'); $dateFmt = $this->formaterDateCourante(); $sujet = sprintf($this->conteneur->getParametre('titre_message_recapitulatif_obs'), $dateFmt); $messagerie = $this->conteneur->getMessagerie(); $envoieStatut = $messagerie->envoyerHtml($destinataires, $sujet, $this->messageHtml, $this->messageTxt); return $envoieStatut; } private function envoyerMessageRecap() { $msgRecap = $this->obtenirMessageRecap(); $dateFmt = $this->formaterDateCourante(); $sujet = "IdentiPlante : obs du $dateFmt"; $messagerie = $this->conteneur->getMessagerie(); $destinataire = $this->conteneur->getParametre('email_recap'); $messagerie->envoyerTxt($destinataire, $sujet, $msgRecap); } private function obtenirMessageRecap() { if ($this->messageRecapitulatif == null) { $utilisateursIntitules = $this->obtenirInfosUtilisateurs(); $intituleRecap = implode("\n", $utilisateursIntitules); $separateur = str_repeat('-', 50); $msgTpl = "Messages envoyés aux utilisateurs suivant :\n%s\n%s\n%s"; $this->messageRecapitulatif = sprintf($msgTpl, $intituleRecap, $separateur, $this->messageTxt); } return $this->messageRecapitulatif; } private function obtenirInfosUtilisateurs() { $utilisateursIntitules = []; $utilisateurs = $this->obtenirDestinatairesMailsRecapitulatif(); foreach ($utilisateurs as $utilisateurId) { $infosUtilisateur = $this->telechargerUtilisateurInfos($utilisateurId); $intitule = $this->formaterUtilisateurInfos($infosUtilisateur); $utilisateursIntitules[$utilisateurId] = $intitule; } asort($utilisateursIntitules); return $utilisateursIntitules; } protected function telechargerUtilisateurInfos($utilisateurId) { if (! isset($this->utilisateursInfos[$utilisateurId])) { $urlTpl = $this->conteneur->getParametre('url_service_utilisateur'); $url = sprintf($urlTpl, $utilisateurId); $clientRest = $this->conteneur->getRestClient(); $json = $clientRest->consulter($url); $infos = json_decode($json, true); if (is_array($infos)) { $infos = array_shift($infos); } $this->utilisateursInfos[$utilisateurId] = isset($infos['id']) ? $infos : $utilisateurId; } return $this->utilisateursInfos[$utilisateurId]; } protected function formaterUtilisateurInfos($infos) { $utilisateurId = isset($infos['id']) ? $infos['id'] : intval($infos); if (isset($infos['courriel']) && isset($infos['intitule'])) { $prenomNom = $infos['nom'].' '.$infos['prenom']; $pseudo = empty($infos['pseudo']) ? '' : '['.$infos['pseudo'].'] '; $courriel = $infos['courriel']; $intitule = "$prenomNom $pseudo($courriel) - id#$utilisateurId"; } else { $intitule = "Utilisateur avec id $utilisateurId introuvable"; } return $intitule; } private function envoyerMessageTesteur() { if ($this->testeurCourriel != null) { $messagerie = $this->conteneur->getMessagerie(); $dateFmt = $this->formaterDateCourante(); $sujet = "TESTEUR : obs du $dateFmt"; $msgRecap = $this->obtenirMessageRecap(); $messagerie->envoyerTxt($this->testeurCourriel, $sujet, $msgRecap); $sujet = "TESTEUR : HTML - obs du $dateFmt"; $messagerie->envoyerHtml($this->testeurCourriel, $sujet, $this->messageHtml, $this->messageTxt); $sujet = "TESTEUR : TXT - obs du $dateFmt"; $messagerie->envoyerTxt($this->testeurCourriel, $sujet, $this->messageTxt); } } }