/branches/v5.8-seynes/widget/.htaccess |
---|
New file |
0,0 → 1,13 |
<files *.ini> |
order deny,allow |
deny from all |
</files> |
#AddHandler x-httpd-php5 .php |
AddDefaultCharset UTF-8 |
RewriteEngine On |
# Redirections générale vers le fichier principal de Widget. |
RewriteCond %{REQUEST_FILENAME} !-d |
RewriteCond %{REQUEST_FILENAME} !-f |
RewriteRule ^.*$ index.php/ |
/branches/v5.8-seynes/widget/bibliotheque/WidgetCommun.php |
---|
New file |
0,0 → 1,431 |
<?php |
abstract class WidgetCommun { |
protected $config = null; |
protected $parametres = null; |
protected $messages = array(); |
protected $debug = array(); |
public function __construct($config, $parametres) { |
$this->config = $config; |
$this->parserFichierIni($config['chemins']['widgetCourantDossier'].'config.ini'); |
$this->parametres = $parametres; |
} |
/** |
* Parse le fichier ini donné en paramètre |
* @param string $fichier_ini nom du fichier ini à parser |
* @return boolean true si le fichier ini a été trouvé. |
*/ |
private function parserFichierIni($fichier_ini) { |
$retour = false; |
if (file_exists($fichier_ini)) { |
$ini = parse_ini_file($fichier_ini, true); |
$this->fusionner($ini); |
$retour = true; |
} |
return $retour; |
} |
/** |
* fusionne un tableau de paramètres avec le tableau de config global |
* @param array $ini le tableau à fusionner |
*/ |
private function fusionner(array $ini) { |
$this->config = array_merge($this->config, $ini); |
} |
protected function traiterNomMethodeExecuter($nom) { |
$methode = 'executer'; |
$methode .= str_replace(' ', '', ucwords(str_replace('-', ' ', strtolower($nom)))); |
return $methode; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION des CLASSES CHARGÉES à la DEMANDE |
protected function getDao() { |
if (! isset($this->dao)) { |
$this->dao = new Dao(); |
} |
return $this->dao; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION DE MÉTHODES COMMUNES ENTRE LES SERVICES |
protected function getUrlImage($id, $format = 'L') { |
$url_tpl = $this->config['chemins']['celImgUrlTpl']; |
$id = sprintf('%09s', $id).$format; |
$url = sprintf($url_tpl, $id); |
return $url; |
} |
protected function encoderMotCle($mot_cle) { |
return md5(mb_strtolower($mot_cle)); |
} |
private function protegerMotsCles($mots_cles, $type) { |
$separateur = ($type == self::TYPE_IMG) ? ',' : ';' ; |
$mots_cles_a_proteger = explode($separateur,rtrim(trim($mots_cles), $separateur)); |
foreach ($mots_cles_a_proteger as $mot) { |
$mots_cles_proteges[] = $this->bdd->quote($mot); |
} |
$mots_cles = implode(',', $mots_cles_proteges); |
return $mots_cles; |
} |
protected function tronquerCourriel($courriel) { |
$courriel = preg_replace('/[^@]+$/i', '...', $courriel); |
return $courriel; |
} |
protected function nettoyerTableau($tableau) { |
foreach ($tableau as $cle => $valeur) { |
if (is_array($valeur)) { |
$valeur = $this->nettoyerTableau($valeur); |
} else { |
$valeur = $this->nettoyerTexte($valeur); |
} |
$tableau[$cle] = $valeur; |
} |
return $tableau; |
} |
protected function nettoyerTexte($txt) { |
$txt = preg_replace('/&(?!([a-z]+|#[0-9]+|#x[0-9][a-f]+);)/i', '&', $txt); |
$txt = preg_replace('/^(?:000null|null)$/i', '', $txt); |
return $txt; |
} |
protected function etreVide($valeur) { |
$vide = false; |
if ($valeur == '' || $valeur == 'null'|| $valeur == '000null' || $valeur == '0') { |
$vide = true; |
} |
return $vide; |
} |
protected function formaterDate($date_heure_mysql, $format = '%A %d %B %Y à %H:%M') { |
$date_formatee = ''; |
if (!$this->etreVide($date_heure_mysql)) { |
$timestamp = $this->convertirDateHeureMysqlEnTimestamp($date_heure_mysql); |
$date_formatee = strftime($format, $timestamp); |
} |
return $date_formatee; |
} |
protected function convertirDateHeureMysqlEnTimestamp($date_heure_mysql){ |
$val = explode(' ', $date_heure_mysql); |
$date = explode('-', $val[0]); |
$heure = explode(':', $val[1]); |
return mktime((int) $heure[0], (int) $heure[1], (int) $heure[2], (int) $date[1], (int) $date[2], (int) $date[0]); |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION DE L'IDENTIFICATION et des UTILISATEURS |
protected function getAuthIdentifiant() { |
$id = (isset($_SERVER['PHP_AUTH_USER'])) ? $_SERVER['PHP_AUTH_USER'] : null; |
return $id; |
} |
protected function getAuthMotDePasse() { |
$mdp = (isset($_SERVER['PHP_AUTH_PW'])) ? $_SERVER['PHP_AUTH_PW'] : null; |
return $mdp; |
} |
protected function authentifierAdmin() { |
$message_accueil = "Veuillez vous identifier avec votre compte Tela Botanica."; |
$message_echec = "Accès limité aux administrateurs du CEL.\n". |
"Votre tentative d'identification a échoué.\n". |
"Actualiser la page pour essayer à nouveau si vous êtes bien inscrit comme administrateur."; |
return $this->authentifier($message_accueil, $message_echec, 'Admin'); |
} |
protected function authentifierUtilisateur() { |
$message_accueil = "Veuillez vous identifier avec votre compte Tela Botanica."; |
$message_echec = "Accès limité aux utilisateur du CEL.\n". |
"Inscrivez vous http://www.tela-botanica.org/page:inscription pour le devenir.\n". |
"Votre tentative d'identification a échoué.\n". |
"Actualiser la page pour essayer à nouveau si vous êtes déjà inscrit ou contacter 'accueil@tela-botanica.org'."; |
return $this->authentifier($message_accueil, $message_echec, 'Utilisateur'); |
} |
private function authentifier($message_accueil, $message_echec, $type) { |
$id = $this->getAuthIdentifiant(); |
if (!isset($id)) { |
$this->envoyerAuth($message_accueil, $message_echec); |
} else { |
if ($type == 'Utilisateur' && $this->getAuthMotDePasse() == 'debug') { |
$autorisation = true; |
} else { |
$methodeAutorisation = "etre{$type}Autorise"; |
$autorisation = $this->$methodeAutorisation(); |
} |
if ($autorisation == false) { |
$this->envoyerAuth($message_accueil, $message_echec); |
} |
} |
return true; |
} |
protected function etreUtilisateurAutorise() { |
$identifiant = $this->getAuthIdentifiant(); |
$mdp = md5($this->getAuthMotDePasse()); |
$url = sprintf($this->config['authentification']['serviceUrlTpl'], $identifiant, $mdp); |
$json = $this->getDao()->consulter($url); |
$existe = json_decode($json); |
$autorisation = (isset($existe) && $existe) ? true :false; |
return $autorisation; |
} |
protected function etreAdminAutorise($identifiant) { |
$identifiant = $this->getAuthIdentifiant(); |
$autorisation = ($this->etreUtilisateurAutorise() && $this->etreAdminCel($identifiant)) ? true : false; |
return $autorisation; |
} |
protected function etreAdminCel($courriel) { |
$admins = $this->config['authentification']['administrateurs']; |
$courriels_autorises = explode(',', $admins); |
$autorisation = (in_array($courriel, $courriels_autorises)) ? true : false ; |
return $autorisation; |
} |
/** |
* Prend en paramêtre un tableau de courriels et retourne après avoir intérogé un service we de l'annuaire |
* une tableau avec en clé le courriel et en valeur, un tableau associatif : |
* - nom : le nom de l'utilisateur |
* - prenom : le prénom de l'utilisateur. |
* @param array $courriels un tableau de courriels pour lesquels il faut recherche le prénom et nom. |
*/ |
protected function recupererUtilisateursNomPrenom(Array $courriels) { |
// Récupération des données au format Json |
$service = "utilisateur/prenom-nom-par-courriel/".implode(',', $courriels); |
$url = sprintf($this->config['chemins']['baseURLServicesAnnuaireTpl'], $service); |
$json = $this->getDao()->consulter($url); |
return (array) json_decode($json); |
} |
protected function recupererUtilisateursIdentite(Array $courriels) { |
// Récupération des données au format Json |
$service = "utilisateur/identite-par-courriel/".implode(',', $courriels); |
$url = sprintf($this->config['chemins']['baseURLServicesAnnuaireTpl'], $service); |
$json = $this->getDao()->consulter($url); |
$utilisateurs = json_decode($json); |
foreach ($courriels as $courriel) { |
$info = array('id' => null, 'intitule' => ''); |
if (isset($utilisateurs->$courriel)) { |
$info['intitule'] = $utilisateurs->$courriel->intitule; |
$info['id'] = $utilisateurs->$courriel->id; |
} else { |
$info['intitule'] = $this->tronquerCourriel($courriel); |
} |
$noms[$courriel] = $info; |
} |
return $noms; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION de l'ENVOIE au NAVIGATEUR |
protected function envoyerJsonp($donnees = null, $encodage = 'utf-8') { |
$contenu = $_GET['callback'].'('.json_encode($donnees).');'; |
$this->envoyer($contenu, 'text/html', $encodage); |
} |
protected function envoyer($donnees = null, $mime = 'text/html', $encodage = 'utf-8') { |
// Traitements des messages d'erreurs et données |
if (count($this->messages) != 0) { |
header('HTTP/1.1 500 Internal Server Error'); |
$mime = 'text/html'; |
$encodage = 'utf-8'; |
$sortie = '<html>'. |
'<head><title>Messages</title></head>'. |
'<body><pre>'.implode("\n", $this->messages).'</pre><body>'. |
'</html>'; |
} else { |
$sortie = $donnees; |
if (is_null($donnees)) { |
$sortie = 'OK'; |
} |
} |
// Gestion de l'envoie du déboguage |
$this->envoyerDebogage(); |
// Envoie sur la sortie standard |
$this->envoyerContenu($encodage, $mime, $sortie); |
} |
private function envoyerDebogage() { |
if (!is_array($this->debug)) { |
$this->debug[] = $this->debug; |
} |
if (count($this->debug) != 0) { |
foreach ($this->debug as $cle => $val) { |
if (is_array($val)) { |
$this->debug[$cle] = print_r($val, true); |
} |
} |
header('X-DebugJrest-Data:'.json_encode($this->debug)); |
} |
} |
private function envoyerContenu($encodage, $mime, $contenu) { |
if (!is_null($mime) && !is_null($encodage)) { |
header("Content-Type: $mime; charset=$encodage"); |
} else if (!is_null($mime) && is_null($encodage)) { |
header("Content-Type: $mime"); |
} |
print_r($contenu); |
} |
private function envoyerAuth($message_accueil, $message_echec) { |
header('HTTP/1.0 401 Unauthorized'); |
header('WWW-Authenticate: Basic realm="'.mb_convert_encoding($message_accueil, 'ISO-8859-1', 'UTF-8').'"'); |
header('Content-type: text/plain; charset=UTF-8'); |
print $message_echec; |
exit(0); |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION DES SQUELETTES (PHP, TXT...) |
/** |
* Méthode prenant en paramètre un tableau associatif, les clés seront recherchées dans le texte pour être |
* remplacer par la valeur. Dans le texte, les clés devront être entre accolades : {} |
* |
* @param String $txt le texte où chercher les motifs. |
* @param Array $donnees un tableau associatif contenant les motifs à remplacer. |
* |
* @return String le texte avec les motifs remplacer par les valeurs du tableau. |
*/ |
protected static function traiterSqueletteTxt($txt, Array $donnees = array()) { |
$motifs = array(); |
$valeurs = array(); |
foreach ($donnees as $cle => $valeur) { |
if (strpos($cle, '{') === false && strpos($cle, '}') === false) { |
$motifs = '{'.$cle.'}'; |
$valeurs = $valeur; |
} |
} |
$txt = str_replace($motifs, $valeurs, $txt); |
return $txt; |
} |
/** |
* Méthode prenant en paramètre un chemin de fichier squelette et un tableau associatif de données, |
* en extrait les variables, charge le squelette et retourne le résultat des deux combinés. |
* |
* @param String $fichier le chemin du fichier du squelette |
* @param Array $donnees un tableau associatif contenant les variables a injecter dans le squelette. |
* |
* @return boolean false si le squelette n'existe pas, sinon la chaine résultat. |
*/ |
protected static function traiterSquelettePhp($fichier, Array $donnees = array()) { |
$sortie = false; |
if (file_exists($fichier)) { |
// Extraction des variables du tableau de données |
extract($donnees); |
// Démarage de la bufferisation de sortie |
ob_start(); |
// Si les tags courts sont activés |
if ((bool) @ini_get('short_open_tag') === true) { |
// Simple inclusion du squelette |
include $fichier; |
} else { |
// Sinon, remplacement des tags courts par la syntaxe classique avec echo |
$html_et_code_php = self::traiterTagsCourts($fichier); |
// Pour évaluer du php mélangé dans du html il est nécessaire de fermer la balise php ouverte par eval |
$html_et_code_php = '?>'.$html_et_code_php; |
// Interprétation du html et du php dans le buffer |
echo eval($html_et_code_php); |
} |
// Récupèration du contenu du buffer |
$sortie = ob_get_contents(); |
// Suppression du buffer |
@ob_end_clean(); |
} else { |
$msg = "Le fichier du squelette '$fichier' n'existe pas."; |
trigger_error($msg, E_USER_WARNING); |
} |
// Retourne le contenu |
return $sortie; |
} |
/** |
* Fonction chargeant le contenu du squelette et remplaçant les tags court php (<?= ...) par un tag long avec echo. |
* |
* @param String $chemin_squelette le chemin du fichier du squelette |
* |
* @return string le contenu du fichier du squelette php avec les tags courts remplacés. |
*/ |
private static function traiterTagsCourts($chemin_squelette) { |
$contenu = file_get_contents($chemin_squelette); |
// Remplacement de tags courts par un tag long avec echo |
$contenu = str_replace('<?=', '<?php echo ', $contenu); |
// Ajout systématique d'un point virgule avant la fermeture php |
$contenu = preg_replace("/;*\s*\?>/", "; ?>", $contenu); |
return $contenu; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// UTILITAIRES |
/** |
* Permet de trier un tableau multi-dimenssionnel en gardant l'ordre des clés. |
* |
* @param Array $array le tableau à trier |
* @param Array $cols tableau indiquant en clé la colonne à trier et en valeur l'ordre avec SORT_ASC ou SORT_DESC |
* @author cagret at gmail dot com |
* @see http://fr.php.net/manual/fr/function.array-multisort.php Post du 21-Jun-2009 12:38 |
*/ |
public static function trierTableauMd($array, $cols) { |
$colarr = array(); |
foreach ($cols as $col => $order) { |
$colarr[$col] = array(); |
foreach ($array as $k => $row) { |
$colarr[$col]['_'.$k] = strtolower(self::supprimerAccents($row[$col])); |
} |
} |
$params = array(); |
foreach ($cols as $col => $order) { |
$params[] =& $colarr[$col]; |
$params = array_merge($params, (array)$order); |
} |
call_user_func_array('array_multisort', $params); |
$ret = array(); |
$keys = array(); |
$first = true; |
foreach ($colarr as $col => $arr) { |
foreach ($arr as $k => $v) { |
if ($first) { |
$keys[$k] = substr($k,1); |
} |
$k = $keys[$k]; |
if (!isset($ret[$k])) { |
$ret[$k] = $array[$k]; |
} |
$ret[$k][$col] = $array[$k][$col]; |
} |
$first = false; |
} |
return $ret; |
} |
private static function supprimerAccents($str, $charset='utf-8') |
{ |
$str = htmlentities($str, ENT_NOQUOTES, $charset); |
$str = preg_replace('#&([A-za-z])(?:acute|cedil|circ|grave|orn|ring|slash|th|tilde|uml);#', '\1', $str); |
$str = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $str); // pour les ligatures e.g. 'œ' |
$str = preg_replace('#&[^;]+;#', '', $str); // supprime les autres caractères |
return $str; |
} |
} |
?> |
/branches/v5.8-seynes/widget/bibliotheque/Dao.php |
---|
New file |
0,0 → 1,155 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Classe modèle spécifique à l'application, donc d'accés au données, elle ne devrait pas être appelée de l'extérieur. |
* |
* @category php5 |
* @package Widget |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL |
* @version SVN: $Id$ |
*/ |
class Dao { |
const HTTP_URL_REQUETE_SEPARATEUR = '&'; |
const HTTP_URL_REQUETE_CLE_VALEUR_SEPARATEUR = '='; |
private $http_methodes = array('GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'CONNECT', 'TRACE'); |
protected $parametres = null; |
private $url = null; |
private $reponse_entetes = null; |
//+----------------------------------------------------------------------------------------------------------------+ |
// ACCESSEURS |
public function getReponseEntetes($cle) { |
return $this->reponse_entetes; |
} |
public function getParametre($cle) { |
$valeur = (isset($this->parametres[$cle])) ? $this->parametres[$cle] : null; |
return $valeur; |
} |
public function ajouterParametre($cle, $valeur) { |
$this->parametres[$cle] = $valeur; |
} |
public function supprimerParametre($cle) { |
unset($this->parametres[$cle]); |
} |
public function nettoyerParametres() { |
$this->parametres = null; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// MÉTHODES |
public function consulter($url) { |
$retour = $this->envoyerRequete($url, 'GET'); |
return $retour; |
} |
public function ajouter($url, Array $donnees) { |
$retour = $this->envoyerRequete($url, 'PUT', $donnees); |
return $retour; |
} |
public function modifier($url, Array $donnees) { |
$retour = $this->envoyerRequete($url, 'POST', $donnees); |
return $retour; |
} |
public function supprimer($url) { |
$retour = $this->envoyerRequete($url, 'DELETE'); |
return $retour; |
} |
public function envoyerRequete($url, $mode, Array $donnees = array()) { |
$this->url = $url; |
$contenu = false; |
if (! in_array($mode, $this->http_methodes)) { |
$e = "Le mode de requête '$mode' n'est pas accepté!"; |
trigger_error($e, E_USER_WARNING); |
} else { |
if ($mode == 'GET') { |
$this->traiterUrlParametres(); |
} |
$contexte = stream_context_create(array( |
'http' => array( |
'method' => $mode, |
'header' => "Content-type: application/x-www-form-urlencoded\r\n", |
'content' => http_build_query($donnees, null, self::HTTP_URL_REQUETE_SEPARATEUR)))); |
$flux = @fopen($this->url, 'r', false, $contexte); |
if (!$flux) { |
$this->reponse_entetes = $http_response_header; |
$e = "L'ouverture de l'url '{$this->url}' par la méthode HTTP '$mode' a échoué!"; |
trigger_error($e, E_USER_WARNING); |
} else { |
// Informations sur les en-têtes et métadonnées du flux |
$this->reponse_entetes = stream_get_meta_data($flux); |
// Contenu actuel de $url |
$contenu = stream_get_contents($flux); |
fclose($flux); |
} |
$this->traiterEntete(); |
} |
$this->reinitialiser(); |
return $contenu; |
} |
private function traiterUrlParametres() { |
$parametres = array(); |
if (count($this->parametres) > 0) { |
foreach ($this->parametres as $cle => $valeur) { |
$cle = rawurlencode($cle); |
$valeur = rawurlencode($valeur); |
$parametres[] = $cle.self::HTTP_URL_REQUETE_CLE_VALEUR_SEPARATEUR.$valeur; |
} |
$url_parametres = implode(self::HTTP_URL_REQUETE_SEPARATEUR, $parametres); |
$this->url = $this->url.'?'.$url_parametres; |
} |
} |
private function traiterEntete() { |
$infos = $this->analyserEntete(); |
$this->traiterEnteteDebogage($infos); |
} |
private function analyserEntete() { |
$entetes = $this->reponse_entetes; |
$infos = array('date' => null, 'uri' => $this->url, 'debogages' => null); |
if (isset($entetes['wrapper_data'])) { |
$entetes = $entetes['wrapper_data']; |
} |
foreach ($entetes as $entete) { |
if (preg_match('/^X_REST_DEBOGAGE_MESSAGES: (.+)$/', $entete, $match)) { |
$infos['debogages'] = json_decode($match[1]); |
} |
if (preg_match('/^Date: .+ ([012][0-9]:[012345][0-9]:[012345][0-9]) .*$/', $entete, $match)) { |
$infos['date'] = $match[1]; |
} |
} |
return $infos; |
} |
private function traiterEnteteDebogage($entetes_analyses) { |
if (isset($entetes['debogages'])) { |
$date = $entetes['date']; |
$uri = $entetes['uri']; |
$debogages = $entetes['debogages']; |
foreach ($debogages as $debogage) { |
$e = "DEBOGAGE : $date - $uri :\n$debogage"; |
trigger_error($e, E_USER_NOTICE); |
} |
} |
} |
private function reinitialiser() { |
$this->nettoyerParametres(); |
} |
} |
/branches/v5.8-seynes/widget/index.php |
---|
New file |
0,0 → 1,5 |
<?php |
require 'Widget.php'; |
$widget = new Widget(); |
$widget->executer(); |
?> |
/branches/v5.8-seynes/widget/widget.ini.defaut.php |
---|
New file |
0,0 → 1,29 |
;<?/* |
[parametres] |
;Memoire maxi pour les services : 128Mo = 134217728 ; 256Mo = 268435456 ; 512Mo = 536870912 ; 1Go = 1073741824 |
limiteMemoire = "512M" |
; Niveau d'erreur PHP |
erreurNiveau = 30719 ; E_ALL = 30719 |
; Séparateur d'url en entrée |
argSeparatorInput = "&" |
; Indication de la locale (setLocale(LC_ALL, ?)) pour les classes appelées par Widget.php |
locale = "fr_FR.UTF-8" |
; Indication du fuseau horraire par défaut date_default_timezone_set(?)pour les classes appelées par Widget.php |
fuseauHoraire = "Europe/Paris" |
[chemins] |
; Chemins à utiliser dans la méthode autoload des widgets |
autoload = "bibliotheque/" |
; Dossier contenant les widgets |
widgetsDossier = "modules/" |
; Dossier contenant le widget demandé construit dynamiquement dans le fichier Widget.php |
widgetCourantDossier = "" |
; Dossier contenant les fichiers des bibliothèques tierces |
bibliothequeDossier = "bibliotheque/" |
; Base de l'url servant à appeler les widgets |
baseURL = "/eflore-consultation/widget/" |
; URL de base absolue des Widgets du CEL construit dynamiquement dans le fichier WidgetCommun.php |
baseURLAbsoluDyn = "" |
; URL des services web du CEL sous forme de template à utiliser avec sprintf |
baseURLServicesEfloreTpl = "http://localhost/service:eflore::0.1/%s" |
;*/?> |
/branches/v5.8-seynes/widget/modules/recherche/Recherche.php |
---|
New file |
0,0 → 1,105 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Service de recherche dans eflore, permettant d'intégrer le moteur dans une page donnée |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* Cas d'utilisation et documentation : |
* @link http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=AideEfloreWidgetRecherche |
* |
* |
* @author Aurélien PERONNET <aurelien@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright Copyright (c) 2013, Tela Botanica (accueil@tela-botanica.org) |
*/ |
class Recherche extends WidgetCommun { |
const DS = DIRECTORY_SEPARATOR; |
/** |
* Méthode appelée par défaut pour charger ce widget. |
*/ |
public function executer() { |
$retour = null; |
$this->extraireParametres(); |
$methode = $this->traiterNomMethodeExecuter("recherche"); |
if (method_exists($this, $methode)) { |
$retour = $this->$methode(); |
} else { |
$this->messages[] = "Ce type de service '$methode' n'est pas disponible."; |
} |
if (is_null($retour)) { |
$info = 'Un problème est survenu : '.print_r($this->messages, true); |
$this->envoyer($info); |
} else { |
$squelette = dirname(__FILE__).self::DS.'squelettes'.self::DS.$retour['squelette'].'.tpl.html'; |
$contenu = $this->traiterSquelettePhp($squelette, $retour['donnees']); |
if (isset($_GET['callback'])) { |
$this->envoyerJsonp(array('contenu' => $contenu)); |
} else { |
$this->envoyer($contenu); |
} |
} |
} |
public function extraireParametres() { |
extract($this->parametres); |
} |
public function executerRecherche() { |
$widget['donnees'] = array(); |
$widget['donnees']['efloreScriptUrl'] = $this->config['url']['efloreScriptUrl']; |
$widget['donnees']['efloreConsultationUrl'] = $this->config['url']['efloreConsultationUrl']; |
$widget['donnees']['efloreRechercheSciUrlTpl'] = $this->config['url']['efloreRechercheSciUrlTpl']; |
$widget['donnees']['efloreRechercheVernaUrlTpl'] = $this->config['url']['efloreRechercheVernaUrlTpl']; |
$widget['donnees']['ficheTaxonUrlTpl'] = $this->config['url']['ficheTaxonUrlTpl']; |
$widget['donnees']['referentielsSciDispos'] = $this->traiterReferentielSciDispos(); |
$widget['donnees']['referentielsConsultationUrls'] = $this->traiterUrlsConsultationReferentiels($widget['donnees']['referentielsSciDispos']); |
$widget['donnees']['referentielsVernasDispos'] = $this->traiterReferentielsSciVernasDispos(); |
$ref_sci_defaut = array_shift(array_keys($widget['donnees']['referentielsSciDispos'])); |
$ref_verna_defaut = $widget['donnees']['referentielsVernasDispos'][$ref_sci_defaut]; |
$widget['donnees']['efloreRechercheSciUrlDefaut'] = str_replace('{referentiel}', $ref_sci_defaut, $this->config['url']['efloreRechercheSciUrlTpl']); |
$widget['donnees']['efloreRechercheVernaUrlDefaut'] = str_replace('{referentiel}',$ref_verna_defaut, $this->config['url']['efloreRechercheVernaUrlTpl']); |
$widget['donnees']['ficheTaxonUrlTplDefaut'] = str_replace('{referentiel}', $ref_sci_defaut, $this->config['url']['ficheTaxonUrlTpl']); |
$widget['squelette'] = 'recherche'; |
return $widget; |
} |
private function traiterReferentielSciDispos() { |
$refs_sci_fmt = array(); |
$refs_sci = $this->config['referentiel']['referentielsSciDispos']; |
$refs_sci = explode(',', $refs_sci); |
foreach($refs_sci as $ref) { |
$ref_code_desc = explode('#', $ref); |
$refs_sci_fmt[$ref_code_desc[0]] = $ref_code_desc[1]; |
} |
return $refs_sci_fmt; |
} |
private function traiterReferentielsSciVernasDispos() { |
$refs_verna = $this->config['referentiel']['referentielsVernaDispos']; |
$refs_verna = explode(',', $refs_verna); |
$tab_refs_verna = array(); |
foreach($refs_verna as $ref_verna) { |
$ref_sci_a_verna = explode(":", $ref_verna); |
$tab_refs_verna[$ref_sci_a_verna[0]] = $ref_sci_a_verna[1]; |
} |
return $tab_refs_verna; |
} |
private function traiterUrlsConsultationReferentiels($referentiels) { |
$urls = array(); |
foreach($referentiels as $code_ref => $nom) { |
$config_url_ref = 'efloreConsultation'.ucwords($code_ref).'Url'; |
if(isset($this->config['url'][$config_url_ref])) { |
$urls[$code_ref] = $this->config['url'][$config_url_ref]; |
} else { |
$urls[$code_ref] = $this->config['url']['efloreConsultationUrl']; |
} |
} |
return $urls; |
} |
} |
?> |
/branches/v5.8-seynes/widget/modules/recherche/squelettes/exemple.tpl.html |
---|
New file |
0,0 → 1,15 |
<div id="recherche-eflore-1"> |
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/1.7.1/jquery-1.7.1.js"></script> |
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/jquery-ui/1.8.17/js/jquery-ui-1.8.17.custom.min.js"></script> |
<link xmlns:xh="http://www.w3.org/1999/xhtml/vocab#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" rel="xh:stylesheet stylesheet" href="http://localhost/eflore-consultation/presentations/styles/eflore.css" media="screen" type="text/css" /> |
<link xmlns:xh="http://www.w3.org/1999/xhtml/vocab#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" rel="xh:stylesheet stylesheet" href="http://localhost/eflore-consultation/widget/modules/recherche/squelettes/css/recherche.css" media="screen" type="text/css" /> |
<link href="http://www.tela-botanica.org/commun/jquery/jquery-ui/1.8.17/css/ui-lightness/jquery-ui-1.8.17.custom.css" rel="stylesheet" type="text/css" /> |
<script type="text/javascript"> |
$(document).ready(function() { |
$.getJSON("http://localhost/eflore-consultation/widget/recherche/?mode=ajax&callback=?", function (moteur) { |
$("#recherche-eflore-1").append(moteur.contenu); |
initialiser(); |
}); |
}); |
</script> |
</div> |
/branches/v5.8-seynes/widget/modules/recherche/squelettes/css/recherche.css |
---|
New file |
0,0 → 1,72 |
#conteneur-recherche { |
width: 660px; |
} |
#conteneur-recherche h1.titre-widget { |
margin-top: 5px; |
margin-bottom: 0px; |
color: black; |
background: none; |
} |
#conteneur-recherche { |
background-color: #FFFFFF; |
border-radius: 10px 10px 10px 10px; |
box-shadow: 1px 6px 6px 6px #C3C0AD; |
color: #3A3633; |
font-family: arial; |
font-size: 11px; |
margin: 10px 10px 20px; |
padding: 8px; |
} |
#conteneur-recherche h1 { |
font-size: 14px; |
} |
#conteneur-recherche h1.titre-widget { |
padding-left: 15px; |
} |
#conteneur-recherche .zone-choix-referentiel { |
padding: 3px; |
padding-bottom : 5px; |
padding-left: 10px; |
} |
#conteneur-recherche .label-referentiel { |
color: #FD8C13; |
font-weight: bold; |
letter-spacing: 0; |
padding: 0 0 0 5px; |
text-transform: uppercase; |
} |
#conteneur-recherche .selection-referentiel { |
background: none repeat scroll 0 0 white; |
cursor: pointer; |
height: 25px; |
} |
#conteneur-recherche .referentiel-selectionne { |
background-color: #EEE; |
border-color: #EB8F00; |
color: #C87A00; |
cursor: default; |
font-weight: bold; |
text-decoration: underline; |
height: 35px; |
} |
#ef-form-nomenclature label { |
display: inline; |
} |
#eflore_nomenclature_fiche { |
color: black; |
border-color: black; |
} |
.ef-groupe-champs { |
border: none; |
} |
/branches/v5.8-seynes/widget/modules/recherche/squelettes/recherche.tpl.html |
---|
New file |
0,0 → 1,95 |
<!-- DEBUT FORM_NOM --> |
<script type="text/javascript"> |
<!-- |
var AUTOCOMPLETION_ELEMENTS_NBRE = 50; |
var URL_SERVICE_AUTOCOMPLETION_NOM_SCI_TPL = "<?= $efloreRechercheSciUrlTpl; ?>"; |
var URL_SERVICE_AUTOCOMPLETION_NOM_VERNA_TPL = "<?= $efloreRechercheVernaUrlTpl; ?>"; |
var URL_BASE_FICHE_TAXON_TPL = "<?= $ficheTaxonUrlTpl; ?>"; |
var VALEUR_DEFAUT_NOM_SCI = "Saisir un nom scientifique (sans auteur)"; |
var VALEUR_DEFAUT_NOM_VERNA = "Saisir un nom commun"; |
var VALEUR_DEFAUT_AU = ""; |
var VALEUR_DEFAUT_BIB = ""; |
var VALEUR_DEFAUT_DATE = ""; |
var URL_BASE_FICHE_TAXON = "<?= $ficheTaxonUrlTplDefaut; ?>"; |
<?php $refs_urls = json_encode($referentielsConsultationUrls); ?> |
var REFERENTIELS_CONSULTATION_URLS = <?= $refs_urls; ?>; |
<?php $refs_verna = json_encode($referentielsVernasDispos); ?> |
var REFERENTIELS_VERNA_DISPOS = <?= $refs_verna; ?>; |
var URL_SERVICE_AUTOCOMPLETION_NOM_SCI = "<?= $efloreRechercheSciUrlDefaut; ?>"; |
var URL_SERVICE_AUTOCOMPLETION_NOM_VERNA = "<?= $efloreRechercheVernaUrlDefaut; ?>"; |
function gererVisibiliteSelecteurNom() { |
ref_sci = $(".selection-referentiel[disabled=disabled]").attr("name"); |
$("#eflore_nomenclature_referentiel").val(ref_sci); |
URL_SERVICE_AUTOCOMPLETION_NOM_SCI = URL_SERVICE_AUTOCOMPLETION_NOM_SCI_TPL.replace("{referentiel}", ref_sci); |
URL_BASE_FICHE_TAXON = REFERENTIELS_CONSULTATION_URLS[ref_sci]+URL_BASE_FICHE_TAXON_TPL.replace("{referentiel}", ref_sci); |
console.log(URL_BASE_FICHE_TAXON); |
if(REFERENTIELS_VERNA_DISPOS[ref_sci] != undefined) { |
URL_SERVICE_AUTOCOMPLETION_NOM_VERNA = URL_SERVICE_AUTOCOMPLETION_NOM_VERNA_TPL.replace("{referentiel}", REFERENTIELS_VERNA_DISPOS[ref_sci]); |
$("#type_nom_vernaculaire").parent().css("visibility","visible"); |
} else { |
$("#type_nom_vernaculaire").parent().css("visibility","hidden"); |
$("#type_nom_scientifique").attr('checked', 'checked'); |
$('#nom').val(); |
$('#nom').attr("placeholder", ""); |
} |
$('#ef-form-nomenclature').attr("action", REFERENTIELS_CONSULTATION_URLS[ref_sci]); |
} |
function mettreEnValeurReferentielSelectionne(bouton) { |
$(".selection-referentiel").removeAttr("disabled"); |
$(".selection-referentiel").removeClass("referentiel-selectionne"); |
bouton.attr("disabled","disabled"); |
bouton.addClass("referentiel-selectionne"); |
gererVisibiliteSelecteurNom(); |
} |
function initialiser() { |
$.getScript("<?= $efloreScriptUrl; ?>").done(function(script, textStatus) { |
// la fonction initialiserMoteur est la fonction d'initialisation du script de recherche tiré d'eflore |
// elle utilise les variable définies ci dessus, et elle est donc chargée après. |
initialiserMoteur(); |
$(".selection-referentiel").click(function () { |
mettreEnValeurReferentielSelectionne($(this)); |
}); |
mettreEnValeurReferentielSelectionne($($(".selection-referentiel")[0])); |
}); |
} |
// --> |
</script> |
<div class="importance1" id="conteneur-recherche"> |
<h1 class="titre-widget">Cherchez une plante de <span class="zone-choix-referentiel"> |
<?php $premier_ref = true; ?> |
<?php foreach($referentielsSciDispos as $code => $intitule) : ?> |
<span class="referentiel"> |
<input type="button" class="selection-referentiel" id="referentiel_<?= $code ?>" name="<?= $code; ?>" value="<?= $intitule; ?>" <?= $premier_ref ? 'disabled="disabled"' : ""; ?> /> |
</span> |
<?php $premier_ref = false; ?> |
<?php endforeach; ?> |
</span> </h1> |
<form id="ef-form-nomenclature" name="ef-form-nomenclature" action="<?= $efloreConsultationUrl; ?>" method="get"> |
<fieldset class="ef-groupe-champs"> |
<span class="zone-choix-type-nom"> |
<span class="type-nom"> |
<input type="radio" id="type_nom_scientifique" name="type_nom" value="nom_scientifique" checked="checked" /> |
<label for="type_nom_scientifique">Nom scientifique</label> |
</span> |
<span class="type-nom"> |
<input type="radio" id="type_nom_vernaculaire" name="type_nom" value="nom_vernaculaire" /> |
<label for="type_nom_vernaculaire" title="(en français, allemand, anglais, catalan, espagnol, italien ou néerlandais)">Nom commun</label> |
</span> |
</span> |
<input type="text" aria-haspopup="true" aria-autocomplete="list" role="textbox" autocomplete="off" id="nom" name="nom" class="champ ui-autocomplete-input" size="30" maxlength="255" /> |
<span id="zone-liens-recherche"> |
<input type="hidden" id="eflore_nomenclature_niveau" name="niveau" value="2" /> |
<input type="hidden" id="eflore_nomenclature_module" name="module" value="recherche" /> |
<input type="hidden" id="eflore_nomenclature_referentiel" name="referentiel" value="<?= array_shift(array_keys($referentielsSciDispos)); ?>" /> |
<input type="hidden" id="eflore_nomenclature_action" name="action" value="rechercheSimple" /> |
<input type="submit" id="eflore_nomenclature_submit" name="submit" value="OK" class="ok" /> |
<input type="submit" id="eflore_nomenclature_fiche" name="acces_fiche" value="Accès fiche" /> |
</span> |
</fieldset> |
</form> |
</div> |
<!-- FIN FORM_NOM --> |
/branches/v5.8-seynes/widget/modules/recherche/config.defaut.ini |
---|
New file |
0,0 → 1,15 |
[url] |
efloreScriptUrl = "http://www.tela-botanica.org/eflore/consultation/presentations/scripts/recherche.js" |
; url vers l'application utilisée par défaut |
efloreConsultationUrl = "http://www.tela-botanica.org/page:eflore" |
; url spécifique à un référentiel |
efloreConsultationBdtfxUrl = "http://www.tela-botanica.org/page:eflore_bdtfx" |
; url spécifique à un référentiel |
efloreConsultationBdtxaUrl = "http://www.tela-botanica.org/page:isfgm" |
efloreRechercheSciUrlTpl = "http://www.tela-botanica.org/service:eflore:0.1/{referentiel}/noms" |
efloreRechercheVernaUrlTpl = "http://www.tela-botanica.org/service:eflore:0.1/{referentiel}/noms-vernaculaires" |
ficheTaxonUrlTpl = "?referentiel={referentiel}&niveau=2&module=fiche&action=fiche&num_nom={num_taxon}&type_nom=nom_scientifique&nom=" |
[referentiel] |
referentielsSciDispos = bdtfx#France : métropole,bdtxa#France : Antilles,isfan#Afrique du Nord,apd#Afrique tropicale |
referentielsVernaDispos = bdtfx:nvjfl,bdtxa:nva |
/branches/v5.8-seynes/widget/modules/recherche |
---|
New file |
Property changes: |
Added: svn:ignore |
+config.ini |
/branches/v5.8-seynes/widget/Widget.php |
---|
New file |
0,0 → 1,161 |
<?php |
// In : utf8 url_encoded (get et post) |
// Out : utf8 |
/** |
* La classe Widget analyser l'url et chage le widget correspondant. |
* Format d'url : |
* /widget/nom_du_widget?parametres1=ma_valeur1¶metre2=ma_valeur2 |
* Les widget sont dans des dossiers en minuscule correspondant au nom de la classe du widget. |
* Exemple : /widget/carto avec la classe Carto.php dans le dossier carto. |
* |
* |
* @author jpm |
* |
*/ |
class Widget { |
/** Les paramètres de configuration extrait du fichier .ini */ |
private static $config; |
/** Le nom du widget demandé. */ |
private $widget = null; |
/** Les chemins où l'autoload doit chercher des classes. */ |
private static $autoload_chemins = array(); |
/** Les paramètres de l'url $_GET nettoyés. */ |
private $parametres = null; |
/** |
* Constructeur. |
* Parse le fichier de configuraion "widget.ini" et parse l'url à la recherche du widget demandé. |
* @param str iniFile Configuration file to use |
*/ |
public function __construct($fichier_ini = 'widget.ini.php') { |
// Chargement de la configuration |
self::$config = parse_ini_file($fichier_ini, TRUE); |
// Paramêtres de config dynamiques |
self::$config['chemins']['baseURLAbsoluDyn'] = 'http://'.$_SERVER['SERVER_NAME'].self::$config['chemins']['baseURL'].'%s'; |
// Gestion de la mémoire maximum allouée aux services |
ini_set('memory_limit', self::$config['parametres']['limiteMemoire']); |
// Réglages de PHP |
setlocale(LC_ALL, self::$config['parametres']['locale']); |
date_default_timezone_set(self::$config['parametres']['fuseauHoraire']); |
// Gestion des erreurs |
error_reporting(self::$config['parametres']['erreurNiveau']); |
if (isset($_SERVER['REQUEST_URI']) && isset($_SERVER['QUERY_STRING'])) { |
$url_morceaux = $this->parserUrl(); |
if (isset($url_morceaux[0])) { |
$this->widget = $url_morceaux[0]; |
self::$config['chemins']['widgetCourantDossier'] = self::$config['chemins']['widgetsDossier'].strtolower($this->widget).DIRECTORY_SEPARATOR; |
$this->chargerWidgetConfig(); |
} |
// Chargement des chemins pour l'autoload |
$this->chargerCheminAutoload(); |
// Enregistrement de la méthode gérant l'autoload des classes |
spl_autoload_register(array('Widget', 'chargerClasse')); |
// Nettoyage du $_GET (sécurité) |
$this->collecterParametres(); |
} else { |
$e = 'Les widget nécessite les variables serveurs suivantes pour fonctionner : REQUEST_URI et QUERY_STRING.'; |
trigger_error($e, E_USER_ERROR); |
} |
} |
private function parserUrl() { |
if (strlen($_SERVER['QUERY_STRING']) == 0) { |
$len = strlen($_SERVER['REQUEST_URI']); |
} else { |
$len = -(strlen($_SERVER['QUERY_STRING']) + 1); |
} |
$url = substr($_SERVER['REQUEST_URI'], strlen(self::$config['chemins']['baseURL']), $len); |
$url_morceaux = explode('/', $url); |
return $url_morceaux; |
} |
private function collecterParametres() { |
if (isset($_GET) && $_GET != '') { |
$this->nettoyerGet(); |
$this->parametres = $_GET; |
} |
} |
private function nettoyerGet() { |
foreach ($_GET as $cle => $valeur) { |
$verifier = array('NULL', "\n", "\r", "\\", '"', "\x00", "\x1a", ';'); |
$_GET[$cle] = strip_tags(str_replace($verifier, '', $valeur)); |
} |
} |
private function chargerCheminAutoload() { |
$chemins_communs = explode(';', self::$config['chemins']['autoload']); |
$chemins_communs = array_map('trim', $chemins_communs); |
array_unshift($chemins_communs, ''); |
$chemins_widget = array(); |
if (isset(self::$config[$this->widget]['autoload'])) { |
$chemins_widget = explode(';', self::$config[$this->widget]['autoload']); |
foreach ($chemins_widget as $cle => $chemin) { |
$chemins_widget[$cle] = self::$config['chemins']['widgetCourantDossier'].trim($chemin); |
} |
} |
self::$autoload_chemins = array_merge($chemins_communs, $chemins_widget); |
} |
/** |
* La méthode chargerClasse() charge dynamiquement les classes trouvées dans le code. |
* Cette fonction est appelée par php5 quand il trouve une instanciation de classe dans le code. |
* |
*@param string le nom de la classe appelée. |
*@return void le fichier contenant la classe doit être inclu par la fonction. |
*/ |
public static function chargerClasse($classe) { |
if (class_exists($classe)) { |
return null; |
} |
foreach (self::$autoload_chemins as $chemin) { |
$chemin = $chemin.$classe.'.php'; |
if (file_exists($chemin)) { |
require_once $chemin; |
} |
} |
} |
/** |
* Execute le widget. |
*/ |
function executer() { |
if (!is_null($this->widget)) { |
$classe_widget = ucfirst($this->widget); |
$fichier_widget = self::$config['chemins']['widgetCourantDossier'].$classe_widget.'.php'; |
if (file_exists($fichier_widget)) { |
include_once $fichier_widget; |
if (class_exists($classe_widget)) { |
$widget = new $classe_widget(self::$config, $this->parametres); |
$widget->executer(); |
} |
} |
} |
} |
/** |
* Charge le fichier de config spécifique du wiget et fusionne la config avec celle partagés par l'ensemble des widgets. |
*/ |
private function chargerWidgetConfig() { |
$widget_config_ini_fichier = self::$config['chemins']['widgetCourantDossier'].'config.ini'; |
if (file_exists($widget_config_ini_fichier)) { |
$widget_config = parse_ini_file($widget_config_ini_fichier, TRUE); |
self::$config = array_merge(self::$config, $widget_config); |
} |
} |
} |
?> |
/branches/v5.8-seynes/widget/. |
---|
New file |
Property changes: |
Added: svn:ignore |
+widget.ini.php |