* @license GPL v3 * @license CECILL v2 * @version $Id$ * @copyright © 2011, Jean-Pascal MILCENT */ class CelWidgetSaisie extends CelMotCle { private $projet = null; private $tagsObs = null; private $tagsImg = null; private $utilisateur_id = null; const DUREE_DE_VIE_IMG = 86400;// 3600 * 24 * 2 = 172 800 const ARRET_SERVICE = false;// Permet de bloquer le service en cas de problème sur le serveur public function createElement($requeteDonnees) { if (self::ARRET_SERVICE) { $this->messages[] = "Désactivation temporaire du service d'envoi des données au CEL."; } else if (array_key_exists('projet', $requeteDonnees)) { $this->debug[] = 'Projet : ok'; $this->projet = $requeteDonnees['projet']; if (array_key_exists('tag-obs', $requeteDonnees) && $requeteDonnees['tag-obs'] != '') { $this->tagsObs = explode(',', $requeteDonnees['tag-obs']); } $this->tagsObs[] = 'Projets coopératifs>'.$this->projet; if (array_key_exists('tag-img', $requeteDonnees) && $requeteDonnees['tag-img'] != '') { $this->tagsImg = explode(',', $requeteDonnees['tag-img']); } $this->tagsImg[] = 'Projets coopératifs>'.$this->projet; if (array_key_exists('utilisateur', $requeteDonnees)) { $this->debug[] = 'Utilisateur : ok'; $utilisateur = $requeteDonnees['utilisateur']; if (array_key_exists('courriel', $utilisateur)) { $this->debug[] = 'Courriel : ok'; extract($utilisateur); $this->utilisateur_id = $courriel; $ordre = $this->getMaxOrdre($courriel); if (!is_null($ordre)) { $requeteDonnees = $this->supprimerSlashesProfond($requeteDonnees); // Triage et manipulation des données $observations = array(); foreach ($requeteDonnees as $cle => $obs) { if (preg_match('/^obsId[0-9]+$/', $cle)) { $idObs = $ordre++; $this->debug[] = 'commune_nom : '.$obs['commune_nom']; $this->debug[] = 'commune_code_insee : '.$obs['commune_code_insee']; $obsAAjouter = array(); $obsAAjouter['identifiant'] = $courriel; $obsAAjouter['prenom_utilisateur'] = $prenom; $obsAAjouter['nom_utilisateur'] = $nom; $obsAAjouter['ordre'] = $idObs; $obsAAjouter['nom_sel'] = $obs['nom_sel']; $obsAAjouter['num_nom_sel'] = isset($obs['num_nom_sel']) ? $obs['num_nom_sel'] : null; $obsAAjouter['nom_ret'] = isset($obs['nom_ret']) ? $obs['nom_ret'] : null; $obsAAjouter['num_nom_ret'] = isset($obs['num_nom_ret']) ? $obs['num_nom_ret'] : null; $obsAAjouter['num_taxon'] = isset($obs['num_taxon']) ? $obs['num_taxon'] : null; $obsAAjouter['famille'] = isset($obs['famille']) ? $obs['famille'] : null; $obsAAjouter['nom_referentiel'] = isset($obs['referentiel']) ? $obs['referentiel'] : null; $obsAAjouter['date_observation'] = $this->transormerDateFrVersMysql($obs['date']); $obsAAjouter['commentaire'] = $obs['notes']; $obsAAjouter['location'] = $obs['commune_nom']; $obsAAjouter['id_location'] = substr($obs['commune_code_insee'], 0, 2); $obsAAjouter['lieudit'] = isset($obs['lieudit']) ? $obs['lieudit'] : null; $obsAAjouter['station'] = isset($obs['station']) ? $obs['station'] : null; $obsAAjouter['milieu'] = $obs['milieu']; $obsAAjouter['coord_x'] = $obs['latitude']; $obsAAjouter['coord_y'] = $obs['longitude']; $obsAAjouter['ref_geo'] = 'WGS84'; $obsAAjouter['transmission'] = '1'; $obsAAjouter['date_creation'] = date('Y-m-d H:i:s'); $obsAAjouter['date_modification'] = $obsAAjouter['date_creation']; $obsAAjouter['date_transmission'] = $obsAAjouter['date_creation']; $imgAAjouter = null; if (!empty($obs['image_nom'])) { $imgAAjouter = array(); $imgAAjouter['id_utilisateur'] = $courriel; $imgAAjouter['id_obs'] = $idObs; $imgAAjouter['nom'] = $obs['image_nom']; $imgAAjouter['b64'] = $obs['image_b64']; $this->debug[] = 'Contient B64 : '.(empty($obs['image_b64']) ? 'non' : 'oui'); } $observations[$idObs] = array( 'obs' => $this->protegerTableau($obsAAjouter), 'img' => $imgAAjouter); } } $this->debug[] = 'Nbre obs ajoutée : '.count($observations); // Insertion dans la base $obs_a_taguer_ordres = array(); $img_a_taguer_ids = array(); foreach ($observations as $infos) { $obs = $infos['obs']; $img = $infos['img']; // si le formulaire contient une image on la traite if ($img != null) { $this->nettoyerImagesUploades(); $nomFichierImg = $this->traiterNomFichierImage($img['nom']); $cheminImage = $this->config['cel_db']['chemin_stockage_temp']."/$nomFichierImg"; // Si l'image est transmise en base 64 if (empty($img['b64']) === false) { $this->transformerBase64enFichier($cheminImage, $img['b64']); } $this->debug[] = 'Nom fichier img debut :'.$nomFichierImg; $idImg = $this->ajouterImageSurDdEtBdd($img['id_utilisateur'], $cheminImage, $nomFichierImg); if ($idImg !== false) { $liaisonOk = $this->lierObsEtImg($idImg, $img['id_utilisateur'], $img['id_obs']); if ($liaisonOk === true) { $img_a_taguer_ids[] = $idImg; } } } $champs = implode(', ', array_keys($obs)); $valeurs = implode(', ', $obs); $requete = "INSERT INTO cel_inventory ($champs) VALUES ($valeurs) "; if ($this->executerRequeteSimple($requete) === false) { $this->messages[] = "Un problème est survenu lors de l'insertion de l'obs dans la base de données."; } else { $obs_a_taguer_ordres[] = trim($obs['ordre'], "'"); } } $this->taguerObs($obs_a_taguer_ordres); $this->taguerImg($img_a_taguer_ids); } else { $this->messages[] = "Un nouveau numéro d'ordre d'observation n'a pu être généré."; } } else { $this->messages[] = "L'identifiant de l'utilisateur (courriel) n'a pas été transmis."; } } else { $this->messages[] = "Les informations concernant l'utilisateur (prénom, nom, courriel) n'ont pas été transmises."; } } else { $this->messages[] = "Les informations concernant le projet coopératif n'ont pas été transmises."; } $msg = (count($this->messages) > 0) ? 'erreur' : 'ok'; $retour = (object) array('msg' => $msg); $this->envoyerJson($retour); } private function supprimerSlashesProfond($valeur) { $valeur = is_array($valeur) ? array_map(array($this, 'supprimerSlashesProfond'), $valeur) : stripslashes($valeur); return $valeur; } private function getMaxOrdre($identifiant) { $ordre = null; $identifiant = $this->bdd->quote($identifiant); $requete = "SELECT MAX(ordre) AS ordre ". "FROM cel_inventory ". "WHERE identifiant = $identifiant "; $ordre_max = $this->executerRequete($requete, 'Column'); if ($ordre_max !== false) { $ordre = $ordre_max + 1; } return $ordre; } /** * Transforme une date au format français (jj/mm/aaaa) dans un format Mysql (aaaa-mm-jj). * @param string $dateFr date au format français (jj/mm/aaaa) * @return string date au format Mysql (aaaa-mm-jj) */ private function transormerDateFrVersMysql($dateFr) { $dateMysql = '0000-00-00'; $morceauxDate = explode('/', $dateFr); if (count($morceauxDate) == 3) { $dateMysql = implode('-', array_reverse($morceauxDate)); } return $dateMysql; } private function taguerObs($obs_a_taguer_ordres) { if (count($obs_a_taguer_ordres) > 0) { foreach ($this->tagsObs as $hierarchieTag) { $tagsALier = explode('>', $hierarchieTag); $liaisonOk = $this->lierObsAMotsCles($obs_a_taguer_ordres, $tagsALier); if ($liaisonOk === false) { $e = "Toutes les observations n'ont pas pu être liées aux mots-clés : $hierarchieTag"; $this->messages[] = $e; } } } } private function lierObsAMotsCles($observations_ordres, $tags) { $idTagParent = self::OBS_RACINE_ID; $listeIdsTags = array(); foreach ($tags as $tag) { $tag = $this->nettoyerTag($tag); if ($tag != '') { $id_mot_cle = $this->ajouterMotCleObs($this->utilisateur_id, $tag, $idTagParent); if ($id_mot_cle !== false) { $listeIdsTags[] = $id_mot_cle; $idTagParent = $id_mot_cle; } } } $liaison_ok = $this->lierMotCleObs($this->utilisateur_id, $listeIdsTags, $observations_ordres); return $liaison_ok; } private function taguerImg($img_a_taguer_ids) { if (count($img_a_taguer_ids) > 0) { $this->debug[] = "Tags img : ".print_r($this->tagsImg, true); foreach ($this->tagsImg as $hierarchieTag) { $tagsALier = explode('>', $hierarchieTag); $liaisonOk = $this->lierImgAMotsCles($img_a_taguer_ids, $tagsALier); if ($liaisonOk === false) { $e = "Toutes les images n'ont pas pu être liées aux mots-clés : $hierarchieTag"; $this->messages[] = $e; } } } } private function lierImgAMotsCles($images_ids, $tags) { $idTagParent = self::IMG_RACINE_ID; $listeIdsTags = array(); foreach ($tags as $tag) { $tag = $this->nettoyerTag($tag); if ($tag != '') { $id_mot_cle = $this->ajouterMotCleImg($this->utilisateur_id, $tag, $idTagParent); if ($id_mot_cle !== false) { $listeIdsTags[] = $id_mot_cle; $idTagParent = $id_mot_cle; } } } $liaison_ok = $this->lierMotCleImg($this->utilisateur_id, $listeIdsTags, $images_ids); return $liaison_ok; } private function nettoyerTag($tag) { $tag = trim($tag); $tag = preg_replace('/(?:\s+|[,]+)/', ' ', $tag); return $tag; } private function traiterNomFichierImage($fichierNom) { $fichierNom = preg_replace('/[.](jpeg|jpg)$/i', '.jpg', strtolower(trim($fichierNom))); return $fichierNom; } /** * Décode l'image en base64,enregistre celle-ci sous forme de fichier du type de l'image * dans un dossier temporaire. */ private function transformerBase64enFichier($cheminImage, $imageInfosB64) { // Enleve la partie data:image qui permet la previsalisation pour firefox de l'image en base64 $imageBase64 = explode(';', $imageInfosB64); $dataBase64 = explode(',',$imageBase64[1]); $dataImg = base64_decode($dataBase64[1]); $imageRessource = fopen($cheminImage, 'wb'); fwrite($imageRessource, $dataImg); fclose($imageRessource); if (file_exists($cheminImage) == false) { $this->messages[] = "Erreur lors de la création du fichier"; } } public function lierObsEtImg($id_image, $id_utilisateur, $id_obs) { $id_image = $this->proteger($id_image); $id_utilisateur = $this->proteger($id_utilisateur); $id_obs = $this->proteger($id_obs); $requete = 'INSERT INTO cel_obs_images '. ' (coi_ce_image, coi_ce_utilisateur, coi_ce_observation, coi_date_liaison) '. "VALUES ($id_image, $id_utilisateur, $id_obs, NOW()) ". ' ON DUPLICATE KEY UPDATE coi_ce_image = coi_ce_image'; $liaison = true; if ($this->executerRequeteSimple($requete) === false) { $this->messages[] = "La requête de liaison de l'obs $id_obs à l'image $id_image pour l'utilisateur $id_utilisateur a échouée."; $liaison = false; } return $liaison; } public function nettoyerImagesUploades() { $dossierStockage = $this->config['cel_db']['chemin_stockage_temp'].'/'; if (is_dir($dossierStockage)) { $objets = scandir($dossierStockage); if ($objets !== false) { foreach ($objets as $objet) { $chemin = $dossierStockage.$objet; if (is_file($chemin)) { $filemtime = @filemtime($chemin); if ($filemtime !== false) { $suppression = (time() - $filemtime >= self::DUREE_DE_VIE_IMG) ? true : false; if ($suppression === true) { unlink($chemin); } } } } } } } /** * Ajoute une image dans la base de données et stocke le fichier en fabriquant les miniatures, * renvoie le nouvel id d'image en cas de succès * * @param string $idUtilisateur l'identifiant de l'utilisateur * @param string $cheminImage le chemin vers le fichier original de l'image * @param string $nomFichierImage le nom du fichier original de l'image */ public function ajouterImageSurDdEtBdd($idUtilisateur, $cheminImage, $nomFichierImage) { $idImage = false; $nouvelOrdre = $this->obtenirNouvelOrdrePourUtilisateur($idUtilisateur); if ($nouvelOrdre !== false) { if (file_exists($cheminImage)) { $extracteurMetadonnees = new ExtracteurMetadonnees(); $metadonnees = $extracteurMetadonnees->extraireMetadonnees($cheminImage) ; if ($metadonnees !== false) { $infosImage = $metadonnees; $infosImage['ci_ordre'] = $nouvelOrdre; $infosImage['ci_publiable_eflore'] = 'false'; $infosImage['ci_nom_original'] = $nomFichierImage; $infosImage['ci_ce_utilisateur'] = $idUtilisateur; $infosImage['ci_md5'] = md5_file($cheminImage); $this->debug[] = 'Nom fichier img meta :'.$nomFichierImage; $requete = $this->construireRequeteInsertionImage($infosImage); $resultat = $this->executerRequeteSimple($requete); if ($resultat !== false) { $idImage = $this->obtenirIdImagePourIdentifiantEtOrdre($idUtilisateur, $nouvelOrdre); if ($idImage !== false) { $manipulateurImage = new ImageRecreation($this->config); $stockageOk = $manipulateurImage->stockerFichierEtCreerMiniatures($cheminImage, $idImage); if ($stockageOk) { $miniatureChemin = str_replace('.jpg', '_min.jpg', $cheminImage); if (file_exists($miniatureChemin)) { if (@unlink($miniatureChemin) === false) { $this->messages[] = "La miniature de l'image n'a pu être supprimée."; } } } else { $this->messages[] = "Une erreur s'est produite lors du stockage du fichier."; } } else { $this->messages[] = "Impossible d'obtenir le nouvel identifiant de l'image"; } } else { $this->messages[] = "Echec de l'insertion dans la base de donnees des informations de l'image."; } } else { $this->messages[] = "Erreur lors de l'extraction des metadonnées."; } } else { $this->messages[] = "L'image originale est introuvable sur le serveur."; } } else { $this->messages[] = "Erreur lors du calcul du nouvel ordre de l'image."; } return $idImage; } private function obtenirNouvelOrdrePourUtilisateur($id_utilisateur) { $id_utilisateur = $this->proteger($id_utilisateur); $requete = 'SELECT MAX(ci_ordre) as max_ordre '. 'FROM cel_images '. "WHERE ci_ce_utilisateur = $id_utilisateur "; $resultat = $this->executerRequete($requete); $ordre = ($resultat) ? ++$resultat[0]['max_ordre'] : 0; return $ordre; } private function obtenirIdImagePourIdentifiantEtOrdre($id_utilisateur, $ordre) { $id_utilisateur = $this->proteger($id_utilisateur); $ordre = $this->proteger($ordre); $requete = 'SELECT ci_id_image '. 'FROM cel_images '. "WHERE ci_ce_utilisateur = $id_utilisateur ". " AND ci_ordre = $ordre "; $resultat = $this->executerRequete($requete); $id_image = (count($resultat) > 0) ? $resultat[0]['ci_id_image'] : false; return $id_image; } private function construireRequeteInsertionImage($informations) { $champs = array('ci_meta_date_ajout'); $valeurs = array('CURRENT_TIMESTAMP()'); foreach ($informations as $champ => $valeur) { $champs[] = $champ; $valeurs[] = is_null($valeur) ? 'NULL' : $this->proteger($valeur); if ($champ == 'ci_meta_date_time' && $valeur != 'NULL') { $champs[] = 'ci_meta_date'; $valeurs[] = $this->proteger($valeur); } } $champs = implode(', ', $champs); $valeurs = implode(', ', $valeurs); $requete = "INSERT INTO cel_images ($champs) VALUES ($valeurs) "; return $requete; } } ?>