Subversion Repositories eFlore/Applications.cel

Compare Revisions

No changes between revisions

Ignore whitespace Rev 941 → Rev 948

/tags/celw-v1.1/widget/bibliotheque/WidgetCommun.php
New file
0,0 → 1,404
<?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', '&amp;', $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 de l'annuaire
* une tableau avec en clé le courriel et en valeur, un tableau associatif :
* - nom
* - prenom
* - pseudo
* - pseudoUtilise : si true, nous devons afficher le pseudo à la place de Prénom NOM.
* - intitule : directement la valeur à afficher (pseudo ou Prénom NOM en fonction du champ pseudoUtilise)
* @param array $courriels un tableau de courriels pour lesquels il faut rechercher les infos d'identité
*/
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);
return (array) json_decode($json);
}
//+----------------------------------------------------------------------------------------------------------------+
// 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($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;
}
}
?>
/tags/celw-v1.1/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();
}
}
/tags/celw-v1.1/widget/index.php
New file
0,0 → 1,5
<?php
require 'Widget.php';
$widget = new Widget();
$widget->executer();
?>
/tags/celw-v1.1/widget/widget.ini.defaut.php
New file
0,0 → 1,39
;<?/*
[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 = "/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
baseURLServicesCelTpl = "http://www.tela-botanica.org/service:cel:%s"
; URL des services web du CEL sous forme de template à utiliser avec sprintf
baseURLServicesAnnuaireTpl = "http://www.tela-botanica.org/service:annuaire:%s"
; Squelette d'Url permettant d'afficher une image du CEL (remplace %s par l'id de l'image sans underscore)
celImgUrlTpl = "http://www.tela-botanica.org/appli:cel-img:%s.jpg"
; Squelette d'URL pour les services web d'eFlore.
baseURLServicesEfloreTpl = "http://www.tela-botanica.org/service:eflore:{projetCode}/{apiVersion}/{serviceNom}"
 
[authentification]
serviceUrlTpl = "http://www.tela-botanica.org/client/annuaire_nouveau/actuelle/jrest/TestLoginMdp/%s/%s"
administrateurs = aurelien@tela-botanica.org,david.delon@clapas.net,jpm@tela-botanica.org,marie@tela-botanica.org
;*/?>
/tags/celw-v1.1/widget/modules/carto/config.defaut.ini
New file
0,0 → 1,5
[carto]
; Chemin vers le dossier contenant les fichiers kmz des limites communales
communesKmzChemin = "/home/telabotap/www/commun/google/map/3/kmz/communes/,/home/telabotap/www/commun/google/map/3/kmz/communes_incompletes/"
; Template de l'url où charger les fichiers kml des limites communales.
limitesCommunaleUrlTpl = "http://www.tela-botanica.org/eflore/cel2/widget/modules/carto/squelettes/kml/%s/%s"
/tags/celw-v1.1/widget/modules/carto/Carto.php
New file
0,0 → 1,195
<?php
// declare(encoding='UTF-8');
/**
* Service fournissant une carte dynamique des obsertions publiques du CEL.
* 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=AideCELWidgetCarto
*
* Paramètres :
* ===> utilisateur = identifiant
* Affiche seulement les observations d'un utilisateur donné. L'identifiant correspond au courriel de
* l'utilisateur avec lequel il s'est inscrit sur Tela Botanica.
* ===> dept = code_du_département
* Affiche seulement les observations pour le département français métropolitain indiqué. Les codes de département utilisables
* sont : 01 à 19, 2A, 2B et 21 à 95.
* ===> projet = mot-clé
* Affiche seulement les observations pour le projet d'observations indiqué. Dans l'interface du CEL, vous pouvez taguer vos
* observations avec un mot-clé de projet. Si vous voulez regrouper des observations de plusieurs utilisateurs, communiquez un
* mot-clé de projet à vos amis et visualisez les informations ainsi regroupées.
* ===> num_taxon = num_taxon
* Affiche seulement les observations pour la plante indiquée. Le num_taxon correspond au numéro taxonomique de la plante.
* Ce numéro est disponible dans les fiches d'eFlore. Par exemple, pour "Poa bulbosa L." le numéro taxonomique vaut 7080.
*
* @author Jean-Pascal MILCENT <jpm@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) 2010, Tela Botanica (accueil@tela-botanica.org)
*/
class Carto extends WidgetCommun {
const DS = DIRECTORY_SEPARATOR;
const SERVICE_CARTO_NOM = 'CelWidgetMap';
const SERVICE_CARTO_ACTION_DEFAUT = 'carte-defaut';
private $carte = null;
private $utilisateur = null;
private $projet = null;
private $dept = null;
private $num_taxon = null;
private $station = null;
private $format = null;// Format des obs pour les stations (tableau/liste)
/**
* Méthode appelée par défaut pour charger ce widget.
*/
public function executer() {
$retour = null;
$this->extraireParametres();
$methode = $this->traiterNomMethodeExecuter($this->carte);
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';
$html = $this->traiterSquelettePhp($squelette, $retour['donnees']);
$this->envoyer($html);
}
}
public function extraireParametres() {
extract($this->parametres);
$this->carte = (isset($carte) ? $carte : self::SERVICE_CARTO_ACTION_DEFAUT);
$this->utilisateur = (isset($utilisateur) ? $utilisateur : '*');
$this->projet = (isset($projet) ? $projet : '*');
$this->tag = (isset($tag) ? $tag : '*');
$this->dept = (isset($dept) ? $dept : '*');
$this->commune = (isset($commune) ? $commune : '*');
$this->num_taxon = (isset($num_taxon) ? $num_taxon : '*');
$this->date = (isset($date) ? $date : '*');
$this->taxon = (isset($taxon) ? $taxon : '*');
$this->commentaire = (isset($commentaire) ? $commentaire : null);
$this->station = (isset($station) ? $station : null);
$this->format = (isset($format) ? $format : null);
$this->start = (isset($start) ? $start : null);
$this->limit = (isset($limit) ? $limit : null);
}
 
/**
* Carte par défaut
*/
public function executerCarteDefaut() {
$widget = null;
$url_stations = $this->contruireUrlServiceCarto('stations');
$url_base = sprintf($this->config['chemins']['baseURLAbsoluDyn'], '');
 
// Création des infos du widget
$widget['donnees']['url_cel_carto'] = $this->contruireUrlServiceCarto();
$widget['donnees']['url_stations'] = $url_stations;
$widget['donnees']['url_base'] = $url_base;
$widget['donnees']['utilisateur'] = $this->utilisateur;
$widget['donnees']['projet'] = $this->projet;
$widget['donnees']['tag'] = $this->tag;
$widget['donnees']['dept'] = $this->dept;
$widget['donnees']['commune'] = $this->commune;
$widget['donnees']['num_taxon'] = $this->num_taxon;
$widget['donnees']['date'] = $this->date;
$widget['donnees']['taxon'] = $this->taxon;
$widget['donnees']['commentaire'] = $this->commentaire;
$widget['donnees']['url_limites_communales'] = $this->obtenirUrlsLimitesCommunales();
$widget['squelette'] = 'carte_defaut';
return $widget;
}
private function contruireUrlServiceCarto($action = null) {
// Création url données json
$url = sprintf($this->config['chemins']['baseURLServicesCelTpl'], self::SERVICE_CARTO_NOM);
if ($action) {
$url .= "/$action";
$parametres_retenus = array();
$parametres_a_tester = array('station', 'utilisateur', 'projet', 'tag', 'dept', 'commune',
'num_taxon', 'taxon', 'date', 'commentaire',
'start', 'limit');
foreach ($parametres_a_tester as $param) {
if (isset($this->$param) && $this->$param != '*') {
$parametres_retenus[$param] = $this->$param;
}
}
if (count($parametres_retenus) > 0) {
$parametres_url = array();
foreach ($parametres_retenus as $cle => $valeur) {
$parametres_url[] = $cle.'='.$valeur;
}
$url .= '?'.implode('&', $parametres_url);
}
}
return $url;
}
private function obtenirUrlsLimitesCommunales() {
$urls = null;
if (isset($this->dept)) {
// si on veut afficher les limites départemmentales on va compter et chercher les noms de fichiers
$fichiersKml = $this->chercherFichierKml();
if (count($fichiersKml) > 0) {
foreach ($fichiersKml as $kml => $dossier){
$url_limites_communales = sprintf($this->config['carto']['limitesCommunaleUrlTpl'], $dossier, $kml);
$urls[] = $url_limites_communales;
}
}
}
$urls = json_encode($urls);
return $urls;
}
private function chercherFichierKml(){
$fichiers = array();
$chemins = explode(',', $this->config['carto']['communesKmzChemin']);
$departements = explode(',', $this->dept);// plrs code de départements peuvent être demandés séparés par des virgules
$departements_trouves = array();
foreach ($chemins as $dossier_chemin) {
if ($dossier_ressource = opendir($dossier_chemin)) {
while ($element = readdir($dossier_ressource)) {
if ($element != '.' && $element != '..') {
foreach ($departements as $departement) {
$nom_dossier = basename($dossier_chemin);
if (!isset($departements_trouves[$departement]) || $departements_trouves[$departement] == $nom_dossier) {
$dept_protege = preg_quote($departement);
if (!is_dir($dossier_chemin.'/'.$element) && preg_match("/^$dept_protege(?:_[0-9]+|)\.km[lz]$/", $element)) {
$fichiers[$element] = $nom_dossier;
$departements_trouves[$departement] = $nom_dossier;
}
}
}
}
}
closedir($dossier_ressource);
}
}
return $fichiers;
}
/**
* Afficher message d'avertissement.
*/
public function executerAvertissement() {
$widget = null;
 
// Création des infos du widget
$widget['donnees']['url_base'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], '');
$widget['squelette'] = 'avertissement';
return $widget;
}
}
/tags/celw-v1.1/widget/modules/carto/squelettes/avertissement.tpl.html
New file
0,0 → 1,107
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Avertissements - CEL widget cartographie</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Content-style-type" content="text/css" />
<meta http-equiv="Content-script-type" content="text/javascript" />
<meta http-equiv="Content-language" content="fr" />
<meta name="revisit-after" content="15 days" />
<meta name="robots" content="index,follow" />
<meta name="author" content="Delphine CAUQUIL, Jean-Pascal MILCENT" />
<meta name="keywords" content="Avertissement, Tela Botanica, cartographie, CEL" />
<meta name="description" content="Avertissement du widget de cartographie des observations publiques de plantes saisies dans le Carnet en Ligne (CEL)" />
 
<!-- Spécial mobile -->
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<!-- Favicones -->
<link rel="icon" type="image/png" href="http://www.tela-botanica.org/sites/commun/generique/images/favicones/tela_botanica.png" />
<link rel="shortcut icon" type="image/x-icon" href="http://www.tela-botanica.org/sites/commun/generique/images/favicones/tela_botanica.ico" />
<!-- CSS -->
<link href="<?=$url_base?>modules/carto/squelettes/css/carto.css" rel="stylesheet" type="text/css" media="screen" />
<style>
html {
overflow:auto;
}
body {
overflow:auto;
}
</style>
<!-- Stats : Google Analytics -->
<script type="text/javascript">
//<![CDATA[
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-20092557-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
//]]>
</script>
</head>
<body>
<div id="zone-avertissement">
<h1>Avertissements &amp; informations</h1>
<h2>C'est quoi ces chiffres sur la carte ?</h2>
<p>
Afin de ne pas divulguer la localisation des stations d'espèces rares ou protégées, l'ensemble des observations
a été regroupé par commune.<br />
Ainsi les nombres apparaissant sur la carte représentent le nombre de communes où des observations ont été
réalisées.<br />
Ce nombre varie en fonction du niveau de zoom auquel vous vous trouvez, jusqu'à faire apparaître l'icône
<img src="http://chart.apis.google.com/chart?cht=mm&chs=24x32&chco=FFFFFF,008CFF,000000&ext=.png" alt="Icône de regroupement des observations" />.
Il indique le centre d'une commune et permet en cliquant dessus d'afficher l'ensemble des observations que l'on
peut y trouver.
</p>
<h2>Avertissements</h2>
<p>
Les observations affichées sur cette carte proviennent des saisies des membres du réseau Tela Botanica réalisées à l'aide
de l'application <a href="http://www.tela-botanica.org/appli:cel" onclick="window.open(this.href); return false;">Carnet en Ligne (CEL)</a>.<br />
Bien que la plupart des botanistes cherchent à déterminer avec un maximum de rigueur les espèces qu'ils observent, il arrive que des erreurs soient faites.<br />
Il est donc important de garder un esprit critique vis à vis des observations diffusées sur cette carte.<br />
Nous souhaitons prochainement ajouter à cette application cartographique un moyen de contacter les auteurs des observations.
Cette fonctionnalité permettra de faciliter la correction d'eventuelles erreurs.<br />
Pour l'instant, si vous constatez des problèmes, veuillez contacter : <a href="mailto:eflore_remarques@tela-botanica.org">eflore_remarques@tela-botanica.org</a>.
</p>
<h2>Le <a href="http://www.tela-botanica.org/appli:cel" onclick="window.open(this.href); return false;">Carnet en Ligne (CEL)</a>, c'est quoi ?</h2>
<h3>Un outil pour gérer mes relevés de terrain</h3>
<p>
Le Carnet en ligne est <a href="http://www.tela-botanica.org/appli:cel" onclick="window.open(this.href); return false;">accessible en ligne sur le site de Tela Botanica</a>.
Vous pouvez y déposer vos observations de plantes de manière simple et efficace
(aide à la saisie, visualisation de la chorologie d’une plante, utilisation de Google Map),
les trier et les rechercher.
</p>
<h3>Des fonctionnalités à la demande</h3>
<ul>
<li>Un module cartographique vous permet de géolocaliser vos observations grâce aux coordonnées ou bien par pointage sur une carte (en France métropolitaine).</li>
<li>Un module image vous permet d’ajouter des images et des les associer à vos observations.</li>
<li>Un module projet vous permet de créer des projets et d’y associer des observations.</li>
<li>Un module import/export au format tableur pour traiter ses données.</li>
</ul>
<h3>Partage des données</h3>
<p>
Partager vos observations permet d’alimenter la base de données eFlore, de compléter automatiquement la carte
de répartition des espèces du site de Tela Botanica, de servir de source de données pour des projets externes...<br />
Les données sont publiées sous licence libre <a href="http://www.tela-botanica.org/page:licence" onclick="window.open(this.href); return false;">Creative commons</a>
afin d'en faciliter la divulgation.
</p>
<h3>Vous souhaitez participer ?</h3>
<p>Consulter le mode d'emploi ci-dessous pour facilement prendre en main cet outil.</p>
<div>
<object style="width: 600px; height: 282px;">
<param value="http://static.issuu.com/webembed/viewers/style1/v1/IssuuViewer.swf?mode=embed&amp;viewMode=presentation&amp;layout=http%3A%2F%2Fskin.issuu.com%2Fv%2Flight%2Flayout.xml&amp;showFlipBtn=true&amp;autoFlip=true&amp;autoFlipTime=6000&amp;documentId=100624090135-b3beeea0f20641bf8f277c49ebc5bbee&amp;docName=cel&amp;username=marietela&amp;loadingInfoText=Carnet%20en%20ligne&amp;et=1277375679622&amp;er=55" name="movie">
<param value="true" name="allowfullscreen">
<param value="false" name="menu"><embed flashvars="mode=embed&amp;viewMode=presentation&amp;layout=http%3A%2F%2Fskin.issuu.com%2Fv%2Flight%2Flayout.xml&amp;showFlipBtn=true&amp;autoFlip=true&amp;autoFlipTime=6000&amp;documentId=100624090135-b3beeea0f20641bf8f277c49ebc5bbee&amp;docName=cel&amp;username=marietela&amp;loadingInfoText=Carnet%20en%20ligne&amp;et=1277375679622&amp;er=55" style="width: 600px; height: 282px;" menu="false" allowfullscreen="true" type="application/x-shockwave-flash" src="http://static.issuu.com/webembed/viewers/style1/v1/IssuuViewer.swf">
</object>
<p style="width: 600px; text-align: left;"><a target="_blank" href="http://issuu.com/marietela/docs/cel?mode=embed&amp;viewMode=presentation&amp;layout=http%3A%2F%2Fskin.issuu.com%2Fv%2Flight%2Flayout.xml&amp;showFlipBtn=true&amp;autoFlip=true&amp;autoFlipTime=6000">Open publication</a> - Free <a target="_blank" href="http://issuu.com">publishing</a> - <a target="_blank" href="http://issuu.com/search?q=terrain">More terrain</a></p>
</div>
</div>
</body>
</html>
/tags/celw-v1.1/widget/modules/carto/squelettes/images/chargement.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/celw-v1.1/widget/modules/carto/squelettes/images/chargement.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/celw-v1.1/widget/modules/carto/squelettes/images/fermeture.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/celw-v1.1/widget/modules/carto/squelettes/images/fermeture.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/celw-v1.1/widget/modules/carto/squelettes/images/ouverture.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/celw-v1.1/widget/modules/carto/squelettes/images/ouverture.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/celw-v1.1/widget/modules/carto/squelettes/images/trie_decroissant.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/celw-v1.1/widget/modules/carto/squelettes/images/trie_decroissant.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/celw-v1.1/widget/modules/carto/squelettes/images/trie.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/celw-v1.1/widget/modules/carto/squelettes/images/trie.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/celw-v1.1/widget/modules/carto/squelettes/images/information.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/celw-v1.1/widget/modules/carto/squelettes/images/information.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/celw-v1.1/widget/modules/carto/squelettes/images/trie_croissant.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/celw-v1.1/widget/modules/carto/squelettes/images/trie_croissant.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/celw-v1.1/widget/modules/carto/squelettes/obs_msg_info.tpl.html
New file
0,0 → 1,3
<p id="obs-msg-info">
Les observations de cette carte sont regroupées par commune.
</p>
/tags/celw-v1.1/widget/modules/carto/squelettes/carte_defaut.tpl.html
New file
0,0 → 1,316
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Observations publiques du CEL - Tela Botanica</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Content-style-type" content="text/css" />
<meta http-equiv="Content-script-type" content="text/javascript" />
<meta http-equiv="Content-language" content="fr" />
<meta name="revisit-after" content="15 days" />
<meta name="robots" content="index,follow" />
<meta name="author" content="Delphine CAUQUIL, Jean-Pascal MILCENT" />
<meta name="keywords" content="Tela Botanica, cartographie, CEL" />
<meta name="description" content="Widget de cartographie des observations publiques de plantes saisies dans le Carnet en Ligne (CEL)" />
 
<!-- Spécial mobile -->
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<!-- Favicones -->
<link rel="icon" type="image/png" href="http://www.tela-botanica.org/sites/commun/generique/images/favicones/tela_botanica.png" />
<link rel="shortcut icon" type="image/x-icon" href="http://www.tela-botanica.org/sites/commun/generique/images/favicones/tela_botanica.ico" />
<!-- Javascript : bibliothèques -->
<!-- <script type="text/javascript" src="https://getfirebug.com/firebug-lite.js"></script> -->
<!-- Google Map v3 -->
<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3.6&amp;sensor=true&amp;language=fr&amp;region=FR"></script>
<script type="text/javascript" src="http://www.tela-botanica.org/commun/google/map/3/markerclusterer/2.0.1/markerclusterer-2.0.1.pack.js"></script>
<!-- Jquery -->
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/1.6.2/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/jquery-ui/1.8.15/js/jquery-ui-1.8.15.custom.min.js"></script>
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/tablesorter/2.0.5/jquery.tablesorter.min.js"></script>
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/fancybox/1.3.4/jquery.fancybox-1.3.4.pack.js"></script>
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/pagination/2.2/jquery.pagination.js"></script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/validate/1.8.1/jquery.validate.min.js"></script>
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/validate/1.8.1/messages_fr.js"></script>
<!-- Javascript : données -->
<script src="<?=$url_stations?>" type="text/javascript"></script>
<!-- Javascript : appli carto -->
<script type="text/javascript">
//<![CDATA[
var urlsLimitesCommunales = <?=$url_limites_communales?>;
var nt = '<?=$num_taxon?>';
var filtreCommun =
'&taxon=<?=$taxon?>'+
'&utilisateur=<?=$utilisateur?>'+
'&projet=<?=$projet?>'+
'&tag=<?=$tag?>'+
'&date=<?=$date?>'+
'&dept=<?=$dept?>'+
'&commune=<?=$commune?>'+
'&commentaire=<?=$commentaire?>';
var stationsUrl = '<?=$url_cel_carto?>/stations'+'?'+
'num_taxon='+nt+
filtreCommun;
var taxonsUrl = '<?=$url_cel_carto?>/taxons'+'?'+
'num_taxon='+nt+
filtreCommun;
var observationsUrl = '<?=$url_cel_carto?>/observations'+'?'+
'station={stationId}'+
'&num_taxon={nt}'+
filtreCommun;
//]]>
</script>
<script type="text/javascript" src="<?=$url_base?>modules/carto/squelettes/scripts/carto.js"></script>
<!-- CSS -->
<link rel="stylesheet" href="http://www.tela-botanica.org/commun/jquery/fancybox/1.3.4/jquery.fancybox-1.3.4.css" type="text/css" media="screen" />
<link rel="stylesheet" href="http://www.tela-botanica.org/commun/jquery/jquery-ui/1.8.15/css/smoothness/jquery-ui-1.8.15.custom.css" type="text/css" media="screen" />
<link href="<?=$url_base?>modules/carto/squelettes/css/carto.css" rel="stylesheet" type="text/css" media="screen" />
</head>
 
<body>
<div id="zone-titre">
<h1 id="carte-titre">
<span id="logo">
<a href="http://www.tela-botanica.org/site:accueil" title="Aller à l'accueil de Tela Botanica">
<img src="http://www.tela-botanica.org/sites/commun/generique/images/favicones/tela_botanica.png" alt="TB" />
</a>
</span>
<span id="obs-nbre">&nbsp;</span> observations
<span class="plante-titre">de <span class="plantes-nbre">&nbsp;</span> plantes</span> sur
<span id="commune-nbre">&nbsp;</span> communes
- <a href="http://www.tela-botanica.org/appli:cel" title="Carnet en Ligne" onclick="window.open(this.href); arreter(event); return false;">CEL</a> (<a href="http://www.tela-botanica.org/" onclick="window.open(this.href); arreter(event); return false;">Tela Botanica</a>)
</h1>
<div id="zone-info">
<a href="<?=$url_base?>carto?carte=avertissement" onClick="ouvrirPopUp('<?=$url_base?>carto?carte=avertissement', 'Avertissement'); arreter(event); return false;">
<img src="<?=$url_base?>modules/carto/squelettes/images/information.png"
alt="Avertissements" title="Avertissements &amp; informations" />
</a>
</div>
</div>
<? if ($num_taxon == '*') : ?>
<div id="panneau-lateral">
<div id="pl-ouverture" title="Ouvrir le panneau latéral"><span>Panneau >></span></div>
<div id="pl-fermeture" title="Fermer le panneau latéral"><span><< Fermer [x]</span></div>
<div id="pl-contenu">
<div id="pl-entete">
<h2>Filtre sur <span class="plantes-nbre">&nbsp;</span> plantes</h2>
<p>
Cliquez sur un nom de plante pour filtrer les observations sur la carte.<br />
Pour revenir à l'état initial, cliquez à nouveau sur le nom sélectionné.
</p>
</div>
<div id="pl-corps" onMouseOver="map.setOptions({'scrollwheel':false});" onMouseOut="map.setOptions({'scrollwheel':true});">
<!-- Insertion des lignes à partir du squelette tpl-taxons-liste -->
</div>
</div>
</div>
<? endif ?>
<div id="carte"></div>
<!-- +-------------------------------------------------------------------------------------------+ -->
<!-- Blocs chargés à la demande : par défaut avec un style display à none -->
<!-- Squelette du message de chargement des observations -->
<script id="tpl-chargement" type="text/x-jquery-tmpl">
<div id="chargement" style="height:500px;">
<img src="<?=$url_base?>modules/carto/squelettes/images/chargement.gif" alt="Chargement en cours..." />
<p>Chargement des observations en cours...</p>
</div>
</script>
<!-- Squelette du contenu d'une info-bulle observation -->
<script id="tpl-obs" type="text/x-jquery-tmpl">
<div id="info-bulle" style="min-height:500px;width:600px;">
<div id="obs">
<h2><span id="obs-total"></span> observations pour <span id="obs-commune"></span></h2>
<div class="navigation">&nbsp;</div>
<div>
<ul>
<li><a href="#obs-vue-tableau">Tableau</a></li>
<li><a href="#obs-vue-liste">Liste</a></li>
</ul>
</div>
<div id="observations">
<div id="obs-vue-tableau" style="display:none;">
<table id="obs-tableau">
<thead>
<tr>
<th title="Nom scientifique défini par l'utilisateur.">Nom</th>
<th title="Date de l'observation">Date</th>
<th title="Lieu d'observation">Lieu</th>
<th title="Auteur de l'observation">Observateur</th>
</tr>
</thead>
<tbody id="obs-tableau-lignes" class="obs-conteneur">
<!-- Insertion des lignes à partir du squelette tpl-obs-tableau -->
</tbody>
</table>
</div>
<div id="obs-vue-liste" style="display:none;">
<ol id="obs-liste-lignes" class="obs-conteneur">
<!-- Insertion des lignes à partir du squelette tpl-obs-liste -->
</ol>
</div>
</div>
<div class="navigation">&nbsp;</div>
<div id="obs-pieds-page">
<p id="obs-msg-info">Les observations de cette carte sont regroupées par commune.</p>
<p>Id : <span id="obs-station-id">&nbsp;</span></p>
</div>
</div>
</div>
</script>
<!-- Squelette du contenu du tableau des observation -->
<script id="tpl-obs-tableau" type="text/x-jquery-tmpl">
<tr>
<td>
<span class="nom-sci">
{{if nn != 0}}
<a href="http://www.tela-botanica.org/nn${nn}"
onclick="window.open(this.href); arreter(event); return false; ">
${nomSci}
</a>
{{else}}
${nomSci}
{{/if}}
</span>
</td>
<td>{{if date}}${date}{{else}}&nbsp;{{/if}}</td>
<td>{{if lieu}}${lieu}{{else}}&nbsp;{{/if}}</td>
<td>
{{if observateur}}
{{if observateurId}}
<a class="contact obs-${idObs} contributeur-${observateurId}"
href="#form-contact"
title="Contactez ce contributeur">
${observateur}
</a>
{{else}}
${observateur}
{{/if}}
{{else}}
&nbsp;
{{/if}}
</td>
</tr>
</script>
<!-- Squelette du contenu de la liste des observations -->
<script id="tpl-obs-liste" type="text/x-jquery-tmpl">
<li>
<div id="cel-obs-${idObs}">
{{if images}}
{{each(index, img) images}}
<div{{if index == 0}} class="cel-img-principale" {{else}} class="cel-img-secondaire"{{/if}}>
<a class="cel-img"
href="${img.normale}"
title="${nomSci} {{if nn}} [${nn}] {{/if}} par ${observateur} - Publiée le ${datePubli} - GUID : ${img.guid}"
rel="cel-obs-${idObs}">
<img src="${img.miniature}" alt="Image #${img.idImg} de l'osbervation #${nn}" />
</a>
<p id="cel-info-${img.idImg}" class="cel-infos">
<a class="cel-img-titre" href="${urlEflore}"
onclick="window.open(this.href);return false;"
title="Cliquez pour accéder à la fiche eFlore">
<strong>${nomSci} {{if nn}} [nn${nn}] {{/if}}</strong> par <em>${observateur}</em>
</a>
<br />
<span class="cel-img-date">Publiée le ${datePubli}</span>
</p>
</div>
{{/each}}
{{/if}}
<dl>
<dt class="champ-nom-sci">Nom</dt>
<dd title="Nom défini par l'utilisateur{{if nn != 0}}. Cliquez pour accéder à la fiche d'eFlore.{{/if}}">
<span class="nom-sci">
{{if nn != 0}}
<a href="http://www.tela-botanica.org/nn${nn}"
onclick="window.open(this.href); arreter(event); return false; ">
${nomSci}
</a>
{{else}}
${nomSci}
{{/if}}
</span>
</dd>
<dt title="Lieu d'observation">Lieu</dt><dd class="lieu">&nbsp;${lieu}</dd>
<dt title="Date d'observation">Le</dt><dd class="date">&nbsp;${date}</dd>
<dt title="Auteur de l'observation">Publié par</dt>
<dd>
{{if observateur}}
{{if observateurId}}
<a class="contact obs-${idObs} contributeur-${observateurId}"
href="#form-contact"
title="Contactez ce contributeur">
${observateur}
</a>
{{else}}
${observateur}
{{/if}}
{{else}}
&nbsp;
{{/if}}
</dd>
</dl>
<hr class="nettoyage"/>
</div>
</li>
</script>
<!-- Squelette de la liste des taxons -->
<script id="tpl-taxons-liste" type="text/x-jquery-tmpl">
<ol id="taxons">
{{each(index, taxon) taxons}}
<li id="taxon-${taxon.nt}">
<span class="taxon" title="Numéro taxonomique : ${taxon.nt} - Famille : ${taxon.famille}">
${taxon.nom} <span class="nt" title="Numéro taxonomique">${taxon.nt}</span>
</span>
</li>
{{/each}}
</ol>
</script>
<!-- Squelette du formulaire de contact -->
<div id="tpl-form-contact" style="display:none;">
<form id="form-contact" method="post" action="">
<div id="fc-zone-dialogue"></div>
<dl>
<dt><label for="fc_sujet">Sujet</label></dt>
<dd><input id="fc_sujet" name="fc_sujet"/></dd>
<dt><label for="fc_message">Message</label></dt>
<dd><textarea id="fc_message" name="fc_message"></textarea></dd>
<dt><label for="fc_utilisateur_courriel" title="Utilisez le courriel avec lequel vous êtes inscrit à Tela Botanica">Votre courriel</label></dt>
<dd><input id="fc_utilisateur_courriel" name="fc_utilisateur_courriel"/></dd>
</dl>
<input id="fc_destinataire_id" name="fc_destinataire_id" type="hidden" value="" />
<input id="fc_copies" name="fc_copies" type="hidden" value="eflore_remarques@tela-botanica.org" />
<button id="fc_annuler" type="button">Annuler</button>
<button id="fc_effacer" type="reset">Effacer</button>
<input id="fc_envoyer" type="submit" value="Envoyer" />
</form>
</div>
<!-- Stats : Google Analytics -->
<script type="text/javascript">
//<![CDATA[
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-20092557-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
//]]>
</script>
</body>
</html>
/tags/celw-v1.1/widget/modules/carto/squelettes/scripts/carto.js
New file
0,0 → 1,698
/*+--------------------------------------------------------------------------------------------------------+*/
// PARAMÊTRES et CONSTANTES
// Mettre à true pour afficher les messages de débogage
var DEBUG = true;
var pointImageUrl = 'http://chart.apis.google.com/chart?cht=mm&chs=24x32&chco=FFFFFF,008CFF,000000&ext=.png';
var pointsOrigine = null;
var boundsOrigine = null;
var markerClusterer = null;
var map = null;
var infoBulle = new google.maps.InfoWindow();
var pointClique = null;
var carteCentre = new google.maps.LatLng(46.4, 3.10);
var carteOptions = {
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControlOptions: {
mapTypeIds: ['OSM',
google.maps.MapTypeId.ROADMAP,
google.maps.MapTypeId.HYBRID,
google.maps.MapTypeId.SATELLITE,
google.maps.MapTypeId.TERRAIN]
}
};
var ctaLayer = null;
var osmMapType = new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
return "http://tile.openstreetmap.org/" +
zoom + "/" + coord.x + "/" + coord.y + ".png";
},
tileSize: new google.maps.Size(256, 256),
isPng: true,
alt: "OpenStreetMap",
name: "OSM",
maxZoom: 19
});
var pagineur = {'limite':50, 'start':0, 'total':0, 'stationId':null, 'format':'tableau'};
var station = {'commune':'', 'obsNbre':0};
var obsStation = new Array();
var obsPage = new Array();
var taxonsCarte = new Array();
/*+--------------------------------------------------------------------------------------------------------+*/
// INITIALISATION DU CODE
 
//Déclenchement d'actions quand JQuery et le document HTML sont OK
$(document).ready(function() {
initialiserWidget();
});
 
function initialiserWidget() {
afficherStats();
initialiserAffichageCarte();
initialiserAffichagePanneauLateral();
initialiserCarte();
initialiserInfoBulle();
initialiserFormulaireContact();
chargerLimitesCommunales();
rafraichirCarte();
}
 
/*+--------------------------------------------------------------------------------------------------------+*/
// AFFICHAGE GÉNÉRAL
 
function afficherStats() {
// Ajout du nombre de communes où des observations ont eu lieu
$('#commune-nbre').text(stations.stats.communes.formaterNombre());
// Ajout du nombre d'observations
$('#obs-nbre').text(stations.stats.observations.formaterNombre());
}
 
/*+--------------------------------------------------------------------------------------------------------+*/
// CARTE
 
function initialiserAffichageCarte() {
$('#carte').height($(window).height() - 35);
$('#carte').width($(window).width() - 24);
if (nt != '*') {
$('#carte').css('left', 0);
}
}
 
function initialiserCarte() {
map = new google.maps.Map(document.getElementById('carte'), carteOptions);
// Ajout de la couche OSM à la carte
map.mapTypes.set('OSM', osmMapType);
}
 
 
function chargerLimitesCommunales() {
if (urlsLimitesCommunales != null) {
for (urlId in urlsLimitesCommunales) {
var url = urlsLimitesCommunales[urlId];
ctaLayer = new google.maps.KmlLayer(url, {preserveViewport: true});
ctaLayer.setMap(map);
}
}
}
 
function rafraichirCarte() {
var points = [];
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < stations.stats.communes; ++i) {
var maLatLng = new google.maps.LatLng(stations.points[i].coord_x, stations.points[i].coord_y);
var pointImage = new google.maps.MarkerImage(pointImageUrl, new google.maps.Size(24, 32));
var point = new google.maps.Marker({
position: maLatLng,
map: map,
icon: pointImage,
stationId: stations.points[i].id
});
 
bounds.extend(maLatLng);
google.maps.event.addListener(point, 'click', function() {
pointClique = this;
infoBulle.open(map, this);
var limites = map.getBounds();
var centre = limites.getCenter();
var nordEst = limites.getNorthEast();
var centreSudLatLng = new google.maps.LatLng(nordEst.lat(), centre.lng());
map.panTo(centreSudLatLng);
afficherInfoBulle();
chargerObs(0, 0);
});
points.push(point);
}
 
if (pointsOrigine == null && boundsOrigine == null) {
pointsOrigine = points;
boundsOrigine = bounds;
}
executerMarkerClusterer(points, bounds);
}
 
function deplacerCartePointClique() {
map.panTo(pointClique.position);
}
 
function executerMarkerClusterer(points, bounds) {
if (markerClusterer) {
markerClusterer.clearMarkers();
}
markerClusterer = new MarkerClusterer(map, points);
map.fitBounds(bounds);
}
 
/*+--------------------------------------------------------------------------------------------------------+*/
// INFO BULLE
 
function initialiserInfoBulle() {
google.maps.event.addListener(infoBulle, 'domready', initialiserContenuInfoBulle);
google.maps.event.addListener(infoBulle, 'closeclick', deplacerCartePointClique);
}
 
function afficherInfoBulle() {
var obsHtml = $("#tpl-obs").html();
infoBulle.setContent(obsHtml);
}
 
function afficherMessageChargement(element) {
if ($('#chargement').get() == '') {
$('#tpl-chargement').tmpl().appendTo(element);
}
}
 
function supprimerMessageChargement() {
$('#chargement').remove();
}
 
function chargerObs(depart, total) {
if (depart == 0 || depart < total) {
var limite = 300;
if (depart == 0) {
obsStation = new Array();
}
console.log("Chargement de "+depart+" à "+(depart+limite));
var urlObs = observationsUrl+'&start={start}&limit='+limite;
urlObs = urlObs.replace(/\{stationId\}/g, pointClique.stationId);
urlObs = urlObs.replace(/\{nt\}/g, nt);
urlObs = urlObs.replace(/\{start\}/g, depart);
$.getJSON(urlObs, function(observations){
obsStation = obsStation.concat(observations.observations);
if (depart == 0) {
actualiserInfosStation(observations);
actualiserPagineur();
creerTitreInfoBulle();
}
console.log("Chargement ok");
chargerObs(depart+limite, station.obsNbre);
});
} else {
if (pagineur.limite < total) {
afficherPagination();
} else {
surClicPagePagination(0, null);
selectionnerOnglet("#obs-vue-"+pagineur.format);
}
}
}
 
function actualiserInfosStation(infos) {
station.commune = infos.commune;
station.obsNbre = infos.total;
}
 
function actualiserPagineur() {
pagineur.stationId = pointClique.stationId;
pagineur.total = station.obsNbre;
console.log("Total pagineur: "+pagineur.total);
if (pagineur.total > 4) {
pagineur.format = 'tableau';
} else {
pagineur.format = 'liste';
}
}
 
function afficherPagination(observations) {
$(".navigation").pagination(pagineur.total, {
items_per_page:pagineur.limite,
callback:surClicPagePagination,
next_text:'Suivant',
prev_text:'Précédent',
prev_show_always:false,
num_edge_entries:1,
num_display_entries:5,
load_first_page:true
});
}
 
function surClicPagePagination(pageIndex, paginationConteneur) {
var index = pageIndex * pagineur.limite;
var indexMax = index + pagineur.limite;
pagineur.depart = index;
obsPage = new Array();
for(index; index < indexMax; index++) {
obsPage.push(obsStation[index]);
}
supprimerMessageChargement();
mettreAJourObservations();
return false;
}
 
function mettreAJourObservations() {
$("#obs-"+pagineur.format+"-lignes").empty();
$("#obs-vue-"+pagineur.format).css('display', 'block');
$(".obs-conteneur").css('counter-reset', 'item '+pagineur.depart);
$("#tpl-obs-"+pagineur.format).tmpl(obsPage).appendTo("#obs-"+pagineur.format+"-lignes");
// Actualisation de Fancybox
ajouterFomulaireContact("a.contact");
if (pagineur.format == 'liste') {
ajouterGaleriePhoto("a.cel-img");
}
}
 
function creerTitreInfoBulle() {
$("#obs-total").append(station.obsNbre);
$("#obs-commune").append(station.commune);
}
 
function initialiserContenuInfoBulle() {
afficherOnglets();
afficherMessageChargement('#observations');
ajouterTableauTriable("#obs-tableau");
afficherTextStationId();
corrigerLargeurInfoWindow();
}
 
function afficherOnglets() {
var $tabs = $('#obs').tabs();
$('#obs').bind('tabsselect', function(event, ui) {
if (ui.panel.id == 'obs-vue-tableau') {
surClicAffichageTableau();
} else if (ui.panel.id == 'obs-vue-liste') {
surClicAffichageListe();
}
});
$tabs.tabs('select', "#obs-vue-"+pagineur.format);
}
 
function selectionnerOnglet(onglet) {
$('#obs').tabs('select', onglet);
}
 
function afficherTextStationId() {
$('#obs-station-id').text(pointClique.stationId);
}
 
function corrigerLargeurInfoWindow() {
$("#info-bulle").width($("#info-bulle").width() - 16);
}
 
function surClicAffichageTableau(event) {
console.log('tableau');
pagineur.format = 'tableau';
mettreAJourObservations();
mettreAJourTableauTriable("#obs-tableau");
}
 
function surClicAffichageListe(event) {
console.log('liste');
pagineur.format = 'liste';
mettreAJourObservations();
ajouterGaleriePhoto("a.cel-img");
}
 
function ajouterTableauTriable(element) {
// add parser through the tablesorter addParser method
$.tablesorter.addParser({
// Définition d'un id unique pour ce parsseur
id: 'date_cel',
is: function(s) {
// doit retourner false si le parsseur n'est pas autodétecté
return /^\s*\d{2}[\/-]\d{2}[\/-]\d{4}\s*$/.test(s);
},
format: function(date) {
// Transformation date jj/mm/aaaa en aaaa/mm/jj
date = date.replace(/^\s*(\d{2})[\/-](\d{2})[\/-](\d{4})\s*$/, "$3/$2/$1");
// Remplace la date par un nombre de millisecondes pour trier numériquement
return $.tablesorter.formatFloat(new Date(date).getTime());
},
// set type, either numeric or text
type: 'numeric'
});
$(element).tablesorter({
headers: {
1: {
sorter:'date_cel'
}
}
});
}
 
function mettreAJourTableauTriable(element) {
$(element).trigger('update');
}
 
function ajouterGaleriePhoto(element) {
$(element).fancybox({
transitionIn:'elastic',
transitionOut:'elastic',
speedIn :600,
speedOut:200,
overlayShow:true,
titleShow:true,
titlePosition:'inside',
titleFormat:function (titre, currentArray, currentIndex, currentOpts) {
var motif = /urn:lsid:tela-botanica[.]org:cel:img([0-9]+)$/;
motif.exec(titre);
var id = RegExp.$1;
var info = $('#cel-info-'+id).clone().html();
var tpl =
'<div class="cel-legende">'+
'<p class="cel-legende-vei">'+'Image n°' + (currentIndex + 1) + ' sur ' + currentArray.length +'<\/p>'+
(titre && titre.length ? '<p>'+info+'<\/p>' : '' )+
'<\/div>';
return tpl;
}
}).live('click', function(e) {
if (e.stopPropagation) {
e.stopPropagation();
}
return false;
});
}
 
function ajouterFomulaireContact(element) {
$(element).fancybox({
transitionIn:'elastic',
transitionOut:'elastic',
speedIn :600,
speedOut:200,
scrolling: 'no',
titleShow: false,
onStart: function(selectedArray, selectedIndex, selectedOpts) {
var element = selectedArray[selectedIndex];
 
var motif = / contributeur-([0-9]+)$/;
motif.exec($(element).attr('class'));
var id = RegExp.$1;
console.log('Destinataire id : '+id);
$("#fc_destinataire_id").attr('value', id);
var motif = / obs-([0-9]+) /;
motif.exec($(element).attr('class'));
var id = RegExp.$1;
console.log('Obs id : '+id);
chargerInfoObsPourMessage(id);
},
onCleanup: function() {
console.log('Avant fermeture fancybox');
$("#fc_destinataire_id").attr('value', '');
$("#fc_sujet").attr('value', '');
$("#fc_message").text('');
},
onClosed: function(e) {
console.log('Fermeture fancybox');
if (e.stopPropagation) {
e.stopPropagation();
}
return false;
}
});
}
 
function chargerInfoObsPourMessage(idObs) {
var sujet = "Remarque sur l'observation #"+idObs;
var message = "--\nConcerne l'observation de "+
' "'+trim($("#cel-obs-"+idObs+" .nom-sci").text())+'" '+
'du "'+trim($("#cel-obs-"+idObs+" .date").text())+'" '+
'au lieu "'+trim($("#cel-obs-"+idObs+" .lieu").text())+'".';
$("#fc_sujet").attr('value', sujet);
$("#fc_message").text(message);
}
 
function initialiserFormulaireContact() {
console.log('Initialisation du form contact');
$("#form-contact").validate({
rules: {
fc_sujet : "required",
fc_message : "required",
fc_courriel : {
required : true,
email : true}
}
});
$("#form-contact").bind("submit", envoyerCourriel);
$("#fc_annuler").bind("click", function() {console.log('clic annuler');$.fancybox.close();});
}
 
function envoyerCourriel() {
console.log('Formulaire soumis');
if ($("#form-contact").valid()) {
console.log('Formulaire valide');
//$.fancybox.showActivity();
var destinataireId = $("#fc_destinataire_id").attr('value');
var urlMessage = "http://www.tela-botanica.org/service:annuaire:Utilisateur/"+destinataireId+"/message"
var erreurMsg = "";
var donnees = new Array();
$.each($(this).serializeArray(), function (index, champ) {
var cle = champ.name;
cle = cle.replace(/^fc_/, '');
console.log('Clé:'+cle);
donnees[index] = {'name':cle,'value':champ.value};
});
$.ajax({
type : "POST",
cache : false,
url : urlMessage,
data : donnees,
beforeSend : function() {
$(".msg").remove();
},
success : function(data) {
$("#fc-zone-dialogue").append('<pre class="msg info">'+data.message+'</pre>');
},
error : function(jqXHR, textStatus, errorThrown) {
erreurMsg += "Erreur Ajax :\ntype : "+textStatus+' '+errorThrown+"\n";
reponse = jQuery.parseJSON(jqXHR.responseText);
if (reponse != null) {
$.each(reponse, function (cle, valeur) {
erreurMsg += valeur + "\n";
});
}
},
complete : function(jqXHR, textStatus) {
var debugMsg = '';
if (jqXHR.getResponseHeader("X-DebugJrest-Data") != '') {
debugInfos = jQuery.parseJSON(jqXHR.getResponseHeader("X-DebugJrest-Data"));
if (debugInfos != null) {
$.each(debugInfos, function (cle, valeur) {
debugMsg += valeur + "\n";
});
}
}
if (erreurMsg != '') {
$("#fc-zone-dialogue").append('<p class="msg">'+
'Une erreur est survenue lors de la transmission de votre message.'+'<br />'+
'Vous pouvez signaler le disfonctionnement à <a href="'+
'mailto:cel@tela-botanica.org'+'?'+
'subject=Disfonctionnement du widget de Cartographie'+
"&body="+erreurMsg+"\nDébogage :\n"+debugMsg+
'">cel@tela-botanica.org</a>.'+
'</p>');
}
if (DEBUG) {
console.log('Débogage : '+debugMsg);
}
console.log('Débogage : '+debugMsg);
console.log('Erreur : '+erreurMsg);
}
});
}
return false;
}
/*+--------------------------------------------------------------------------------------------------------+*/
// PANNEAU LATÉRAL
 
function initialiserAffichagePanneauLateral() {
$('#panneau-lateral').height($(window).height() - 35);
if (nt == '*') {
$('#pl-ouverture').bind('click', afficherPanneauLateral);
$('#pl-fermeture').bind('click', cacherPanneauLateral);
}
chargerTaxons(0, 0);
}
 
function chargerTaxons(depart, total) {
if (depart == 0 || depart < total) {
var limite = 7000;
console.log("Chargement des taxons de "+depart+" à "+(depart+limite));
var urlTax = taxonsUrl+'&start={start}&limit='+limite;
urlTax = urlTax.replace(/\{start\}/g, depart);
$.getJSON(urlTax, function(infos) {
taxonsCarte = taxonsCarte.concat(infos.taxons);
console.log("Nbre taxons :"+taxonsCarte.length);
chargerTaxons(depart+limite, infos.total);
});
} else {
if (nt == '*') {
afficherTaxons();
} else {
afficherNomPlante();
}
}
}
 
function afficherTaxons() {
// Ajout du nombre de plantes au titre
$('.plantes-nbre').text(taxonsCarte.length.formaterNombre());
$("#tpl-taxons-liste").tmpl({'taxons':taxonsCarte}).appendTo("#pl-corps");
$('.taxon').live('click', filtrerParTaxon);
}
 
function afficherNomPlante() {
if (nt != '*') {
var taxon = taxonsCarte[0];
$('.plante-titre').text('pour '+taxon.nom);
}
}
 
function afficherPanneauLateral() {
$('#panneau-lateral').width(300);
$('#pl-contenu').css('display', 'block');
$('#pl-ouverture').css('display', 'none');
$('#pl-fermeture').css('display', 'block');
$('#carte').css('left', '300px');
 
google.maps.event.trigger(map, 'resize');
};
 
function cacherPanneauLateral() {
$('#panneau-lateral').width(24);
$('#pl-contenu').css('display', 'none');
$('#pl-ouverture').css('display', 'block');
$('#pl-fermeture').css('display', 'none');
$('#carte').css('left', '24px');
google.maps.event.trigger(map, 'resize');
};
 
function ouvrirPopUp(url, nom) {
window.open(url, nom, 'scrollbars=yes,width=650,height=600,directories=no,location=no,menubar=no,status=no,toolbar=no');
};
 
function filtrerParTaxon() {
var ntAFiltrer = $('.nt', this).text();
infoBulle.close();
$('#taxon-'+nt).removeClass('taxon-actif');
if (nt == ntAFiltrer) {
nt = '*';
executerMarkerClusterer(pointsOrigine, boundsOrigine);
} else {
var url = stationsUrl+'&'+
'num_taxon='+ntAFiltrer+'&'+
'formatRetour=jsonP'+'&'+
'callback=?';
$.getJSON(url, function (stationsFiltrees) {
stations = stationsFiltrees;
nt = ntAFiltrer;
$('#taxon-'+nt).addClass('taxon-actif');
rafraichirCarte();
});
}
};
 
/*+--------------------------------------------------------------------------------------------------------+*/
// FONCTIONS UTILITAIRES
 
function arreter(event) {
if (event.stopPropagation) {
event.stopPropagation();
} else if (window.event) {
window.event.cancelBubble = true;
}
return false;
}
 
/**
* +-------------------------------------+
* Number.prototype.formaterNombre
* +-------------------------------------+
* Params (facultatifs):
* - Int decimales: nombre de decimales (exemple: 2)
* - String signe: le signe precedent les decimales (exemple: "," ou ".")
* - String separateurMilliers: comme son nom l'indique
* Returns:
* - String chaine formatee
* @author ::mastahbenus::
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> : ajout détection auto entier/flotant
* @souce http://www.javascriptfr.com/codes/FORMATER-NOMBRE-FACON-NUMBER-FORMAT-PHP_40060.aspx
*/
Number.prototype.formaterNombre = function (decimales, signe, separateurMilliers) {
var _sNombre = String(this), i, _sRetour = "", _sDecimales = "";
function is_int(nbre) {
nbre = nbre.replace(',', '.');
return !(parseFloat(nbre)-parseInt(nbre) > 0);
}
 
if (decimales == undefined) {
if (is_int(_sNombre)) {
decimales = 0;
} else {
decimales = 2;
}
}
if (signe == undefined) {
if (is_int(_sNombre)) {
signe = '';
} else {
signe = '.';
}
}
if (separateurMilliers == undefined) {
separateurMilliers = ' ';
}
function separeMilliers (sNombre) {
var sRetour = "";
while (sNombre.length % 3 != 0) {
sNombre = "0"+sNombre;
}
for (i = 0; i < sNombre.length; i += 3) {
if (i == sNombre.length-1) separateurMilliers = '';
sRetour += sNombre.substr(i, 3) + separateurMilliers;
}
while (sRetour.substr(0, 1) == "0") {
sRetour = sRetour.substr(1);
}
return sRetour.substr(0, sRetour.lastIndexOf(separateurMilliers));
}
if (_sNombre.indexOf('.') == -1) {
for (i = 0; i < decimales; i++) {
_sDecimales += "0";
}
_sRetour = separeMilliers(_sNombre) + signe + _sDecimales;
} else {
var sDecimalesTmp = (_sNombre.substr(_sNombre.indexOf('.')+1));
if (sDecimalesTmp.length > decimales) {
var nDecimalesManquantes = sDecimalesTmp.length - decimales;
var nDiv = 1;
for (i = 0; i < nDecimalesManquantes; i++) {
nDiv *= 10;
}
_sDecimales = Math.round(Number(sDecimalesTmp) / nDiv);
}
_sRetour = separeMilliers(_sNombre.substr(0, _sNombre.indexOf('.')))+String(signe)+_sDecimales;
}
return _sRetour;
}
 
function debug(objet) {
var msg = '';
if (objet != null) {
$.each(objet, function (cle, valeur) {
msg += cle+":"+valeur + "\n";
});
} else {
msg = "La variable vaut null.";
}
console.log(msg);
}
 
function trim (chaine) {
return chaine.replace(/^\s+/g, '').replace(/\s+$/g, '');
}
/tags/celw-v1.1/widget/modules/carto/squelettes/css/carto.css
New file
0,0 → 1,425
@charset "UTF-8";
html {
overflow:hidden;
}
body {
overflow:hidden;
padding:0;
margin:0;
width:100%;
height:100%;
font-family:Arial;
font-size:12px;
}
h1 {
font-size:1.6em;
}
h2 {
font-size:1.4em;
}
a, a:active, a:visited {
border-bottom:1px dotted #666;
color:#CCC;
text-decoration:none;
}
a:active {
outline:none;
}
a:focus {
outline:thin dotted;
}
a:hover {
color:#56B80E;
border-bottom:1px dotted #56B80E;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Présentation des listes de définitions */
dl {
width:100%;
}
dt {
float:left;
font-weight:bold;
text-align:top left;
margin-right:0.3em;
}
dd {
width:auto;
margin:0.5em 0;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Tableau : */
table {
border:1px solid gray;
border-collapse:collapse;
width:100%;
}
table thead, table tfoot, table tbody {
background-color:Gainsboro;
border:1px solid gray;
}
table tbody {
background-color:#FFF;
}
table th {
font-family:monospace;
border:1px dotted gray;
padding:5px;
background-color:Gainsboro;
}
table td {
font-family:arial;
border:1px dotted gray;
padding:5px;
text-align:left;
}
table caption {
font-family:sans-serif;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Tableau : tablesorter */
th.header {
background:url(../images/trie.png) no-repeat center right;
padding-right:20px;
}
th.headerSortUp {
background:url(../images/trie_croissant.png) no-repeat center right #56B80E;
color:white;
}
th.headerSortDown {
background:url(../images/trie_decroissant.png) no-repeat center right #56B80E;
color:white;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Générique */
.nettoyage{
clear:both;
}
hr.nettoyage{
visibility:hidden;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Carte */
#carte {
padding:0;
margin:0;
position:absolute;
top:35px;
left:24px;
right:0;
bottom:0;
overflow:auto;
}
.bouton {
background-color:white;
border:2px solid black;
cursor:pointer;
text-align:center;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Message de chargement */
#chargement {
margin:25px;
text-align:center;
}
#chargement img{
display:block;
margin:auto;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Avertissement */
#zone-avertissement {
background-color:#4A4B4C;
color:#CCC;
padding:12px;
text-align:justify;
line-height:16px;
}
#zone-avertissement h1{
margin:0;
}
#zone-avertissement a {
border-bottom:1px dotted gainsboro;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Carte titre */
#zone-titre {
padding:0;
margin:0;
position:absolute;
top:0;
left:0;
width:100%;
height:35px;
overflow:hidden;
background-color:#4A4B4C;
}
#zone-info {
position:absolute;
top:0;
right:8px;
width:48px;
text-align:right;
}
#zone-info img {
display:inline;
padding:4px;
margin:0;
border:none;
}
#carte-titre {
display:inline-block;
margin:0;
padding:0.2em;
color:#CCCCCC;
}
#carte-titre {/*Hack CSS fonctionne seulement dans ie6, 7 & 8 */
display:inline !hackCssIe6Et7;/*Hack CSS pour ie6 & ie7 */
display /*\**/:inline\9;/*Hack CSS pour ie8 */
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Panneau latéral */
#panneau-lateral {
padding:0;
margin:0;
position:absolute;
top:35px;
left:0;
bottom:0;
width:24px;
overflow:hidden;
background-color:#4A4B4C;
border-right:1px solid grey;
}
#pl-contenu {
display:none;
}
#pl-entete {
height:95px;
}
#pl-corps {
position:absolute;
top:105px;
bottom:0;
overflow:auto;
padding:5px;
width:290px;
}
#pl-ouverture, #pl-fermeture {
position:absolute;
top:0;
height:24px;
width:24px;
text-align:center;
cursor:pointer;
}
#pl-ouverture {
left:0;
background:url(../images/ouverture.png) no-repeat top left #4A4B4C;
height:100%;
}
#pl-fermeture {
display:none;
left:276px;
background:url(../images/fermeture.png) no-repeat top right #4A4B4C;
}
#pl-ouverture span, #pl-fermeture span{
display:none;
}
/* Panneau latéral : balises */
#panneau-lateral h2, #panneau-lateral p {
color:#CCCCCC;}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Liste des taxons de la carte */
#taxons {
color:#999;
}
#taxons .taxon-actif, #taxons .taxon-actif span {
color:#56B80E;
}
#taxons li span {
border-bottom:1px dotted #666;
color:#CCC;
}
#taxons li span:focus {
outline:thin dotted;
}
#taxons li span:hover {
color:#56B80E;
border-bottom:1px dotted #56B80E;
cursor:pointer;
}
.nt {
display:none;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Pop-up observations */
 
#observations {
overflow:none;
margin:-1px 0 0 0;
border: 1px solid #AAA;
border-radius:0 0 4px 4px;
}
#obs-pieds-page {
font-size:10px;
color:#CCC;
clear:both;
}
.ui-tabs {
padding:0;
}
.ui-widget-content {
border:0;
}
.ui-widget-header {
background:none;
border:0;
border-bottom:1px solid #AAA;
border-radius:0;
}
.ui-tabs-selected a {
border-bottom:1px solid white;
}
.ui-tabs-selected a:focus {
outline:0;
}
.ui-tabs .ui-tabs-panel {
padding:0.2em;
}
#obs h2 {
margin:0;
text-align:center;
}
#observations a {
color:#333;
border-bottom:1px dotted gainsboro;
}
#observations a:hover {
color:#56B80E;
border-bottom:1px dotted #56B80E;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Pop-up observations : liste */
.champ-nom-sci {
display:none;
}
.cel-img-principale img{
float:right;
height:75px;
padding:1px;
border:1px solid white;
}
#observations .cel-img:hover img{
border: 1px dotted #56B80E;
}
.cel-img-secondaire, .cel-infos{
display: none;
}
ol#obs-liste-lignes {
padding:5px;
margin:0;
}
.obs-conteneur{
counter-reset: item;
}
.obs-conteneur .nom-sci:before {
content: counter(item) ". ";
counter-increment: item;
display:block;
float:left;
}
.obs-conteneur li {
display: block;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Diaporama */
.cel-legende{
text-align:left;
}
.cel-legende-vei{
float:right;
}
.cel-legende p{
color: black;
font-size: 12px;
line-height: 18px;
margin: 0;
}
.cel-legende a, .cel-legende a:active, .cel-legende a:visited {
border-bottom:1px dotted gainsboro;
color:#333;
text-decoration:none;
background-image:none;
}
.cel-legende a:hover {
color:#56B80E;
border-bottom:1px dotted #56B80E;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Plugin Jquery Pagination */
.navigation {
padding:5px;
float:right;
}
.pagination {
font-size: 80%;
}
.pagination a {
text-decoration: none;
border: solid 1px #666;
color: #666;
background:gainsboro;
}
.pagination a:hover {
color: white;
background: #56B80E;
}
.pagination a, .pagination span {
display: block;
float: left;
padding: 0.3em 0.5em;
margin-right: 5px;
margin-bottom: 5px;
min-width:1em;
text-align:center;
}
.pagination .current {
background: #4A4B4C;
color: white;
border: solid 1px gainsboro;
}
.pagination .current.prev, .pagination .current.next{
color: #999;
border-color: #999;
background: gainsboro;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Formulaire de contact */
#form-contact input{
width:300px;
}
#form-contact textarea{
width:300px;
height:200px;
}
#form-contact #fc_envoyer{
width:50px;
float:right;
}
#form-contact #fc_annuler{
width:50px;
float:left;
}
#form-contact label.error {
color:red;
font-weight:bold;
}
#form-contact .info {
padding:5px;
background-color: #4A4B4C;
border: solid 1px #666;
color: white;
white-space: pre-wrap;
width: 300px;
}
/tags/celw-v1.1/widget/modules/carto
New file
Property changes:
Added: svn:ignore
+config.ini
/tags/celw-v1.1/widget/modules/photo/squelettes/css/photo.css
New file
0,0 → 1,112
@charset "UTF-8";
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Widget */
.cel-photo-contenu{
position:relative;
padding:0 5px;
margin:5px auto;
font-family:Arial,verdana,sans-serif;
background-color:#4A4B4C;
color:#CCC;
}
.cel-photo-contenu h1 {
margin:5px !important;
padding:0 !important;
font-size:16px !important;
color:white !important;
background-color:transparent !important;
background-image:none !important;
text-transform:none !important;
text-align:left !important;
}
.cel-photo-contenu h1 a{
color:#CCC !important;
}
.cel-photo-contenu h1 a:hover {
color:#56B80E !important;
border-bottom:1px dotted #56B80E;
}
.cel-photo-contenu h1 .cel-photo-flux{
width:16px;
height:20px;
}
.cel-photo-contenu img {
border:0 !important;
padding:0 !important;
margin:0 !important;
}
.cel-photo-contenu a, .cel-photo-contenu a:active, .cel-photo-contenu a:visited {
border-bottom:1px dotted #666;
color:#CCC;
text-decoration:none;
background-image:none;
}
.cel-photo-contenu a:active {
outline:none;
}
.cel-photo-contenu a:focus {
outline:thin dotted;
}
.cel-photo-contenu a:hover {
color:#56B80E;
border-bottom:1px dotted #56B80E;
}
.cel-photo-date-generation{
float:right;
font-size:8px;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Général */
.cel-photo-contenu .discretion {
color:grey;
font-family:arial;
font-size:11px;
font-weight:bold;
}
.cel-photo-contenu .nettoyage {
clear:both;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Galerie Photos CEL */
.cel-photo-contenu .cel-photo a{
float:left;
padding:2px;
border:1px solid white;
}
.cel-photo-contenu .cel-photo a:hover{
border:1px dotted #FD8C13;
}
.cel-photo-contenu .cel-photo a img{
float:left;
width:63px;
height:63px;
}
.cel-photo-contenu .cel-photo-extra a img{
height:auto;
}
.cel-photo-contenu .cel-infos {
display:none;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Diaporama */
.cel-legende{
text-align:left;
}
.cel-legende-vei{
float:right;
}
.cel-legende p{
color:black;
font-size:12px;
margin:5px 0;
}
.cel-legende a, .cel-legende a:active, .cel-legende a:visited {
border-bottom:1px dotted gainsboro;
color:#333;
text-decoration:none;
background-image:none;
}
.cel-legende a:hover {
color:#56B80E;
border-bottom:1px dotted #56B80E;
}
/tags/celw-v1.1/widget/modules/photo/squelettes/photo.tpl.html
New file
0,0 → 1,151
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Photographies publiques du CEL - Tela Botanica</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Content-style-type" content="text/css" />
<meta http-equiv="Content-script-type" content="text/javascript" />
<meta http-equiv="Content-language" content="fr" />
<meta name="revisit-after" content="15 days" />
<meta name="robots" content="index,follow" />
<meta name="author" content="Jean-Pascal MILCENT, Grégoire DUCHÉ" />
<meta name="keywords" content="Tela Botanica, photographie, CEL" />
<meta name="description" content="Widget de présentation des dernières photo publiées sur le Carnet en Ligne de Tela Botanica" />
 
<!-- Spécial mobile -->
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<!-- Favicones -->
<link rel="icon" type="image/png" href="http://www.tela-botanica.org/sites/commun/generique/images/favicones/tela_botanica.png" />
<link rel="shortcut icon" type="image/x-icon" href="http://www.tela-botanica.org/sites/commun/generique/images/favicones/tela_botanica.ico" />
<!-- Feuilles de styles -->
<link rel="stylesheet" type="text/css" href="http://www.tela-botanica.org/commun/jquery/fancybox/1.3.4/jquery.fancybox-1.3.4.css" media="screen" />
<link rel="stylesheet" type="text/css" href="<?=$url_css?>photo.css" media="screen" />
<style type="text/css">
html {
overflow:hidden;
}
body{
overflow:hidden;
padding:0;
margin:0;
width:100%;
height:100%;
background-color:#4A4B4C;
color:#CCC;
}
#cel-photo-contenu<?=$id?>, #cel-galerie-photo<?=$id?>{
width:<?=(($colonne * 69))?>px;
}
#cel-galerie-photo<?=$id?> #cel-photo-extra<?=$id?> img{
width:<?=(($colonne * 69)-6)?>px;
}
</style>
<!-- Javascript : bibliothèques -->
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/1.6/jquery-1.6.min.js"></script>
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/fancybox/1.3.4/jquery.fancybox-1.3.4.js"></script>
</head>
<body>
<!-- WIDGET:CEL:PHOTO - DEBUT -->
<div id="cel-photo-contenu<?=$id?>" class="cel-photo-contenu">
<?php if (isset($erreurs) || isset($informations)) : ?>
<h1>Erreur &amp; informations</h1>
<p>Impossible d'afficher le flux.</p>
<!-- Affichage des erreurs et messages d'information : -->
<?php if ($erreurs) : ?>
<?php foreach ($erreurs as $erreur) : ?>
<p class="erreur"><?=$erreur;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php if ($informations) : ?>
<?php foreach ($informations as $information) : ?>
<p class="info"><?=$information;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php else : ?>
<h1>
<? if (!empty($titre)) : ?>
<?=$titre?>
<? else : ?>
Dernières images du
<a href="http://www.tela-botanica.org/appli:cel" title="Carnet en Ligne" onclick="window.open(this.href);return false;">
CEL
</a>
<? endif; ?>
<a href="<?=$flux_rss_url?>"
class="cel-photo-flux"
title="Suivre les images"
onclick="window.open(this.href);return false;">
<img src="http://www.tela-botanica.org/sites/commun/generique/images/rss.png" alt="Suivre les images" />
</a>
</h1>
<div id="cel-galerie-photo<?=$id?>">
<?php foreach ($items as $item) : ?>
<div class="cel-photo">
<a href="<?=sprintf($item['url_tpl'], 'XL')?>" class="cel-img" title="<?=$item['titre']?> - Publiée le <?=$item['date']?> - GUID : <?=$item['guid']?>" rel="galerie-princ<?=$id?>">
<img src="<?=sprintf($item['url_tpl'], 'CRX2S')?>" alt="<?=$item['titre']?>"/>
</a>
<div id="cel-info-<?=$item['guid']?>" class="cel-infos">
<strong>
<a class="cel-img-titre" href="<?=$item['eflore_url']?>"
onclick="window.open(this.href);return false;"
title="Cliquez pour accéder à la fiche eFlore">
<?=$item['titre']?>
</a>
</strong><br />
<span class="cel-img-date">Publiée le <?=$item['date']?></span>
</div>
</div>
<?php endforeach; ?>
<?php if ($extra_actif) : ?>
<div id="cel-photo-extra<?=$id?>" class="cel-photo-extra cel-photo">
<a href="<?=sprintf($extra['url_tpl'], 'XL')?>" class="cel-img" title="<?=$extra['titre']?> - Publiée le <?=$extra['date']?> - GUID : <?=$extra['guid']?>" rel="galerie-princ<?=$id?>">
<img src="<?=sprintf($extra['url_tpl'], 'CRS')?>" alt="<?=$extra['titre']?>"/>
</a>
</div>
</div>
<?php endif ?>
<p class="cel-photo-pieds discretion nettoyage">
<span class="cel-photo-source">
Source :
<a href="http://www.tela-botanica.org/appli:cel" title="Carnet en Ligne" onclick="window.open(this.href);return false;">
CEL
</a>
</span>
<span class="cel-photo-date-generation">Au <?=strftime('%A %d %B %Y à %H:%M:%S')?></span>
</p>
<script type="text/Javascript">
//<![CDATA[
$('a.cel-img').attr('rel', 'galerie-princ<?=$id?>').fancybox({
transitionIn:'elastic',
transitionOut:'elastic',
speedIn :600,
speedOut:200,
overlayShow:true,
titleShow:true,
titlePosition:'inside',
titleFormat:function (titre, currentArray, currentIndex, currentOpts) {
var motif = /GUID : ([0-9]+)$/;
motif.exec(titre);
var guid = RegExp.$1;
var info = $('#cel-info-'+guid).clone().html();
var tpl =
'<div class="cel-legende">'+
'<p class="cel-legende-vei">'+'Image n°' + (currentIndex + 1) + ' sur ' + currentArray.length +'<\/p>'+
(titre && titre.length ? '<p>'+info+'<\/p>' : '' )+
'<\/div>';
return tpl;
}
});
//]]>
</script>
<?php endif; ?>
</div>
<!-- WIDGET:CEL:PHOTO - FIN -->
</body>
</html>
/tags/celw-v1.1/widget/modules/photo/squelettes/photo_ajax.tpl.html
New file
0,0 → 1,111
<!-- WIDGET:CEL:PHOTO - DEBUT -->
<div id="cel-photo-contenu<?=$id?>" class="cel-photo-contenu">
<!-- Feuilles de styles -->
<style type="text/css">
#cel-photo-contenu<?=$id?>, #cel-galerie-photo<?=$id?>{
width:<?=(($colonne * 69))?>px;
}
#cel-galerie-photo<?=$id?> #cel-photo-extra<?=$id?> img{
width:<?=(($colonne * 69)-6)?>px;
}
</style>
<?php if (isset($erreurs) || isset($informations)) : ?>
<h1>Erreur &amp; informations</h1>
<p>Impossible d'afficher le flux.</p>
<!-- Affichage des erreurs et messages d'information : -->
<?php if ($erreurs) : ?>
<?php foreach ($erreurs as $erreur) : ?>
<p class="erreur"><?=$erreur;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php if ($informations) : ?>
<?php foreach ($informations as $information) : ?>
<p class="info"><?=$information;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php else : ?>
<h1>
<? if (!empty($titre)) : ?>
<?=$titre?>
<? else : ?>
Dernières images du
<a href="http://www.tela-botanica.org/appli:cel" title="Carnet en Ligne" onclick="window.open(this.href);return false;">
CEL
</a>
<? endif; ?>
<a href="<?=$flux_rss_url?>"
class="cel-photo-flux<?=$id?>"
title="Suivre les images"
onclick="window.open(this.href);return false;">
<img src="http://www.tela-botanica.org/sites/commun/generique/images/rss.png" alt="Suivre les images" />
</a>
</h1>
<div id="cel-galerie-photo<?=$id?>">
<?php foreach ($items as $item) : ?>
<div class="cel-photo">
<a href="<?=sprintf($item['url_tpl'], 'XL')?>" class="cel-img" title="<?=$item['titre']?> - Publiée le <?=$item['date']?> - GUID : <?=$item['guid']?>" rel="galerie-princ<?=$id?>">
<img src="<?=sprintf($item['url_tpl'], 'CRX2S')?>" alt="<?=$item['titre']?>"/>
</a>
<div id="cel-info-<?=$item['guid']?>" class="cel-infos">
<strong>
<a class="cel-img-titre" href="<?=$item['eflore_url']?>"
onclick="window.open(this.href);return false;"
title="Cliquez pour accéder à la fiche eFlore">
<?=$item['titre']?>
</a>
</strong><br />
<span class="cel-img-date">Publiée le <?=$item['date']?></span>
</div>
</div>
<?php endforeach; ?>
<?php if ($extra_actif) : ?>
<div id="cel-photo-extra<?=$id?>" class="cel-photo cel-photo-extra">
<a href="<?=sprintf($extra['url_tpl'], 'XL')?>" class="cel-img" title="<?=$extra['titre']?> - Publiée le <?=$extra['date']?> - GUID : <?=$extra['guid']?>" rel="galerie-princ<?=$id?>">
<img src="<?=sprintf($extra['url_tpl'], 'CRS')?>" alt="<?=$extra['titre']?>"/>
</a>
</div>
</div>
<?php endif ?>
<p class="cel-photo-pieds discretion nettoyage">
<span class="cel-photo-source">
Source :
<a href="http://www.tela-botanica.org/appli:cel" title="Carnet en Ligne" onclick="window.open(this.href);return false;">
CEL
</a>
</span>
<span class="cel-photo-date-generation">Au <?=strftime('%A %d %B %Y à %H:%M:%S')?></span>
</p>
<script type="text/Javascript">
//<![CDATA[
$(document).ready(function() {
$('a.cel-img').attr('rel', 'galerie-princ<?=$id?>').fancybox({
transitionIn:'elastic',
transitionOut:'elastic',
speedIn :600,
speedOut:200,
overlayShow:true,
titleShow:true,
titlePosition:'inside',
titleFormat:function (titre, currentArray, currentIndex, currentOpts) {
var motif = /GUID : ([0-9]+)$/;
motif.exec(titre);
var guid = RegExp.$1;
var info = $('#cel-info-'+guid).clone().html();
var tpl =
'<div class="cel-legende">'+
'<p class="cel-legende-vei">'+'Image n°' + (currentIndex + 1) + ' sur ' + currentArray.length +'<\/p>'+
(titre && titre.length ? '<p>'+info+'<\/p>' : '' )+
'<\/div>';
return tpl;
}
});
});
//]]>
</script>
<?php endif; ?>
</div>
<!-- WIDGET:CEL:PHOTO - FIN -->
/tags/celw-v1.1/widget/modules/photo/Photo.php
New file
0,0 → 1,172
<?php
// declare(encoding='UTF-8');
/**
* Service affichant les dernières photo publiques du CEL ouvrable sous forme de diaporama.
* 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=AideCELWidgetPhoto
*
* Paramètres :
* ===> extra = booléen (1 ou 0) [par défaut : 1]
* Affiche / Cache la vignette en taille plus importante au bas du widget.
* ===> vignette = [0-9]+,[0-9]+ [par défaut : 4,3]
* Indique le nombre de vignette par ligne et le nombre de ligne.
*
* @author Jean-Pascal MILCENT <jpm@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) 2010, Tela Botanica (accueil@tela-botanica.org)
*/
class Photo extends WidgetCommun {
const DS = DIRECTORY_SEPARATOR;
const SERVICE_DEFAUT = 'photo';
private $flux_rss_url = null;
private $eflore_url_tpl = null;
/**
* Méthode appelée par défaut pour charger ce widget.
*/
public function executer() {
$retour = null;
// Pour la création de l'id du cache nous ne tenons pas compte du paramètre de l'url callback
unset($this->parametres['callback']);
extract($this->parametres);
 
if (!isset($mode)) {
$mode = self::SERVICE_DEFAUT;
}
$this->eflore_url_tpl = $this->config['photo']['efloreUrlTpl'];
$this->flux_rss_url = $this->config['photo']['fluxRssUrl'];
$cache_activation = $this->config['photo.cache']['activation'];
$cache_stockage = $this->config['photo.cache']['stockageDossier'];
$ddv = $this->config['photo.cache']['dureeDeVie'];
$cache = new Cache($cache_stockage, $ddv, $cache_activation);
$id_cache = 'photo-'.hash('adler32', print_r($this->parametres, true));
if (! $contenu = $cache->charger($id_cache)) {
$methode = $this->traiterNomMethodeExecuter($mode);
if (method_exists($this, $methode)) {
$retour = $this->$methode();
} else {
$this->messages[] = "Ce type de service '$methode' n'est pas disponible.";
}
$contenu = '';
if (is_null($retour)) {
$this->messages[] = 'La ressource demandée a retourné une valeur nulle.';
} else {
if (isset($retour['donnees'])) {
$squelette = dirname(__FILE__).self::DS.'squelettes'.self::DS.$retour['squelette'].'.tpl.html';
$contenu = $this->traiterSquelettePhp($squelette, $retour['donnees']);
$cache->sauver($id_cache, $contenu);
} else {
$this->messages[] = 'Les données à transmettre au squelette sont nulles.';
}
}
}
if (isset($_GET['callback'])) {
$this->envoyerJsonp(array('contenu' => $contenu));
} else {
$this->envoyer($contenu);
}
}
private function executerAjax() {
$widget = $this->executerPhoto();
$widget['squelette'] = 'photo_ajax';
return $widget;
}
private function executerPhoto() {
$widget = null;
extract($this->parametres);
$extra = (isset($extra) && $extra == 0) ? false : ($this->config['photo']['extraActif'] ? true : false);
$vignette = (isset($vignette) && preg_match('/^[0-9]+,[0-9]+$/', $vignette)) ? $vignette : '4,3';
$id = '-'.(isset($id) ? $id : '1');
$titre = (isset($titre) ? htmlentities(rawurldecode($titre)) : '');
list($colonne, $ligne) = explode(',', $vignette);
$this->flux_rss_url .= $this->traiterParametres();
if (@file_get_contents($this->flux_rss_url, false) != false) {
$xml = file_get_contents($this->flux_rss_url);
if ($xml) {
try {
$flux = new XmlFeedParser($xml);
$widget['donnees']['id'] = $id;
$widget['donnees']['titre'] = $titre;
$widget['donnees']['flux_rss_url'] = $this->flux_rss_url;
$widget['donnees']['url_css'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/photo/squelettes/css/');
$widget['donnees']['colonne'] = $colonne;
$widget['donnees']['extra_actif'] = $extra;
$max_photo = $colonne * $ligne;
$num = 0;
foreach ($flux as $entree) {
if ($num == $max_photo) {
break;
}
$item = array();
// Formatage date
$date = $entree->updated ? $entree->updated : null;
$date = $entree->pubDate ? $entree->pubDate : $date;
$item['date'] = strftime('%A %d %B %Y', $date);
$item['lien'] = $entree->link;
$item['url_tpl'] = preg_replace('/(XS|[SML]|X(?:[23]|)L|CR(?:|X2)S|C(?:|X)S)\.jpg$/', '%s.jpg', $entree->guid);
// Formatage titre
$item['titre'] = $entree->title;
$item['nn'] = '';
$item['eflore_url'] = '#';
if (preg_match('/\[nn([0-9]+)\]/', $entree->title, $match)) {
$item['nn'] = $match[1];
$item['eflore_url'] = sprintf($this->eflore_url_tpl, $item['nn']);
}
// Récupération du GUID
if (preg_match('/appli:cel-img:([0-9]+)[^.]+\.jpg$/', $entree->guid, $match)) {
$item['guid'] = (int) $match[1];
} else {
$item['guid'] = $entree->guid;
}
// Ajout aux items et si première photo à extra
if ($num == 0) {
$widget['donnees']['extra'] = $item;
}
$widget['donnees']['items'][$num++] = $item;
}
$widget['squelette'] = 'photo';
} catch (XmlFeedParserException $e) {
trigger_error('Flux invalide : '.$e->getMessage(), E_USER_WARNING);
}
} else {
$this->messages[] = "Fichier xml invalide.";
}
} else {
$this->messages[] = "L'URI suivante est invalide : $this->flux_rss_url.\n".
"Veuillez vérifier les paramêtres indiqués et la présence d'images associées.";
}
return $widget;
}
private function traiterParametres() {
$parametres_flux = '?';
$criteres = array('utilisateur', 'commune', 'dept', 'taxon', 'commentaire', 'date', 'tag', 'projet');
foreach($this->parametres as $nom_critere => $valeur_critere) {
if (in_array($nom_critere, $criteres)) {
$valeur_critere = str_replace(' ', '%20', $valeur_critere);
$parametres_flux .= $nom_critere.'='.$valeur_critere.'&';
}
}
if ($parametres_flux == '?') {
$parametres_flux = '';
} else {
$parametres_flux = rtrim($parametres_flux, '&');
}
return $parametres_flux;
}
}
?>
/tags/celw-v1.1/widget/modules/photo/config.defaut.ini
New file
0,0 → 1,19
[photo]
; Chemin pour l'autoload à ajouter
autoload = "bibliotheque/;bibliotheque/xml_feed_parser/1.0.4/;bibliotheque/xml_feed_parser/1.0.4/parsers/"
; URL ou chemin du flux RSS contenant les liens vers les photos
fluxRssUrl = "http://www.tela-botanica.org/service:cel:CelSyndicationImage/multicriteres/atom/M"
; Squelette d'url pour accéder à la fiche eFlore
efloreUrlTpl = "http://www.tela-botanica.org/eflore/BDNFF/4.02/nn/%s/illustration"
; Nombre de vignette à afficher : nombre de vignettes par ligne et nombre de lignes séparés par une vigule (ex. : 4,3).
vignette = 4,3
; Afficher/Cacher l'affichage en grand de la dernière image ajoutée
extraActif = true
 
[photo.cache]
; Active/Désactive le cache
activation = true
; Dossier où stocker les fichiers de cache du widget
stockageDossier = "/tmp"
; Durée de vie du fichier de cache
dureeDeVie = 86400
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserException.php
New file
0,0 → 1,36
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Keeps the exception class for XML_Feed_Parser.
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL
* @version CVS: $Id: Exception.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
/**
* XML_Feed_Parser_Exception is a simple extension of PEAR_Exception, existing
* to help with identification of the source of exceptions.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserException extends Exception {
 
}
 
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserAtom.php
New file
0,0 → 1,358
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Atom feed class for XML_Feed_Parser
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: Atom.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This is the class that determines how we manage Atom 1.0 feeds
*
* How we deal with constructs:
* date - return as unix datetime for use with the 'date' function unless specified otherwise
* text - return as is. optional parameter will give access to attributes
* person - defaults to name, but parameter based access
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserAtom extends XmlFeedParserType {
/**
* The URI of the RelaxNG schema used to (optionally) validate the feed
* @var string
*/
protected $relax = 'atom.rng';
 
/**
* We're likely to use XPath, so let's keep it global
* @var DOMXPath
*/
public $xpath;
 
/**
* When performing XPath queries we will use this prefix
* @var string
*/
private $xpathPrefix = '//';
 
/**
* The feed type we are parsing
* @var string
*/
public $version = 'Atom 1.0';
 
/**
* The class used to represent individual items
* @var string
*/
protected $itemClass = 'XmlFeedParserAtomElement';
/**
* The element containing entries
* @var string
*/
protected $itemElement = 'entry';
 
/**
* Here we map those elements we're not going to handle individually
* to the constructs they are. The optional second parameter in the array
* tells the parser whether to 'fall back' (not apt. at the feed level) or
* fail if the element is missing. If the parameter is not set, the function
* will simply return false and leave it to the client to decide what to do.
* @var array
*/
protected $map = array(
'author' => array('Person'),
'contributor' => array('Person'),
'icon' => array('Text'),
'logo' => array('Text'),
'id' => array('Text', 'fail'),
'rights' => array('Text'),
'subtitle' => array('Text'),
'title' => array('Text', 'fail'),
'updated' => array('Date', 'fail'),
'link' => array('Link'),
'generator' => array('Text'),
'category' => array('Category'),
'content' => array('Text'));
 
/**
* Here we provide a few mappings for those very special circumstances in
* which it makes sense to map back to the RSS2 spec. Key is RSS2 version
* value is an array consisting of the equivalent in atom and any attributes
* needed to make the mapping.
* @var array
*/
protected $compatMap = array(
'guid' => array('id'),
'links' => array('link'),
'tags' => array('category'),
'contributors' => array('contributor'));
 
/**
* Our constructor does nothing more than its parent.
*
* @param DOMDocument $xml A DOM object representing the feed
* @param bool (optional) $string Whether or not to validate this feed
*/
function __construct(DOMDocument $model, $strict = false) {
$this->model = $model;
 
if ($strict) {
if (! $this->relaxNGValidate()) {
throw new XML_Feed_Parser_Exception('Failed required validation');
}
}
 
$this->xpath = new DOMXPath($this->model);
$this->xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
$this->numberEntries = $this->count('entry');
}
 
/**
* Implement retrieval of an entry based on its ID for atom feeds.
*
* This function uses XPath to get the entry based on its ID. If DOMXPath::evaluate
* is available, we also use that to store a reference to the entry in the array
* used by getEntryByOffset so that method does not have to seek out the entry
* if it's requested that way.
*
* @param string $id any valid Atom ID.
* @return XML_Feed_Parser_AtomElement
*/
function getEntryById($id) {
if (isset($this->idMappings[$id])) {
return $this->entries[$this->idMappings[$id]];
}
 
$entries = $this->xpath->query("//atom:entry[atom:id='$id']");
 
if ($entries->length > 0) {
$xmlBase = $entries->item(0)->baseURI;
$entry = new $this->itemClass($entries->item(0), $this, $xmlBase);
if (in_array('evaluate', get_class_methods($this->xpath))) {
$offset = $this->xpath->evaluate("count(preceding-sibling::atom:entry)", $entries->item(0));
$this->entries[$offset] = $entry;
}
 
$this->idMappings[$id] = $entry;
 
return $entry;
}
}
 
/**
* Retrieves data from a person construct.
*
* Get a person construct. We default to the 'name' element but allow
* access to any of the elements.
*
* @param string $method The name of the person construct we want
* @param array $arguments An array which we hope gives a 'param'
* @return string|false
*/
protected function getPerson($method, $arguments) {
$offset = empty($arguments[0]) ? 0 : $arguments[0];
$parameter = empty($arguments[1]['param']) ? 'name' : $arguments[1]['param'];
$section = $this->model->getElementsByTagName($method);
if ($parameter == 'url') {
$parameter = 'uri';
}
 
if ($section->length <= $offset) {
return false;
}
 
$param = $section->item($offset)->getElementsByTagName($parameter);
if ($param->length == 0) {
return false;
}
return $param->item(0)->nodeValue;
}
 
/**
* Retrieves an element's content where that content is a text construct.
*
* Get a text construct. When calling this method, the two arguments
* allowed are 'offset' and 'attribute', so $parser->subtitle() would
* return the content of the element, while $parser->subtitle(false, 'type')
* would return the value of the type attribute.
*
* @todo Clarify overlap with getContent()
* @param string $method The name of the text construct we want
* @param array $arguments An array which we hope gives a 'param'
* @return string
*/
protected function getText($method, $arguments) {
$offset = empty($arguments[0]) ? 0: $arguments[0];
$attribute = empty($arguments[1]) ? false : $arguments[1];
$tags = $this->model->getElementsByTagName($method);
 
if ($tags->length <= $offset) {
return false;
}
 
$content = $tags->item($offset);
 
if (! $content->hasAttribute('type')) {
$content->setAttribute('type', 'text');
}
$type = $content->getAttribute('type');
 
if (! empty($attribute) and
! ($method == 'generator' and $attribute == 'name')) {
if ($content->hasAttribute($attribute)) {
return $content->getAttribute($attribute);
} else if ($attribute == 'href' and $content->hasAttribute('uri')) {
return $content->getAttribute('uri');
}
return false;
}
 
return $this->parseTextConstruct($content);
}
/**
* Extract content appropriately from atom text constructs
*
* Because of different rules applied to the content element and other text
* constructs, they are deployed as separate functions, but they share quite
* a bit of processing. This method performs the core common process, which is
* to apply the rules for different mime types in order to extract the content.
*
* @param DOMNode $content the text construct node to be parsed
* @return String
* @author James Stewart
**/
protected function parseTextConstruct(DOMNode $content) {
if ($content->hasAttribute('type')) {
$type = $content->getAttribute('type');
} else {
$type = 'text';
}
 
if (strpos($type, 'text/') === 0) {
$type = 'text';
}
 
switch ($type) {
case 'text':
case 'html':
return $content->textContent;
break;
case 'xhtml':
$container = $content->getElementsByTagName('div');
if ($container->length == 0) {
return false;
}
$contents = $container->item(0);
if ($contents->hasChildNodes()) {
/* Iterate through, applying xml:base and store the result */
$result = '';
foreach ($contents->childNodes as $node) {
$result .= $this->traverseNode($node);
}
return $result;
}
break;
case preg_match('@^[a-zA-Z]+/[a-zA-Z+]*xml@i', $type) > 0:
return $content;
break;
case 'application/octet-stream':
default:
return base64_decode(trim($content->nodeValue));
break;
}
return false;
}
/**
* Get a category from the entry.
*
* A feed or entry can have any number of categories. A category can have the
* attributes term, scheme and label.
*
* @param string $method The name of the text construct we want
* @param array $arguments An array which we hope gives a 'param'
* @return string
*/
function getCategory($method, $arguments) {
$offset = empty($arguments[0]) ? 0: $arguments[0];
$attribute = empty($arguments[1]) ? 'term' : $arguments[1];
$categories = $this->model->getElementsByTagName('category');
if ($categories->length <= $offset) {
$category = $categories->item($offset);
if ($category->hasAttribute($attribute)) {
return $category->getAttribute($attribute);
}
}
return false;
}
 
/**
* This element must be present at least once with rel="feed". This element may be
* present any number of further times so long as there is no clash. If no 'rel' is
* present and we're asked for one, we follow the example of the Universal Feed
* Parser and presume 'alternate'.
*
* @param int $offset the position of the link within the container
* @param string $attribute the attribute name required
* @param array an array of attributes to search by
* @return string the value of the attribute
*/
function getLink($offset = 0, $attribute = 'href', $params = false) {
if (is_array($params) and !empty($params)) {
$terms = array();
$alt_predicate = '';
$other_predicate = '';
 
foreach ($params as $key => $value) {
if ($key == 'rel' && $value == 'alternate') {
$alt_predicate = '[not(@rel) or @rel="alternate"]';
} else {
$terms[] = "@$key='$value'";
}
}
if (!empty($terms)) {
$other_predicate = '[' . join(' and ', $terms) . ']';
}
$query = $this->xpathPrefix . 'atom:link' . $alt_predicate . $other_predicate;
$links = $this->xpath->query($query);
} else {
$links = $this->model->getElementsByTagName('link');
}
if ($links->length > $offset) {
if ($links->item($offset)->hasAttribute($attribute)) {
$value = $links->item($offset)->getAttribute($attribute);
if ($attribute == 'href') {
$value = $this->addBase($value, $links->item($offset));
}
return $value;
} else if ($attribute == 'rel') {
return 'alternate';
}
}
return false;
}
}
 
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss09.php
New file
0,0 → 1,215
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* RSS0.9 class for XML_Feed_Parser
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS09.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This class handles RSS0.9 feeds.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
* @todo Find a Relax NG URI we can use
*/
class XmlFeedParserRss09 extends XmlFeedParserType {
/**
* The URI of the RelaxNG schema used to (optionally) validate the feed
* @var string
*/
protected $relax = '';
 
/**
* We're likely to use XPath, so let's keep it global
* @var DOMXPath
*/
protected $xpath;
 
/**
* The feed type we are parsing
* @var string
*/
public $version = 'RSS 0.9';
 
/**
* The class used to represent individual items
* @var string
*/
protected $itemClass = 'XmlFeedParserRss09Element';
/**
* The element containing entries
* @var string
*/
protected $itemElement = 'item';
 
/**
* Here we map those elements we're not going to handle individually
* to the constructs they are. The optional second parameter in the array
* tells the parser whether to 'fall back' (not apt. at the feed level) or
* fail if the element is missing. If the parameter is not set, the function
* will simply return false and leave it to the client to decide what to do.
* @var array
*/
protected $map = array(
'title' => array('Text'),
'link' => array('Text'),
'description' => array('Text'),
'image' => array('Image'),
'textinput' => array('TextInput'));
 
/**
* Here we map some elements to their atom equivalents. This is going to be
* quite tricky to pull off effectively (and some users' methods may vary)
* but is worth trying. The key is the atom version, the value is RSS2.
* @var array
*/
protected $compatMap = array(
'title' => array('title'),
'link' => array('link'),
'subtitle' => array('description'));
 
/**
* We will be working with multiple namespaces and it is useful to
* keep them together
* @var array
*/
protected $namespaces = array(
'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
 
/**
* Our constructor does nothing more than its parent.
*
* @todo RelaxNG validation
* @param DOMDocument $xml A DOM object representing the feed
* @param bool (optional) $string Whether or not to validate this feed
*/
function __construct(DOMDocument $model, $strict = false) {
$this->model = $model;
 
$this->xpath = new DOMXPath($model);
foreach ($this->namespaces as $key => $value) {
$this->xpath->registerNamespace($key, $value);
}
$this->numberEntries = $this->count('item');
}
 
/**
* Included for compatibility -- will not work with RSS 0.9
*
* This is not something that will work with RSS0.9 as it does not have
* clear restrictions on the global uniqueness of IDs.
*
* @param string $id any valid ID.
* @return false
*/
function getEntryById($id) {
return false;
}
 
/**
* Get details of the image associated with the feed.
*
* @return array|false an array simply containing the child elements
*/
protected function getImage() {
$images = $this->model->getElementsByTagName('image');
if ($images->length > 0) {
$image = $images->item(0);
$details = array();
if ($image->hasChildNodes()) {
$details = array(
'title' => $image->getElementsByTagName('title')->item(0)->value,
'link' => $image->getElementsByTagName('link')->item(0)->value,
'url' => $image->getElementsByTagName('url')->item(0)->value);
} else {
$details = array('title' => false,
'link' => false,
'url' => $image->attributes->getNamedItem('resource')->nodeValue);
}
$details = array_merge($details,
array('description' => false, 'height' => false, 'width' => false));
if (! empty($details)) {
return $details;
}
}
return false;
}
 
/**
* The textinput element is little used, but in the interests of
* completeness we will support it.
*
* @return array|false
*/
protected function getTextInput() {
$inputs = $this->model->getElementsByTagName('textinput');
if ($inputs->length > 0) {
$input = $inputs->item(0);
$results = array();
$results['title'] = isset(
$input->getElementsByTagName('title')->item(0)->value) ?
$input->getElementsByTagName('title')->item(0)->value : null;
$results['description'] = isset(
$input->getElementsByTagName('description')->item(0)->value) ?
$input->getElementsByTagName('description')->item(0)->value : null;
$results['name'] = isset(
$input->getElementsByTagName('name')->item(0)->value) ?
$input->getElementsByTagName('name')->item(0)->value : null;
$results['link'] = isset(
$input->getElementsByTagName('link')->item(0)->value) ?
$input->getElementsByTagName('link')->item(0)->value : null;
if (empty($results['link']) &&
$input->attributes->getNamedItem('resource')) {
$results['link'] = $input->attributes->getNamedItem('resource')->nodeValue;
}
if (! empty($results)) {
return $results;
}
}
return false;
}
/**
* Get details of a link from the feed.
*
* In RSS1 a link is a text element but in order to ensure that we resolve
* URLs properly we have a special function for them.
*
* @return string
*/
function getLink($offset = 0, $attribute = 'href', $params = false) {
$links = $this->model->getElementsByTagName('link');
if ($links->length <= $offset) {
return false;
}
$link = $links->item($offset);
return $this->addBase($link->nodeValue, $link);
}
 
/**
* Not implemented - no available validation.
*/
public function relaxNGValidate() {
return true;
}
}
 
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserType.php
New file
0,0 → 1,455
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Abstract class providing common methods for XML_Feed_Parser feeds.
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: Type.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This abstract class provides some general methods that are likely to be
* implemented exactly the same way for all feed types.
*
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
*/
abstract class XmlFeedParserType {
/**
* Where we store our DOM object for this feed
* @var DOMDocument
*/
public $model;
 
/**
* For iteration we'll want a count of the number of entries
* @var int
*/
public $numberEntries;
 
/**
* Where we store our entry objects once instantiated
* @var array
*/
public $entries = array();
 
/**
* Store mappings between entry IDs and their position in the feed
*/
public $idMappings = array();
 
/**
* Proxy to allow use of element names as method names
*
* We are not going to provide methods for every entry type so this
* function will allow for a lot of mapping. We rely pretty heavily
* on this to handle our mappings between other feed types and atom.
*
* @param string $call - the method attempted
* @param array $arguments - arguments to that method
* @return mixed
*/
function __call($call, $arguments = array()) {
if (! is_array($arguments)) {
$arguments = array();
}
 
if (isset($this->compatMap[$call])) {
$tempMap = $this->compatMap;
$tempcall = array_pop($tempMap[$call]);
if (! empty($tempMap)) {
$arguments = array_merge($arguments, $tempMap[$call]);
}
$call = $tempcall;
}
 
/* To be helpful, we allow a case-insensitive search for this method */
if (! isset($this->map[$call])) {
foreach (array_keys($this->map) as $key) {
if (strtoupper($key) == strtoupper($call)) {
$call = $key;
break;
}
}
}
 
if (empty($this->map[$call])) {
return false;
}
 
$method = 'get' . $this->map[$call][0];
if ($method == 'getLink') {
$offset = empty($arguments[0]) ? 0 : $arguments[0];
$attribute = empty($arguments[1]) ? 'href' : $arguments[1];
$params = isset($arguments[2]) ? $arguments[2] : array();
return $this->getLink($offset, $attribute, $params);
}
if (method_exists($this, $method)) {
return $this->$method($call, $arguments);
}
 
return false;
}
 
/**
* Proxy to allow use of element names as attribute names
*
* For many elements variable-style access will be desirable. This function
* provides for that.
*
* @param string $value - the variable required
* @return mixed
*/
function __get($value) {
return $this->__call($value, array());
}
 
/**
* Utility function to help us resolve xml:base values
*
* We have other methods which will traverse the DOM and work out the different
* xml:base declarations we need to be aware of. We then need to combine them.
* If a declaration starts with a protocol then we restart the string. If it
* starts with a / then we add on to the domain name. Otherwise we simply tag
* it on to the end.
*
* @param string $base - the base to add the link to
* @param string $link
*/
function combineBases($base, $link) {
if (preg_match('/^[A-Za-z]+:\/\//', $link)) {
return $link;
} else if (preg_match('/^\//', $link)) {
/* Extract domain and suffix link to that */
preg_match('/^([A-Za-z]+:\/\/.*)?\/*/', $base, $results);
$firstLayer = $results[0];
return $firstLayer . "/" . $link;
} else if (preg_match('/^\.\.\//', $base)) {
/* Step up link to find place to be */
preg_match('/^((\.\.\/)+)(.*)$/', $link, $bases);
$suffix = $bases[3];
$count = preg_match_all('/\.\.\//', $bases[1], $steps);
$url = explode("/", $base);
for ($i = 0; $i <= $count; $i++) {
array_pop($url);
}
return implode("/", $url) . "/" . $suffix;
} else if (preg_match('/^(?!\/$)/', $base)) {
$base = preg_replace('/(.*\/).*$/', '$1', $base) ;
return $base . $link;
} else {
/* Just stick it on the end */
return $base . $link;
}
}
 
/**
* Determine whether we need to apply our xml:base rules
*
* Gets us the xml:base data and then processes that with regard
* to our current link.
*
* @param string
* @param DOMElement
* @return string
*/
function addBase($link, $element) {
if (preg_match('/^[A-Za-z]+:\/\//', $link)) {
return $link;
}
 
return $this->combineBases($element->baseURI, $link);
}
 
/**
* Get an entry by its position in the feed, starting from zero
*
* As well as allowing the items to be iterated over we want to allow
* users to be able to access a specific entry. This is one of two ways of
* doing that, the other being by ID.
*
* @param int $offset
* @return XML_Feed_Parser_RSS1Element
*/
function getEntryByOffset($offset) {
if (! isset($this->entries[$offset])) {
$entries = $this->model->getElementsByTagName($this->itemElement);
if ($entries->length > $offset) {
$xmlBase = $entries->item($offset)->baseURI;
$this->entries[$offset] = new $this->itemClass(
$entries->item($offset), $this, $xmlBase);
if ($id = $this->entries[$offset]->id) {
$this->idMappings[$id] = $this->entries[$offset];
}
} else {
throw new XML_Feed_Parser_Exception('No entries found');
}
}
 
return $this->entries[$offset];
}
 
/**
* Return a date in seconds since epoch.
*
* Get a date construct. We use PHP's strtotime to return it as a unix datetime, which
* is the number of seconds since 1970-01-01 00:00:00.
*
* @link http://php.net/strtotime
* @param string $method The name of the date construct we want
* @param array $arguments Included for compatibility with our __call usage
* @return int|false datetime
*/
protected function getDate($method, $arguments) {
$time = $this->model->getElementsByTagName($method);
if ($time->length == 0 || empty($time->item(0)->nodeValue)) {
return false;
}
return strtotime($time->item(0)->nodeValue);
}
 
/**
* Get a text construct.
*
* @param string $method The name of the text construct we want
* @param array $arguments Included for compatibility with our __call usage
* @return string
*/
protected function getText($method, $arguments = array()) {
$tags = $this->model->getElementsByTagName($method);
if ($tags->length > 0) {
$value = $tags->item(0)->nodeValue;
return $value;
}
return false;
}
 
/**
* Apply various rules to retrieve category data.
*
* There is no single way of declaring a category in RSS1/1.1 as there is in RSS2
* and Atom. Instead the usual approach is to use the dublin core namespace to
* declare categories. For example delicious use both:
* <dc:subject>PEAR</dc:subject> and: <taxo:topics><rdf:Bag>
* <rdf:li resource="http://del.icio.us/tag/PEAR" /></rdf:Bag></taxo:topics>
* to declare a categorisation of 'PEAR'.
*
* We need to be sensitive to this where possible.
*
* @param string $call for compatibility with our overloading
* @param array $arguments - arg 0 is the offset, arg 1 is whether to return as array
* @return string|array|false
*/
protected function getCategory($call, $arguments) {
$categories = $this->model->getElementsByTagName('subject');
$offset = empty($arguments[0]) ? 0 : $arguments[0];
$array = empty($arguments[1]) ? false : true;
if ($categories->length <= $offset) {
return false;
}
if ($array) {
$list = array();
foreach ($categories as $category) {
array_push($list, $category->nodeValue);
}
return $list;
}
return $categories->item($offset)->nodeValue;
}
 
/**
* Count occurrences of an element
*
* This function will tell us how many times the element $type
* appears at this level of the feed.
*
* @param string $type the element we want to get a count of
* @return int
*/
protected function count($type) {
if ($tags = $this->model->getElementsByTagName($type)) {
return $tags->length;
}
return 0;
}
 
/**
* Part of our xml:base processing code
*
* We need a couple of methods to access XHTML content stored in feeds.
* This is because we dereference all xml:base references before returning
* the element. This method handles the attributes.
*
* @param DOMElement $node The DOM node we are iterating over
* @return string
*/
function processXHTMLAttributes($node) {
$return = '';
foreach ($node->attributes as $attribute) {
if ($attribute->name == 'src' or $attribute->name == 'href') {
$attribute->value = $this->addBase(htmlentities($attribute->value, NULL, 'utf-8'), $attribute);
}
if ($attribute->name == 'base') {
continue;
}
$return .= $attribute->name . '="' . htmlentities($attribute->value, NULL, 'utf-8') .'" ';
}
if (! empty($return)) {
return ' ' . trim($return);
}
return '';
}
 
/**
* Convert HTML entities based on the current character set.
*
* @param String
* @return String
*/
function processEntitiesForNodeValue($node) {
if (function_exists('iconv')) {
$current_encoding = $node->ownerDocument->encoding;
$value = iconv($current_encoding, 'UTF-8', $node->nodeValue);
} else if ($current_encoding == 'iso-8859-1') {
$value = utf8_encode($node->nodeValue);
} else {
$value = $node->nodeValue;
}
 
$decoded = html_entity_decode($value, NULL, 'UTF-8');
return htmlentities($decoded, NULL, 'UTF-8');
}
 
/**
* Part of our xml:base processing code
*
* We need a couple of methods to access XHTML content stored in feeds.
* This is because we dereference all xml:base references before returning
* the element. This method recurs through the tree descending from the node
* and builds our string.
*
* @param DOMElement $node The DOM node we are processing
* @return string
*/
function traverseNode($node) {
$content = '';
 
/* Add the opening of this node to the content */
if ($node instanceof DOMElement) {
$content .= '<' . $node->tagName .
$this->processXHTMLAttributes($node) . '>';
}
 
/* Process children */
if ($node->hasChildNodes()) {
foreach ($node->childNodes as $child) {
$content .= $this->traverseNode($child);
}
}
 
if ($node instanceof DOMText) {
$content .= $this->processEntitiesForNodeValue($node);
}
 
/* Add the closing of this node to the content */
if ($node instanceof DOMElement) {
$content .= '</' . $node->tagName . '>';
}
 
return $content;
}
 
/**
* Get content from RSS feeds (atom has its own implementation)
*
* The official way to include full content in an RSS1 entry is to use
* the content module's element 'encoded', and RSS2 feeds often duplicate that.
* Often, however, the 'description' element is used instead. We will offer that
* as a fallback. Atom uses its own approach and overrides this method.
*
* @return string|false
*/
protected function getContent() {
$options = array('encoded', 'description');
foreach ($options as $element) {
$test = $this->model->getElementsByTagName($element);
if ($test->length == 0) {
continue;
}
if ($test->item(0)->hasChildNodes()) {
$value = '';
foreach ($test->item(0)->childNodes as $child) {
if ($child instanceof DOMText) {
$value .= $child->nodeValue;
} else {
$simple = simplexml_import_dom($child);
$value .= $simple->asXML();
}
}
return $value;
} else if ($test->length > 0) {
return $test->item(0)->nodeValue;
}
}
return false;
}
 
/**
* Checks if this element has a particular child element.
*
* @param String
* @param Integer
* @return bool
**/
function hasKey($name, $offset = 0) {
$search = $this->model->getElementsByTagName($name);
return $search->length > $offset;
}
 
/**
* Return an XML serialization of the feed, should it be required. Most
* users however, will already have a serialization that they used when
* instantiating the object.
*
* @return string XML serialization of element
*/
function __toString() {
$simple = simplexml_import_dom($this->model);
return $simple->asXML();
}
/**
* Get directory holding RNG schemas. Method is based on that
* found in Contact_AddressBook.
*
* @return string PEAR data directory.
* @access public
* @static
*/
static function getSchemaDir() {
return dirname(__FILE__).'/../schemas';
}
 
public function relaxNGValidate() {
$dir = self::getSchemaDir();
$path = $dir . '/' . $this->relax;
return $this->model->relaxNGValidate($path);
}
}
 
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss1Element.php
New file
0,0 → 1,111
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* RSS1 Element class for XML_Feed_Parser
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS1Element.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/*
* This class provides support for RSS 1.0 entries. It will usually be called by
* XML_Feed_Parser_RSS1 with which it shares many methods.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserRss1Element extends XmlFeedParserRss1 {
/**
* This will be a reference to the parent object for when we want
* to use a 'fallback' rule
* @var XML_Feed_Parser_RSS1
*/
protected $parent;
 
/**
* Our specific element map
* @var array
*/
protected $map = array(
'id' => array('Id'),
'title' => array('Text'),
'link' => array('Link'),
'description' => array('Text'), # or dc:description
'category' => array('Category'),
'rights' => array('Text'), # dc:rights
'creator' => array('Text'), # dc:creator
'publisher' => array('Text'), # dc:publisher
'contributor' => array('Text'), # dc:contributor
'date' => array('Date'), # dc:date
'content' => array('Content')
);
 
/**
* Here we map some elements to their atom equivalents. This is going to be
* quite tricky to pull off effectively (and some users' methods may vary)
* but is worth trying. The key is the atom version, the value is RSS1.
* @var array
*/
protected $compatMap = array(
'content' => array('content'),
'updated' => array('lastBuildDate'),
'published' => array('date'),
'subtitle' => array('description'),
'updated' => array('date'),
'author' => array('creator'),
'contributor' => array('contributor')
);
 
/**
* Store useful information for later.
*
* @param DOMElement $element - this item as a DOM element
* @param XML_Feed_Parser_RSS1 $parent - the feed of which this is a member
*/
function __construct(DOMElement $element, $parent, $xmlBase = '') {
$this->model = $element;
$this->parent = $parent;
}
 
/**
* If an rdf:about attribute is specified, return it as an ID
*
* There is no established way of showing an ID for an RSS1 entry. We will
* simulate it using the rdf:about attribute of the entry element. This cannot
* be relied upon for unique IDs but may prove useful.
*
* @return string|false
*/
function getId() {
if ($this->model->attributes->getNamedItem('about')) {
return $this->model->attributes->getNamedItem('about')->nodeValue;
}
return false;
}
 
/**
* How RSS1 should support for enclosures is not clear. For now we will return
* false.
*
* @return false
*/
function getEnclosure() {
return false;
}
}
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss11Element.php
New file
0,0 → 1,145
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* RSS1 Element class for XML_Feed_Parser
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS11Element.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/*
* This class provides support for RSS 1.1 entries. It will usually be called by
* XML_Feed_Parser_RSS11 with which it shares many methods.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserRss11Element extends XmlFeedParserRss11 {
/**
* This will be a reference to the parent object for when we want
* to use a 'fallback' rule
* @var XML_Feed_Parser_RSS1
*/
protected $parent;
 
/**
* Our specific element map
* @var array
*/
protected $map = array(
'id' => array('Id'),
'title' => array('Text'),
'link' => array('Link'),
'description' => array('Text'), # or dc:description
'category' => array('Category'),
'rights' => array('Text'), # dc:rights
'creator' => array('Text'), # dc:creator
'publisher' => array('Text'), # dc:publisher
'contributor' => array('Text'), # dc:contributor
'date' => array('Date'), # dc:date
'content' => array('Content')
);
 
/**
* Here we map some elements to their atom equivalents. This is going to be
* quite tricky to pull off effectively (and some users' methods may vary)
* but is worth trying. The key is the atom version, the value is RSS1.
* @var array
*/
protected $compatMap = array(
'content' => array('content'),
'updated' => array('lastBuildDate'),
'published' => array('date'),
'subtitle' => array('description'),
'updated' => array('date'),
'author' => array('creator'),
'contributor' => array('contributor')
);
 
/**
* Store useful information for later.
*
* @param DOMElement $element - this item as a DOM element
* @param XML_Feed_Parser_RSS1 $parent - the feed of which this is a member
*/
function __construct(DOMElement $element, $parent, $xmlBase = '') {
$this->model = $element;
$this->parent = $parent;
}
 
/**
* If an rdf:about attribute is specified, return that as an ID
*
* There is no established way of showing an ID for an RSS1 entry. We will
* simulate it using the rdf:about attribute of the entry element. This cannot
* be relied upon for unique IDs but may prove useful.
*
* @return string|false
*/
function getId() {
if ($this->model->attributes->getNamedItem('about')) {
return $this->model->attributes->getNamedItem('about')->nodeValue;
}
return false;
}
 
/**
* Return the entry's content
*
* The official way to include full content in an RSS1 entry is to use
* the content module's element 'encoded'. Often, however, the 'description'
* element is used instead. We will offer that as a fallback.
*
* @return string|false
*/
function getContent() {
$options = array('encoded', 'description');
foreach ($options as $element) {
$test = $this->model->getElementsByTagName($element);
if ($test->length == 0) {
continue;
}
if ($test->item(0)->hasChildNodes()) {
$value = '';
foreach ($test->item(0)->childNodes as $child) {
if ($child instanceof DOMText) {
$value .= $child->nodeValue;
} else {
$simple = simplexml_import_dom($child);
$value .= $simple->asXML();
}
}
return $value;
} else if ($test->length > 0) {
return $test->item(0)->nodeValue;
}
}
return false;
}
/**
* How RSS1.1 should support for enclosures is not clear. For now we will return
* false.
*
* @return false
*/
function getEnclosure() {
return false;
}
}
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss2Element.php
New file
0,0 → 1,166
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Class representing entries in an RSS2 feed.
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS2Element.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This class provides support for RSS 2.0 entries. It will usually be
* called by XML_Feed_Parser_RSS2 with which it shares many methods.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserRss2Element extends XmlFeedParserRss2 {
/**
* This will be a reference to the parent object for when we want
* to use a 'fallback' rule
* @var XML_Feed_Parser_RSS2
*/
protected $parent;
 
/**
* Our specific element map
* @var array
*/
protected $map = array(
'title' => array('Text'),
'guid' => array('Guid'),
'description' => array('Text'),
'author' => array('Text'),
'comments' => array('Text'),
'enclosure' => array('Enclosure'),
'pubDate' => array('Date'),
'source' => array('Source'),
'link' => array('Text'),
'content' => array('Content'));
 
/**
* Here we map some elements to their atom equivalents. This is going to be
* quite tricky to pull off effectively (and some users' methods may vary)
* but is worth trying. The key is the atom version, the value is RSS2.
* @var array
*/
protected $compatMap = array(
'id' => array('guid'),
'updated' => array('lastBuildDate'),
'published' => array('pubdate'),
'guidislink' => array('guid', 'ispermalink'),
'summary' => array('description'));
 
/**
* Store useful information for later.
*
* @param DOMElement $element - this item as a DOM element
* @param XML_Feed_Parser_RSS2 $parent - the feed of which this is a member
*/
function __construct(DOMElement $element, $parent, $xmlBase = '') {
$this->model = $element;
$this->parent = $parent;
}
 
/**
* Get the value of the guid element, if specified
*
* guid is the closest RSS2 has to atom's ID. It is usually but not always a
* URI. The one attribute that RSS2 can posess is 'ispermalink' which specifies
* whether the guid is itself dereferencable. Use of guid is not obligatory,
* but is advisable. To get the guid you would call $item->id() (for atom
* compatibility) or $item->guid(). To check if this guid is a permalink call
* $item->guid("ispermalink").
*
* @param string $method - the method name being called
* @param array $params - parameters required
* @return string the guid or value of ispermalink
*/
protected function getGuid($method, $params) {
$attribute = (isset($params[0]) and $params[0] == 'ispermalink') ?
true : false;
$tag = $this->model->getElementsByTagName('guid');
if ($tag->length > 0) {
if ($attribute) {
if ($tag->hasAttribute("ispermalink")) {
return $tag->getAttribute("ispermalink");
}
}
return $tag->item(0)->nodeValue;
}
return false;
}
 
/**
* Access details of file enclosures
*
* The RSS2 spec is ambiguous as to whether an enclosure element must be
* unique in a given entry. For now we will assume it needn't, and allow
* for an offset.
*
* @param string $method - the method being called
* @param array $parameters - we expect the first of these to be our offset
* @return array|false
*/
protected function getEnclosure($method, $parameters) {
$encs = $this->model->getElementsByTagName('enclosure');
$offset = isset($parameters[0]) ? $parameters[0] : 0;
if ($encs->length > $offset) {
try {
if (! $encs->item($offset)->hasAttribute('url')) {
return false;
}
$attrs = $encs->item($offset)->attributes;
return array(
'url' => $attrs->getNamedItem('url')->value,
'length' => $attrs->getNamedItem('length')->value,
'type' => $attrs->getNamedItem('type')->value);
} catch (Exception $e) {
return false;
}
}
return false;
}
 
/**
* Get the entry source if specified
*
* source is an optional sub-element of item. Like atom:source it tells
* us about where the entry came from (eg. if it's been copied from another
* feed). It is not a rich source of metadata in the same way as atom:source
* and while it would be good to maintain compatibility by returning an
* XML_Feed_Parser_RSS2 element, it makes a lot more sense to return an array.
*
* @return array|false
*/
protected function getSource() {
$get = $this->model->getElementsByTagName('source');
if ($get->length) {
$source = $get->item(0);
$array = array(
'content' => $source->nodeValue);
foreach ($source->attributes as $attribute) {
$array[$attribute->name] = $attribute->value;
}
return $array;
}
return false;
}
}
 
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss1.php
New file
0,0 → 1,267
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* RSS1 class for XML_Feed_Parser
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS1.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This class handles RSS1.0 feeds.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
* @todo Find a Relax NG URI we can use
*/
class XmlFeedParserRss1 extends XmlFeedParserType {
/**
* The URI of the RelaxNG schema used to (optionally) validate the feed
* @var string
*/
protected $relax = 'rss10.rng';
 
/**
* We're likely to use XPath, so let's keep it global
* @var DOMXPath
*/
protected $xpath;
 
/**
* The feed type we are parsing
* @var string
*/
public $version = 'RSS 1.0';
 
/**
* The class used to represent individual items
* @var string
*/
protected $itemClass = 'XmlFeedParserRss1Element';
/**
* The element containing entries
* @var string
*/
protected $itemElement = 'item';
 
/**
* Here we map those elements we're not going to handle individually
* to the constructs they are. The optional second parameter in the array
* tells the parser whether to 'fall back' (not apt. at the feed level) or
* fail if the element is missing. If the parameter is not set, the function
* will simply return false and leave it to the client to decide what to do.
* @var array
*/
protected $map = array(
'title' => array('Text'),
'link' => array('Text'),
'description' => array('Text'),
'image' => array('Image'),
'textinput' => array('TextInput'),
'updatePeriod' => array('Text'),
'updateFrequency' => array('Text'),
'updateBase' => array('Date'),
'rights' => array('Text'), # dc:rights
'description' => array('Text'), # dc:description
'creator' => array('Text'), # dc:creator
'publisher' => array('Text'), # dc:publisher
'contributor' => array('Text'), # dc:contributor
'date' => array('Date') # dc:contributor
);
 
/**
* Here we map some elements to their atom equivalents. This is going to be
* quite tricky to pull off effectively (and some users' methods may vary)
* but is worth trying. The key is the atom version, the value is RSS2.
* @var array
*/
protected $compatMap = array(
'title' => array('title'),
'link' => array('link'),
'subtitle' => array('description'),
'author' => array('creator'),
'updated' => array('date'));
 
/**
* We will be working with multiple namespaces and it is useful to
* keep them together
* @var array
*/
protected $namespaces = array(
'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
'rss' => 'http://purl.org/rss/1.0/',
'dc' => 'http://purl.org/rss/1.0/modules/dc/',
'content' => 'http://purl.org/rss/1.0/modules/content/',
'sy' => 'http://web.resource.org/rss/1.0/modules/syndication/');
 
/**
* Our constructor does nothing more than its parent.
*
* @param DOMDocument $xml A DOM object representing the feed
* @param bool (optional) $string Whether or not to validate this feed
*/
function __construct(DOMDocument $model, $strict = false) {
$this->model = $model;
if ($strict) {
if (! $this->relaxNGValidate()) {
throw new XML_Feed_Parser_Exception('Failed required validation');
}
}
 
$this->xpath = new DOMXPath($model);
foreach ($this->namespaces as $key => $value) {
$this->xpath->registerNamespace($key, $value);
}
$this->numberEntries = $this->count('item');
}
 
/**
* Allows retrieval of an entry by ID where the rdf:about attribute is used
*
* This is not really something that will work with RSS1 as it does not have
* clear restrictions on the global uniqueness of IDs. We will employ the
* _very_ hit and miss method of selecting entries based on the rdf:about
* attribute. If DOMXPath::evaluate is available, we also use that to store
* a reference to the entry in the array used by getEntryByOffset so that
* method does not have to seek out the entry if it's requested that way.
*
* @param string $id any valid ID.
* @return XML_Feed_Parser_RSS1Element
*/
function getEntryById($id) {
if (isset($this->idMappings[$id])) {
return $this->entries[$this->idMappings[$id]];
}
 
$entries = $this->xpath->query("//rss:item[@rdf:about='$id']");
if ($entries->length > 0) {
$classname = $this->itemClass;
$entry = new $classname($entries->item(0), $this);
if (in_array('evaluate', get_class_methods($this->xpath))) {
$offset = $this->xpath->evaluate("count(preceding-sibling::rss:item)", $entries->item(0));
$this->entries[$offset] = $entry;
}
$this->idMappings[$id] = $entry;
return $entry;
}
return false;
}
 
/**
* Get details of the image associated with the feed.
*
* @return array|false an array simply containing the child elements
*/
protected function getImage() {
$images = $this->model->getElementsByTagName('image');
if ($images->length > 0) {
$image = $images->item(0);
$details = array();
if ($image->hasChildNodes()) {
$details = array(
'title' => $image->getElementsByTagName('title')->item(0)->value,
'link' => $image->getElementsByTagName('link')->item(0)->value,
'url' => $image->getElementsByTagName('url')->item(0)->value);
} else {
$details = array('title' => false,
'link' => false,
'url' => $image->attributes->getNamedItem('resource')->nodeValue);
}
$details = array_merge($details, array('description' => false, 'height' => false, 'width' => false));
if (! empty($details)) {
return $details;
}
}
return false;
}
 
/**
* The textinput element is little used, but in the interests of
* completeness we will support it.
*
* @return array|false
*/
protected function getTextInput() {
$inputs = $this->model->getElementsByTagName('textinput');
if ($inputs->length > 0) {
$input = $inputs->item(0);
$results = array();
$results['title'] = isset(
$input->getElementsByTagName('title')->item(0)->value) ?
$input->getElementsByTagName('title')->item(0)->value : null;
$results['description'] = isset(
$input->getElementsByTagName('description')->item(0)->value) ?
$input->getElementsByTagName('description')->item(0)->value : null;
$results['name'] = isset(
$input->getElementsByTagName('name')->item(0)->value) ?
$input->getElementsByTagName('name')->item(0)->value : null;
$results['link'] = isset(
$input->getElementsByTagName('link')->item(0)->value) ?
$input->getElementsByTagName('link')->item(0)->value : null;
if (empty($results['link']) and
$input->attributes->getNamedItem('resource')) {
$results['link'] =
$input->attributes->getNamedItem('resource')->nodeValue;
}
if (! empty($results)) {
return $results;
}
}
return false;
}
 
/**
* Employs various techniques to identify the author
*
* Dublin Core provides the dc:creator, dc:contributor, and dc:publisher
* elements for defining authorship in RSS1. We will try each of those in
* turn in order to simulate the atom author element and will return it
* as text.
*
* @return array|false
*/
function getAuthor() {
$options = array('creator', 'contributor', 'publisher');
foreach ($options as $element) {
$test = $this->model->getElementsByTagName($element);
if ($test->length > 0) {
return $test->item(0)->value;
}
}
return false;
}
/**
* Retrieve a link
*
* In RSS1 a link is a text element but in order to ensure that we resolve
* URLs properly we have a special function for them.
*
* @return string
*/
function getLink($offset = 0, $attribute = 'href', $params = false) {
$links = $this->model->getElementsByTagName('link');
if ($links->length <= $offset) {
return false;
}
$link = $links->item($offset);
return $this->addBase($link->nodeValue, $link);
}
}
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss11.php
New file
0,0 → 1,266
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* RSS1.1 class for XML_Feed_Parser
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS11.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This class handles RSS1.1 feeds. RSS1.1 is documented at:
* http://inamidst.com/rss1.1/
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
* @todo Support for RDF:List
* @todo Ensure xml:lang is accessible to users
*/
class XmlFeedParserRss11 extends XmlFeedParserType {
/**
* The URI of the RelaxNG schema used to (optionally) validate the feed
* @var string
*/
protected $relax = 'rss11.rng';
 
/**
* We're likely to use XPath, so let's keep it global
* @var DOMXPath
*/
protected $xpath;
 
/**
* The feed type we are parsing
* @var string
*/
public $version = 'RSS 1.0';
 
/**
* The class used to represent individual items
* @var string
*/
protected $itemClass = 'XmlFeedParserRss11Element';
/**
* The element containing entries
* @var string
*/
protected $itemElement = 'item';
 
/**
* Here we map those elements we're not going to handle individually
* to the constructs they are. The optional second parameter in the array
* tells the parser whether to 'fall back' (not apt. at the feed level) or
* fail if the element is missing. If the parameter is not set, the function
* will simply return false and leave it to the client to decide what to do.
* @var array
*/
protected $map = array(
'title' => array('Text'),
'link' => array('Text'),
'description' => array('Text'),
'image' => array('Image'),
'updatePeriod' => array('Text'),
'updateFrequency' => array('Text'),
'updateBase' => array('Date'),
'rights' => array('Text'), # dc:rights
'description' => array('Text'), # dc:description
'creator' => array('Text'), # dc:creator
'publisher' => array('Text'), # dc:publisher
'contributor' => array('Text'), # dc:contributor
'date' => array('Date') # dc:contributor
);
 
/**
* Here we map some elements to their atom equivalents. This is going to be
* quite tricky to pull off effectively (and some users' methods may vary)
* but is worth trying. The key is the atom version, the value is RSS2.
* @var array
*/
protected $compatMap = array(
'title' => array('title'),
'link' => array('link'),
'subtitle' => array('description'),
'author' => array('creator'),
'updated' => array('date'));
 
/**
* We will be working with multiple namespaces and it is useful to
* keep them together. We will retain support for some common RSS1.0 modules
* @var array
*/
protected $namespaces = array(
'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
'rss' => 'http://purl.org/net/rss1.1#',
'dc' => 'http://purl.org/rss/1.0/modules/dc/',
'content' => 'http://purl.org/rss/1.0/modules/content/',
'sy' => 'http://web.resource.org/rss/1.0/modules/syndication/');
 
/**
* Our constructor does nothing more than its parent.
*
* @param DOMDocument $xml A DOM object representing the feed
* @param bool (optional) $string Whether or not to validate this feed
*/
function __construct(DOMDocument $model, $strict = false) {
$this->model = $model;
 
if ($strict) {
if (! $this->relaxNGValidate()) {
throw new XML_Feed_Parser_Exception('Failed required validation');
}
}
 
$this->xpath = new DOMXPath($model);
foreach ($this->namespaces as $key => $value) {
$this->xpath->registerNamespace($key, $value);
}
$this->numberEntries = $this->count('item');
}
 
/**
* Attempts to identify an element by ID given by the rdf:about attribute
*
* This is not really something that will work with RSS1.1 as it does not have
* clear restrictions on the global uniqueness of IDs. We will employ the
* _very_ hit and miss method of selecting entries based on the rdf:about
* attribute. Please note that this is even more hit and miss with RSS1.1 than
* with RSS1.0 since RSS1.1 does not require the rdf:about attribute for items.
*
* @param string $id any valid ID.
* @return XML_Feed_Parser_RSS1Element
*/
function getEntryById($id) {
if (isset($this->idMappings[$id])) {
return $this->entries[$this->idMappings[$id]];
}
 
$entries = $this->xpath->query("//rss:item[@rdf:about='$id']");
if ($entries->length > 0) {
$classname = $this->itemClass;
$entry = new $classname($entries->item(0), $this);
return $entry;
}
return false;
}
 
/**
* Get details of the image associated with the feed.
*
* @return array|false an array simply containing the child elements
*/
protected function getImage() {
$images = $this->model->getElementsByTagName('image');
if ($images->length > 0) {
$image = $images->item(0);
$details = array();
if ($image->hasChildNodes()) {
$details = array(
'title' => $image->getElementsByTagName('title')->item(0)->value,
'url' => $image->getElementsByTagName('url')->item(0)->value);
if ($image->getElementsByTagName('link')->length > 0) {
$details['link'] =
$image->getElementsByTagName('link')->item(0)->value;
}
} else {
$details = array('title' => false,
'link' => false,
'url' => $image->attributes->getNamedItem('resource')->nodeValue);
}
$details = array_merge($details,
array('description' => false, 'height' => false, 'width' => false));
if (! empty($details)) {
return $details;
}
}
return false;
}
 
/**
* The textinput element is little used, but in the interests of
* completeness we will support it.
*
* @return array|false
*/
protected function getTextInput() {
$inputs = $this->model->getElementsByTagName('textinput');
if ($inputs->length > 0) {
$input = $inputs->item(0);
$results = array();
$results['title'] = isset(
$input->getElementsByTagName('title')->item(0)->value) ?
$input->getElementsByTagName('title')->item(0)->value : null;
$results['description'] = isset(
$input->getElementsByTagName('description')->item(0)->value) ?
$input->getElementsByTagName('description')->item(0)->value : null;
$results['name'] = isset(
$input->getElementsByTagName('name')->item(0)->value) ?
$input->getElementsByTagName('name')->item(0)->value : null;
$results['link'] = isset(
$input->getElementsByTagName('link')->item(0)->value) ?
$input->getElementsByTagName('link')->item(0)->value : null;
if (empty($results['link']) and
$input->attributes->getNamedItem('resource')) {
$results['link'] = $input->attributes->getNamedItem('resource')->nodeValue;
}
if (! empty($results)) {
return $results;
}
}
return false;
}
 
/**
* Attempts to discern authorship
*
* Dublin Core provides the dc:creator, dc:contributor, and dc:publisher
* elements for defining authorship in RSS1. We will try each of those in
* turn in order to simulate the atom author element and will return it
* as text.
*
* @return array|false
*/
function getAuthor() {
$options = array('creator', 'contributor', 'publisher');
foreach ($options as $element) {
$test = $this->model->getElementsByTagName($element);
if ($test->length > 0) {
return $test->item(0)->value;
}
}
return false;
}
/**
* Retrieve a link
*
* In RSS1 a link is a text element but in order to ensure that we resolve
* URLs properly we have a special function for them.
*
* @return string
*/
function getLink($offset = 0, $attribute = 'href', $params = false) {
$links = $this->model->getElementsByTagName('link');
if ($links->length <= $offset) {
return false;
}
$link = $links->item($offset);
return $this->addBase($link->nodeValue, $link);
}
}
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss2.php
New file
0,0 → 1,323
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Class representing feed-level data for an RSS2 feed
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS2.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This class handles RSS2 feeds.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserRss2 extends XmlFeedParserType {
/**
* The URI of the RelaxNG schema used to (optionally) validate the feed
* @var string
*/
protected $relax = 'rss20.rng';
 
/**
* We're likely to use XPath, so let's keep it global
* @var DOMXPath
*/
protected $xpath;
 
/**
* The feed type we are parsing
* @var string
*/
public $version = 'RSS 2.0';
 
/**
* The class used to represent individual items
* @var string
*/
protected $itemClass = 'XmlFeedParserRss2Element';
/**
* The element containing entries
* @var string
*/
protected $itemElement = 'item';
 
/**
* Here we map those elements we're not going to handle individually
* to the constructs they are. The optional second parameter in the array
* tells the parser whether to 'fall back' (not apt. at the feed level) or
* fail if the element is missing. If the parameter is not set, the function
* will simply return false and leave it to the client to decide what to do.
* @var array
*/
protected $map = array(
'ttl' => array('Text'),
'pubDate' => array('Date'),
'lastBuildDate' => array('Date'),
'title' => array('Text'),
'link' => array('Link'),
'description' => array('Text'),
'language' => array('Text'),
'copyright' => array('Text'),
'managingEditor' => array('Text'),
'webMaster' => array('Text'),
'category' => array('Text'),
'generator' => array('Text'),
'docs' => array('Text'),
'ttl' => array('Text'),
'image' => array('Image'),
'skipDays' => array('skipDays'),
'skipHours' => array('skipHours'));
 
/**
* Here we map some elements to their atom equivalents. This is going to be
* quite tricky to pull off effectively (and some users' methods may vary)
* but is worth trying. The key is the atom version, the value is RSS2.
* @var array
*/
protected $compatMap = array(
'title' => array('title'),
'rights' => array('copyright'),
'updated' => array('lastBuildDate'),
'subtitle' => array('description'),
'date' => array('pubDate'),
'author' => array('managingEditor'));
 
protected $namespaces = array(
'dc' => 'http://purl.org/rss/1.0/modules/dc/',
'content' => 'http://purl.org/rss/1.0/modules/content/');
 
/**
* Our constructor does nothing more than its parent.
*
* @param DOMDocument $xml A DOM object representing the feed
* @param bool (optional) $string Whether or not to validate this feed
*/
function __construct(DOMDocument $model, $strict = false) {
$this->model = $model;
 
if ($strict) {
if (! $this->relaxNGValidate()) {
throw new XmlFeedParserException('Failed required validation');
}
}
 
$this->xpath = new DOMXPath($this->model);
foreach ($this->namespaces as $key => $value) {
$this->xpath->registerNamespace($key, $value);
}
$this->numberEntries = $this->count('item');
}
 
/**
* Retrieves an entry by ID, if the ID is specified with the guid element
*
* This is not really something that will work with RSS2 as it does not have
* clear restrictions on the global uniqueness of IDs. But we can emulate
* it by allowing access based on the 'guid' element. If DOMXPath::evaluate
* is available, we also use that to store a reference to the entry in the array
* used by getEntryByOffset so that method does not have to seek out the entry
* if it's requested that way.
*
* @param string $id any valid ID.
* @return XML_Feed_Parser_RSS2Element
*/
function getEntryById($id) {
if (isset($this->idMappings[$id])) {
return $this->entries[$this->idMappings[$id]];
}
 
$entries = $this->xpath->query("//item[guid='$id']");
if ($entries->length > 0) {
$entry = new $this->itemElement($entries->item(0), $this);
if (in_array('evaluate', get_class_methods($this->xpath))) {
$offset = $this->xpath->evaluate("count(preceding-sibling::item)", $entries->item(0));
$this->entries[$offset] = $entry;
}
$this->idMappings[$id] = $entry;
return $entry;
}
}
 
/**
* Get a category from the element
*
* The category element is a simple text construct which can occur any number
* of times. We allow access by offset or access to an array of results.
*
* @param string $call for compatibility with our overloading
* @param array $arguments - arg 0 is the offset, arg 1 is whether to return as array
* @return string|array|false
*/
function getCategory($call, $arguments = array()) {
$categories = $this->model->getElementsByTagName('category');
$offset = empty($arguments[0]) ? 0 : $arguments[0];
$array = empty($arguments[1]) ? false : true;
if ($categories->length <= $offset) {
return false;
}
if ($array) {
$list = array();
foreach ($categories as $category) {
array_push($list, $category->nodeValue);
}
return $list;
}
return $categories->item($offset)->nodeValue;
}
 
/**
* Get details of the image associated with the feed.
*
* @return array|false an array simply containing the child elements
*/
protected function getImage() {
$images = $this->xpath->query("//image");
if ($images->length > 0) {
$image = $images->item(0);
$desc = $image->getElementsByTagName('description');
$description = $desc->length ? $desc->item(0)->nodeValue : false;
$heigh = $image->getElementsByTagName('height');
$height = $heigh->length ? $heigh->item(0)->nodeValue : false;
$widt = $image->getElementsByTagName('width');
$width = $widt->length ? $widt->item(0)->nodeValue : false;
return array(
'title' => $image->getElementsByTagName('title')->item(0)->nodeValue,
'link' => $image->getElementsByTagName('link')->item(0)->nodeValue,
'url' => $image->getElementsByTagName('url')->item(0)->nodeValue,
'description' => $description,
'height' => $height,
'width' => $width);
}
return false;
}
 
/**
* The textinput element is little used, but in the interests of
* completeness...
*
* @return array|false
*/
function getTextInput() {
$inputs = $this->model->getElementsByTagName('input');
if ($inputs->length > 0) {
$input = $inputs->item(0);
return array(
'title' => $input->getElementsByTagName('title')->item(0)->value,
'description' =>
$input->getElementsByTagName('description')->item(0)->value,
'name' => $input->getElementsByTagName('name')->item(0)->value,
'link' => $input->getElementsByTagName('link')->item(0)->value);
}
return false;
}
 
/**
* Utility function for getSkipDays and getSkipHours
*
* This is a general function used by both getSkipDays and getSkipHours. It simply
* returns an array of the values of the children of the appropriate tag.
*
* @param string $tagName The tag name (getSkipDays or getSkipHours)
* @return array|false
*/
protected function getSkips($tagName) {
$hours = $this->model->getElementsByTagName($tagName);
if ($hours->length == 0) {
return false;
}
$skipHours = array();
foreach($hours->item(0)->childNodes as $hour) {
if ($hour instanceof DOMElement) {
array_push($skipHours, $hour->nodeValue);
}
}
return $skipHours;
}
 
/**
* Retrieve skipHours data
*
* The skiphours element provides a list of hours on which this feed should
* not be checked. We return an array of those hours (integers, 24 hour clock)
*
* @return array
*/
function getSkipHours() {
return $this->getSkips('skipHours');
}
 
/**
* Retrieve skipDays data
*
* The skipdays element provides a list of days on which this feed should
* not be checked. We return an array of those days.
*
* @return array
*/
function getSkipDays() {
return $this->getSkips('skipDays');
}
 
/**
* Return content of the little-used 'cloud' element
*
* The cloud element is rarely used. It is designed to provide some details
* of a location to update the feed.
*
* @return array an array of the attributes of the element
*/
function getCloud() {
$cloud = $this->model->getElementsByTagName('cloud');
if ($cloud->length == 0) {
return false;
}
$cloudData = array();
foreach ($cloud->item(0)->attributes as $attribute) {
$cloudData[$attribute->name] = $attribute->value;
}
return $cloudData;
}
/**
* Get link URL
*
* In RSS2 a link is a text element but in order to ensure that we resolve
* URLs properly we have a special function for them. We maintain the
* parameter used by the atom getLink method, though we only use the offset
* parameter.
*
* @param int $offset The position of the link within the feed. Starts from 0
* @param string $attribute The attribute of the link element required
* @param array $params An array of other parameters. Not used.
* @return string
*/
function getLink($offset, $attribute = 'href', $params = array()) {
$links = $this->model->getElementsByTagName('link');
 
if ($links->length <= $offset) {
return false;
}
$link = $links->item($offset);
return $this->addBase($link->nodeValue, $link);
}
}
 
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserAtomElement.php
New file
0,0 → 1,254
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* AtomElement class for XML_Feed_Parser package
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: AtomElement.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This class provides support for atom entries. It will usually be called by
* XML_Feed_Parser_Atom with which it shares many methods.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserAtomElement extends XmlFeedParserAtom {
/**
* This will be a reference to the parent object for when we want
* to use a 'fallback' rule
* @var XML_Feed_Parser_Atom
*/
protected $parent;
 
/**
* When performing XPath queries we will use this prefix
* @var string
*/
private $xpathPrefix = '';
/**
* xml:base values inherited by the element
* @var string
*/
protected $xmlBase;
 
/**
* Here we provide a few mappings for those very special circumstances in
* which it makes sense to map back to the RSS2 spec or to manage other
* compatibilities (eg. with the Univeral Feed Parser). Key is the other version's
* name for the command, value is an array consisting of the equivalent in our atom
* api and any attributes needed to make the mapping.
* @var array
*/
protected $compatMap = array(
'guid' => array('id'),
'links' => array('link'),
'tags' => array('category'),
'contributors' => array('contributor'));
/**
* Our specific element map
* @var array
*/
protected $map = array(
'author' => array('Person', 'fallback'),
'contributor' => array('Person'),
'id' => array('Text', 'fail'),
'published' => array('Date'),
'updated' => array('Date', 'fail'),
'title' => array('Text', 'fail'),
'rights' => array('Text', 'fallback'),
'summary' => array('Text'),
'content' => array('Content'),
'link' => array('Link'),
'enclosure' => array('Enclosure'),
'category' => array('Category'));
 
/**
* Store useful information for later.
*
* @param DOMElement $element - this item as a DOM element
* @param XML_Feed_Parser_Atom $parent - the feed of which this is a member
*/
function __construct(DOMElement $element, $parent, $xmlBase = '') {
$this->model = $element;
$this->parent = $parent;
$this->xmlBase = $xmlBase;
$this->xpathPrefix = "//atom:entry[atom:id='" . $this->id . "']/";
$this->xpath = $this->parent->xpath;
}
 
/**
* Provides access to specific aspects of the author data for an atom entry
*
* Author data at the entry level is more complex than at the feed level.
* If atom:author is not present for the entry we need to look for it in
* an atom:source child of the atom:entry. If it's not there either, then
* we look to the parent for data.
*
* @param array
* @return string
*/
function getAuthor($arguments) {
/* Find out which part of the author data we're looking for */
if (isset($arguments['param'])) {
$parameter = $arguments['param'];
} else {
$parameter = 'name';
}
$test = $this->model->getElementsByTagName('author');
if ($test->length > 0) {
$item = $test->item(0);
return $item->getElementsByTagName($parameter)->item(0)->nodeValue;
}
$source = $this->model->getElementsByTagName('source');
if ($source->length > 0) {
$test = $this->model->getElementsByTagName('author');
if ($test->length > 0) {
$item = $test->item(0);
return $item->getElementsByTagName($parameter)->item(0)->nodeValue;
}
}
return $this->parent->getAuthor($arguments);
}
 
/**
* Returns the content of the content element or info on a specific attribute
*
* This element may or may not be present. It cannot be present more than
* once. It may have a 'src' attribute, in which case there's no content
* If not present, then the entry must have link with rel="alternate".
* If there is content we return it, if not and there's a 'src' attribute
* we return the value of that instead. The method can take an 'attribute'
* argument, in which case we return the value of that attribute if present.
* eg. $item->content("type") will return the type of the content. It is
* recommended that all users check the type before getting the content to
* ensure that their script is capable of handling the type of returned data.
* (data carried in the content element can be either 'text', 'html', 'xhtml',
* or any standard MIME type).
*
* @return string|false
*/
protected function getContent($method, $arguments = array()) {
$attribute = empty($arguments[0]) ? false : $arguments[0];
$tags = $this->model->getElementsByTagName('content');
 
if ($tags->length == 0) {
return false;
}
 
$content = $tags->item(0);
 
if (! $content->hasAttribute('type')) {
$content->setAttribute('type', 'text');
}
if (! empty($attribute)) {
return $content->getAttribute($attribute);
}
 
$type = $content->getAttribute('type');
 
if (! empty($attribute)) {
if ($content->hasAttribute($attribute))
{
return $content->getAttribute($attribute);
}
return false;
}
 
if ($content->hasAttribute('src')) {
return $content->getAttribute('src');
}
 
return $this->parseTextConstruct($content);
}
 
/**
* For compatibility, this method provides a mapping to access enclosures.
*
* The Atom spec doesn't provide for an enclosure element, but it is
* generally supported using the link element with rel='enclosure'.
*
* @param string $method - for compatibility with our __call usage
* @param array $arguments - for compatibility with our __call usage
* @return array|false
*/
function getEnclosure($method, $arguments = array()) {
$offset = isset($arguments[0]) ? $arguments[0] : 0;
$query = "//atom:entry[atom:id='" . $this->getText('id', false) .
"']/atom:link[@rel='enclosure']";
 
$encs = $this->parent->xpath->query($query);
if ($encs->length > $offset) {
try {
if (! $encs->item($offset)->hasAttribute('href')) {
return false;
}
$attrs = $encs->item($offset)->attributes;
$length = $encs->item($offset)->hasAttribute('length') ?
$encs->item($offset)->getAttribute('length') : false;
return array(
'url' => $attrs->getNamedItem('href')->value,
'type' => $attrs->getNamedItem('type')->value,
'length' => $length);
} catch (Exception $e) {
return false;
}
}
return false;
}
/**
* Get details of this entry's source, if available/relevant
*
* Where an atom:entry is taken from another feed then the aggregator
* is supposed to include an atom:source element which replicates at least
* the atom:id, atom:title, and atom:updated metadata from the original
* feed. Atom:source therefore has a very similar structure to atom:feed
* and if we find it we will return it as an XML_Feed_Parser_Atom object.
*
* @return XML_Feed_Parser_Atom|false
*/
function getSource() {
$test = $this->model->getElementsByTagName('source');
if ($test->length == 0) {
return false;
}
$source = new XML_Feed_Parser_Atom($test->item(0));
}
 
/**
* Get the entry as an XML string
*
* Return an XML serialization of the feed, should it be required. Most
* users however, will already have a serialization that they used when
* instantiating the object.
*
* @return string XML serialization of element
*/
function __toString() {
$simple = simplexml_import_dom($this->model);
return $simple->asXML();
}
}
 
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/parsers/XmlFeedParserRss09Element.php
New file
0,0 → 1,59
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* RSS0.9 Element class for XML_Feed_Parser
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL 2.1
* @version CVS: $Id: RSS09Element.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/*
* This class provides support for RSS 0.9 entries. It will usually be called by
* XML_Feed_Parser_RSS09 with which it shares many methods.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParserRss09Element extends XmlFeedParserRss09 {
/**
* This will be a reference to the parent object for when we want
* to use a 'fallback' rule
* @var XML_Feed_Parser_RSS09
*/
protected $parent;
 
/**
* Our specific element map
* @var array
*/
protected $map = array(
'title' => array('Text'),
'link' => array('Link'));
 
/**
* Store useful information for later.
*
* @param DOMElement $element - this item as a DOM element
* @param XML_Feed_Parser_RSS1 $parent - the feed of which this is a member
*/
function __construct(DOMElement $element, $parent, $xmlBase = '') {
$this->model = $element;
$this->parent = $parent;
}
}
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/schemas/atom.rng
New file
0,0 → 1,598
<?xml version="1.0" encoding="UTF-8"?>
<!--
-*- rnc -*-
RELAX NG Compact Syntax Grammar for the
Atom Format Specification Version 11
-->
<grammar ns="http://www.w3.org/1999/xhtml" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:s="http://www.ascc.net/xml/schematron" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<start>
<choice>
<ref name="atomFeed"/>
<ref name="atomEntry"/>
</choice>
</start>
<!-- Common attributes -->
<define name="atomCommonAttributes">
<optional>
<attribute name="xml:base">
<ref name="atomUri"/>
</attribute>
</optional>
<optional>
<attribute name="xml:lang">
<ref name="atomLanguageTag"/>
</attribute>
</optional>
<zeroOrMore>
<ref name="undefinedAttribute"/>
</zeroOrMore>
</define>
<!-- Text Constructs -->
<define name="atomPlainTextConstruct">
<ref name="atomCommonAttributes"/>
<optional>
<attribute name="type">
<choice>
<value>text</value>
<value>html</value>
</choice>
</attribute>
</optional>
<text/>
</define>
<define name="atomXHTMLTextConstruct">
<ref name="atomCommonAttributes"/>
<attribute name="type">
<value>xhtml</value>
</attribute>
<ref name="xhtmlDiv"/>
</define>
<define name="atomTextConstruct">
<choice>
<ref name="atomPlainTextConstruct"/>
<ref name="atomXHTMLTextConstruct"/>
</choice>
</define>
<!-- Person Construct -->
<define name="atomPersonConstruct">
<ref name="atomCommonAttributes"/>
<interleave>
<element name="atom:name">
<text/>
</element>
<optional>
<element name="atom:uri">
<ref name="atomUri"/>
</element>
</optional>
<optional>
<element name="atom:email">
<ref name="atomEmailAddress"/>
</element>
</optional>
<zeroOrMore>
<ref name="extensionElement"/>
</zeroOrMore>
</interleave>
</define>
<!-- Date Construct -->
<define name="atomDateConstruct">
<ref name="atomCommonAttributes"/>
<data type="dateTime"/>
</define>
<!-- atom:feed -->
<define name="atomFeed">
<element name="atom:feed">
<s:rule context="atom:feed">
<s:assert test="atom:author or not(atom:entry[not(atom:author)])">An atom:feed must have an atom:author unless all of its atom:entry children have an atom:author.</s:assert>
</s:rule>
<ref name="atomCommonAttributes"/>
<interleave>
<zeroOrMore>
<ref name="atomAuthor"/>
</zeroOrMore>
<zeroOrMore>
<ref name="atomCategory"/>
</zeroOrMore>
<zeroOrMore>
<ref name="atomContributor"/>
</zeroOrMore>
<optional>
<ref name="atomGenerator"/>
</optional>
<optional>
<ref name="atomIcon"/>
</optional>
<ref name="atomId"/>
<zeroOrMore>
<ref name="atomLink"/>
</zeroOrMore>
<optional>
<ref name="atomLogo"/>
</optional>
<optional>
<ref name="atomRights"/>
</optional>
<optional>
<ref name="atomSubtitle"/>
</optional>
<ref name="atomTitle"/>
<ref name="atomUpdated"/>
<zeroOrMore>
<ref name="extensionElement"/>
</zeroOrMore>
</interleave>
<zeroOrMore>
<ref name="atomEntry"/>
</zeroOrMore>
</element>
</define>
<!-- atom:entry -->
<define name="atomEntry">
<element name="atom:entry">
<s:rule context="atom:entry">
<s:assert test="atom:link[@rel='alternate'] or atom:link[not(@rel)] or atom:content">An atom:entry must have at least one atom:link element with a rel attribute of 'alternate' or an atom:content.</s:assert>
</s:rule>
<s:rule context="atom:entry">
<s:assert test="atom:author or ../atom:author or atom:source/atom:author">An atom:entry must have an atom:author if its feed does not.</s:assert>
</s:rule>
<ref name="atomCommonAttributes"/>
<interleave>
<zeroOrMore>
<ref name="atomAuthor"/>
</zeroOrMore>
<zeroOrMore>
<ref name="atomCategory"/>
</zeroOrMore>
<optional>
<ref name="atomContent"/>
</optional>
<zeroOrMore>
<ref name="atomContributor"/>
</zeroOrMore>
<ref name="atomId"/>
<zeroOrMore>
<ref name="atomLink"/>
</zeroOrMore>
<optional>
<ref name="atomPublished"/>
</optional>
<optional>
<ref name="atomRights"/>
</optional>
<optional>
<ref name="atomSource"/>
</optional>
<optional>
<ref name="atomSummary"/>
</optional>
<ref name="atomTitle"/>
<ref name="atomUpdated"/>
<zeroOrMore>
<ref name="extensionElement"/>
</zeroOrMore>
</interleave>
</element>
</define>
<!-- atom:content -->
<define name="atomInlineTextContent">
<element name="atom:content">
<ref name="atomCommonAttributes"/>
<optional>
<attribute name="type">
<choice>
<value>text</value>
<value>html</value>
</choice>
</attribute>
</optional>
<zeroOrMore>
<text/>
</zeroOrMore>
</element>
</define>
<define name="atomInlineXHTMLContent">
<element name="atom:content">
<ref name="atomCommonAttributes"/>
<attribute name="type">
<value>xhtml</value>
</attribute>
<ref name="xhtmlDiv"/>
</element>
</define>
<define name="atomInlineOtherContent">
<element name="atom:content">
<ref name="atomCommonAttributes"/>
<optional>
<attribute name="type">
<ref name="atomMediaType"/>
</attribute>
</optional>
<zeroOrMore>
<choice>
<text/>
<ref name="anyElement"/>
</choice>
</zeroOrMore>
</element>
</define>
<define name="atomOutOfLineContent">
<element name="atom:content">
<ref name="atomCommonAttributes"/>
<optional>
<attribute name="type">
<ref name="atomMediaType"/>
</attribute>
</optional>
<attribute name="src">
<ref name="atomUri"/>
</attribute>
<empty/>
</element>
</define>
<define name="atomContent">
<choice>
<ref name="atomInlineTextContent"/>
<ref name="atomInlineXHTMLContent"/>
<ref name="atomInlineOtherContent"/>
<ref name="atomOutOfLineContent"/>
</choice>
</define>
<!-- atom:author -->
<define name="atomAuthor">
<element name="atom:author">
<ref name="atomPersonConstruct"/>
</element>
</define>
<!-- atom:category -->
<define name="atomCategory">
<element name="atom:category">
<ref name="atomCommonAttributes"/>
<attribute name="term"/>
<optional>
<attribute name="scheme">
<ref name="atomUri"/>
</attribute>
</optional>
<optional>
<attribute name="label"/>
</optional>
<ref name="undefinedContent"/>
</element>
</define>
<!-- atom:contributor -->
<define name="atomContributor">
<element name="atom:contributor">
<ref name="atomPersonConstruct"/>
</element>
</define>
<!-- atom:generator -->
<define name="atomGenerator">
<element name="atom:generator">
<ref name="atomCommonAttributes"/>
<optional>
<attribute name="uri">
<ref name="atomUri"/>
</attribute>
</optional>
<optional>
<attribute name="version"/>
</optional>
<text/>
</element>
</define>
<!-- atom:icon -->
<define name="atomIcon">
<element name="atom:icon">
<ref name="atomCommonAttributes"/>
<ref name="atomUri"/>
</element>
</define>
<!-- atom:id -->
<define name="atomId">
<element name="atom:id">
<ref name="atomCommonAttributes"/>
<ref name="atomUri"/>
</element>
</define>
<!-- atom:logo -->
<define name="atomLogo">
<element name="atom:logo">
<ref name="atomCommonAttributes"/>
<ref name="atomUri"/>
</element>
</define>
<!-- atom:link -->
<define name="atomLink">
<element name="atom:link">
<ref name="atomCommonAttributes"/>
<attribute name="href">
<ref name="atomUri"/>
</attribute>
<optional>
<attribute name="rel">
<choice>
<ref name="atomNCName"/>
<ref name="atomUri"/>
</choice>
</attribute>
</optional>
<optional>
<attribute name="type">
<ref name="atomMediaType"/>
</attribute>
</optional>
<optional>
<attribute name="hreflang">
<ref name="atomLanguageTag"/>
</attribute>
</optional>
<optional>
<attribute name="title"/>
</optional>
<optional>
<attribute name="length"/>
</optional>
<ref name="undefinedContent"/>
</element>
</define>
<!-- atom:published -->
<define name="atomPublished">
<element name="atom:published">
<ref name="atomDateConstruct"/>
</element>
</define>
<!-- atom:rights -->
<define name="atomRights">
<element name="atom:rights">
<ref name="atomTextConstruct"/>
</element>
</define>
<!-- atom:source -->
<define name="atomSource">
<element name="atom:source">
<ref name="atomCommonAttributes"/>
<interleave>
<zeroOrMore>
<ref name="atomAuthor"/>
</zeroOrMore>
<zeroOrMore>
<ref name="atomCategory"/>
</zeroOrMore>
<zeroOrMore>
<ref name="atomContributor"/>
</zeroOrMore>
<optional>
<ref name="atomGenerator"/>
</optional>
<optional>
<ref name="atomIcon"/>
</optional>
<optional>
<ref name="atomId"/>
</optional>
<zeroOrMore>
<ref name="atomLink"/>
</zeroOrMore>
<optional>
<ref name="atomLogo"/>
</optional>
<optional>
<ref name="atomRights"/>
</optional>
<optional>
<ref name="atomSubtitle"/>
</optional>
<optional>
<ref name="atomTitle"/>
</optional>
<optional>
<ref name="atomUpdated"/>
</optional>
<zeroOrMore>
<ref name="extensionElement"/>
</zeroOrMore>
</interleave>
</element>
</define>
<!-- atom:subtitle -->
<define name="atomSubtitle">
<element name="atom:subtitle">
<ref name="atomTextConstruct"/>
</element>
</define>
<!-- atom:summary -->
<define name="atomSummary">
<element name="atom:summary">
<ref name="atomTextConstruct"/>
</element>
</define>
<!-- atom:title -->
<define name="atomTitle">
<element name="atom:title">
<ref name="atomTextConstruct"/>
</element>
</define>
<!-- atom:updated -->
<define name="atomUpdated">
<element name="atom:updated">
<ref name="atomDateConstruct"/>
</element>
</define>
<!-- Low-level simple types -->
<define name="atomNCName">
<data type="string">
<param name="minLength">1</param>
<param name="pattern">[^:]*</param>
</data>
</define>
<!-- Whatever a media type is, it contains at least one slash -->
<define name="atomMediaType">
<data type="string">
<param name="pattern">.+/.+</param>
</data>
</define>
<!-- As defined in RFC 3066 -->
<define name="atomLanguageTag">
<data type="string">
<param name="pattern">[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8})*</param>
</data>
</define>
<!--
Unconstrained; it's not entirely clear how IRI fit into
xsd:anyURI so let's not try to constrain it here
-->
<define name="atomUri">
<text/>
</define>
<!-- Whatever an email address is, it contains at least one @ -->
<define name="atomEmailAddress">
<data type="string">
<param name="pattern">.+@.+</param>
</data>
</define>
<!-- Simple Extension -->
<define name="simpleExtensionElement">
<element>
<anyName>
<except>
<nsName ns="http://www.w3.org/2005/Atom"/>
</except>
</anyName>
<text/>
</element>
</define>
<!-- Structured Extension -->
<define name="structuredExtensionElement">
<element>
<anyName>
<except>
<nsName ns="http://www.w3.org/2005/Atom"/>
</except>
</anyName>
<choice>
<group>
<oneOrMore>
<attribute>
<anyName/>
</attribute>
</oneOrMore>
<zeroOrMore>
<choice>
<text/>
<ref name="anyElement"/>
</choice>
</zeroOrMore>
</group>
<group>
<zeroOrMore>
<attribute>
<anyName/>
</attribute>
</zeroOrMore>
<group>
<optional>
<text/>
</optional>
<oneOrMore>
<ref name="anyElement"/>
</oneOrMore>
<zeroOrMore>
<choice>
<text/>
<ref name="anyElement"/>
</choice>
</zeroOrMore>
</group>
</group>
</choice>
</element>
</define>
<!-- Other Extensibility -->
<define name="extensionElement">
<choice>
<ref name="simpleExtensionElement"/>
<ref name="structuredExtensionElement"/>
</choice>
</define>
<define name="undefinedAttribute">
<attribute>
<anyName>
<except>
<name>xml:base</name>
<name>xml:lang</name>
<nsName ns=""/>
</except>
</anyName>
</attribute>
</define>
<define name="undefinedContent">
<zeroOrMore>
<choice>
<text/>
<ref name="anyForeignElement"/>
</choice>
</zeroOrMore>
</define>
<define name="anyElement">
<element>
<anyName/>
<zeroOrMore>
<choice>
<attribute>
<anyName/>
</attribute>
<text/>
<ref name="anyElement"/>
</choice>
</zeroOrMore>
</element>
</define>
<define name="anyForeignElement">
<element>
<anyName>
<except>
<nsName ns="http://www.w3.org/2005/Atom"/>
</except>
</anyName>
<zeroOrMore>
<choice>
<attribute>
<anyName/>
</attribute>
<text/>
<ref name="anyElement"/>
</choice>
</zeroOrMore>
</element>
</define>
<!-- XHTML -->
<define name="anyXHTML">
<element>
<nsName/>
<zeroOrMore>
<choice>
<attribute>
<anyName/>
</attribute>
<text/>
<ref name="anyXHTML"/>
</choice>
</zeroOrMore>
</element>
</define>
<define name="xhtmlDiv">
<element name="xhtml:div">
<zeroOrMore>
<choice>
<attribute>
<anyName/>
</attribute>
<text/>
<ref name="anyXHTML"/>
</choice>
</zeroOrMore>
</element>
</define>
</grammar>
<!-- EOF -->
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/schemas/README
New file
0,0 → 1,9
Most of these schemas are only available in RNC (RelaxNG, Compact) format.
 
libxml (and therefor PHP) only supports RelaxNG - the XML version.
 
To update these, you will need a conversion utility, like trang (http://www.thaiopensource.com/relaxng/trang.html).
 
 
 
clockwerx@clockwerx-desktop:~/trang$ java -jar trang.jar -I rnc -O rng http://atompub.org/2005/08/17/atom.rnc atom.rng
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/schemas/rss10.rng
New file
0,0 → 1,113
<?xml version='1.0' encoding='UTF-8'?>
<!-- http://www.xml.com/lpt/a/2002/01/23/relaxng.html -->
<!-- http://www.oasis-open.org/committees/relax-ng/tutorial-20011203.html -->
<!-- http://www.zvon.org/xxl/XMLSchemaTutorial/Output/ser_wildcards_st8.html -->
 
<grammar xmlns='http://relaxng.org/ns/structure/1.0'
xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
ns='http://purl.org/rss/1.0/'
datatypeLibrary='http://www.w3.org/2001/XMLSchema-datatypes'>
 
<start>
<element name='RDF' ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<ref name='RDFContent'/>
</element>
</start>
 
<define name='RDFContent' ns='http://purl.org/rss/1.0/'>
<interleave>
<element name='channel'>
<ref name='channelContent'/>
</element>
<optional>
<element name='image'><ref name='imageContent'/></element>
</optional>
<oneOrMore>
<element name='item'><ref name='itemContent'/></element>
</oneOrMore>
</interleave>
</define>
 
<define name='channelContent' combine="interleave">
<interleave>
<element name='title'><data type='string'/></element>
<element name='link'><data type='anyURI'/></element>
<element name='description'><data type='string'/></element>
<element name='image'>
<attribute name='resource' ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<data type='anyURI'/>
</attribute>
</element>
<element name='items'>
<ref name='itemsContent'/>
</element>
<attribute name='about' ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<data type='anyURI'/>
</attribute>
</interleave>
</define>
<define name="itemsContent">
<element name="Seq" ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<oneOrMore>
<element name="li" ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<choice>
<attribute name='resource'> <!-- Why doesn't RDF/RSS1.0 ns qualify this attribute? -->
<data type='anyURI'/>
</attribute>
<attribute name='resource' ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<data type='anyURI'/>
</attribute>
</choice>
</element>
</oneOrMore>
</element>
</define>
<define name='imageContent'>
<interleave>
<element name='title'><data type='string'/></element>
<element name='link'><data type='anyURI'/></element>
<element name='url'><data type='anyURI'/></element>
<attribute name='about' ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<data type='anyURI'/>
</attribute>
</interleave>
</define>
 
<define name='itemContent'>
<interleave>
<element name='title'><data type='string'/></element>
<element name='link'><data type='anyURI'/></element>
<optional><element name='description'><data type='string'/></element></optional>
<ref name="anyThing"/>
<attribute name='about' ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<data type='anyURI'/>
</attribute>
</interleave>
</define>
 
<define name='anyThing'>
<zeroOrMore>
<choice>
<text/>
<element>
<anyName>
<except>
<nsName/>
</except>
</anyName>
<ref name='anyThing'/>
<zeroOrMore>
<attribute>
<anyName/>
</attribute>
</zeroOrMore>
</element>
</choice>
</zeroOrMore>
</define>
</grammar>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/schemas/rss11.rng
New file
0,0 → 1,218
<?xml version="1.0" encoding="UTF-8"?>
<!--
RELAX NG Compact Schema for RSS 1.1
Sean B. Palmer, inamidst.com
Christopher Schmidt, crschmidt.net
License: This schema is in the public domain
-->
<grammar xmlns:rss="http://purl.org/net/rss1.1#" xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns="http://purl.org/net/rss1.1#" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<start>
<ref name="Channel"/>
</start>
<define name="Channel">
<a:documentation>http://purl.org/net/rss1.1#Channel</a:documentation>
<element name="Channel">
<ref name="Channel.content"/>
 
</element>
</define>
<define name="Channel.content">
<optional>
<ref name="AttrXMLLang"/>
</optional>
<optional>
<ref name="AttrXMLBase"/>
</optional>
 
<ref name="AttrRDFAbout"/>
<interleave>
<ref name="title"/>
<ref name="link"/>
<ref name="description"/>
<optional>
<ref name="image"/>
</optional>
<zeroOrMore>
 
<ref name="Any"/>
</zeroOrMore>
<ref name="items"/>
</interleave>
</define>
<define name="title">
<a:documentation>http://purl.org/net/rss1.1#title</a:documentation>
<element name="title">
 
<ref name="title.content"/>
</element>
</define>
<define name="title.content">
<optional>
<ref name="AttrXMLLang"/>
</optional>
<text/>
</define>
 
<define name="link">
<a:documentation>http://purl.org/net/rss1.1#link</a:documentation>
<element name="link">
<ref name="link.content"/>
</element>
</define>
<define name="link.content">
<data type="anyURI"/>
 
</define>
<define name="description">
<a:documentation>http://purl.org/net/rss1.1#description</a:documentation>
<element name="description">
<ref name="description.content"/>
</element>
</define>
<define name="description.content">
 
<optional>
<ref name="AttrXMLLang"/>
</optional>
<text/>
</define>
<define name="image">
<a:documentation>http://purl.org/net/rss1.1#image</a:documentation>
<element name="image">
 
<ref name="image.content"/>
</element>
</define>
<define name="image.content">
<optional>
<ref name="AttrXMLLang"/>
</optional>
<ref name="AttrRDFResource"/>
<interleave>
 
<ref name="title"/>
<optional>
<ref name="link"/>
</optional>
<ref name="url"/>
<zeroOrMore>
<ref name="Any"/>
</zeroOrMore>
</interleave>
 
</define>
<define name="url">
<a:documentation>http://purl.org/net/rss1.1#url</a:documentation>
<element name="url">
<ref name="url.content"/>
</element>
</define>
<define name="url.content">
 
<data type="anyURI"/>
</define>
<define name="items">
<a:documentation>http://purl.org/net/rss1.1#items</a:documentation>
<element name="items">
<ref name="items.content"/>
</element>
</define>
 
<define name="items.content">
<optional>
<ref name="AttrXMLLang"/>
</optional>
<ref name="AttrRDFCollection"/>
<zeroOrMore>
<ref name="item"/>
</zeroOrMore>
</define>
 
<define name="item">
<a:documentation>http://purl.org/net/rss1.1#item</a:documentation>
<element name="item">
<ref name="item.content"/>
</element>
</define>
<define name="item.content">
<optional>
 
<ref name="AttrXMLLang"/>
</optional>
<ref name="AttrRDFAbout"/>
<interleave>
<ref name="title"/>
<ref name="link"/>
<optional>
<ref name="description"/>
</optional>
 
<optional>
<ref name="image"/>
</optional>
<zeroOrMore>
<ref name="Any"/>
</zeroOrMore>
</interleave>
</define>
<define name="Any">
 
<a:documentation>http://purl.org/net/rss1.1#Any</a:documentation>
<element>
<anyName>
<except>
<nsName/>
</except>
</anyName>
<ref name="Any.content"/>
 
</element>
</define>
<define name="Any.content">
<zeroOrMore>
<attribute>
<anyName>
<except>
<nsName/>
<nsName ns=""/>
 
</except>
</anyName>
</attribute>
</zeroOrMore>
<mixed>
<zeroOrMore>
<ref name="Any"/>
</zeroOrMore>
</mixed>
 
</define>
<define name="AttrXMLLang">
<attribute name="xml:lang">
<data type="language"/>
</attribute>
</define>
<define name="AttrXMLBase">
<attribute name="xml:base">
<data type="anyURI"/>
 
</attribute>
</define>
<define name="AttrRDFAbout">
<attribute name="rdf:about">
<data type="anyURI"/>
</attribute>
</define>
<define name="AttrRDFResource">
<attribute name="rdf:parseType">
 
<value>Resource</value>
</attribute>
</define>
<define name="AttrRDFCollection">
<attribute name="rdf:parseType">
<value>Collection</value>
</attribute>
</define>
 
</grammar>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/schemas/rss20.rng
New file
0,0 → 1,298
<?xml version="1.0" encoding="utf-8"?>
 
<!-- ======================================================================
* Author: Dino Morelli
* Began: 2004-Feb-18
* Build #: 0001
* Version: 0.1
* E-Mail: dino.morelli@snet.net
* URL: (none yet)
* License: (none yet)
*
* ========================================================================
*
* RSS v2.0 Relax NG schema
*
* ==================================================================== -->
 
 
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
 
<start>
<ref name="element-rss" />
</start>
 
<define name="element-title">
<element name="title">
 
<text />
</element>
</define>
 
<define name="element-description">
<element name="description">
<text />
</element>
</define>
 
<define name="element-link">
<element name="link">
<text />
</element>
</define>
 
<define name="element-category">
<element name="category">
<optional>
 
<attribute name="domain" />
</optional>
<text />
</element>
</define>
 
<define name="element-rss">
<element name="rss">
<attribute name="version">
 
<value>2.0</value>
</attribute>
<element name="channel">
<interleave>
<ref name="element-title" />
<ref name="element-link" />
<ref name="element-description" />
<optional>
 
<element name="language"><text /></element>
</optional>
<optional>
<element name="copyright"><text /></element>
</optional>
<optional>
<element name="lastBuildDate"><text /></element>
</optional>
<optional>
 
<element name="docs"><text /></element>
</optional>
<optional>
<element name="generator"><text /></element>
</optional>
<optional>
<ref name="element-category" />
</optional>
<optional>
 
<element name="managingEditor"><text /></element>
</optional>
<optional>
<element name="webMaster"><text /></element>
</optional>
<optional>
<element name="pubDate"><text /></element>
</optional>
<optional>
 
<element name="rating"><text /></element>
</optional>
<optional>
<element name="image">
<interleave>
<element name="url"><text /></element>
<ref name="element-title" />
<ref name="element-link" />
<optional>
 
<element name="width"><text /></element>
</optional>
<optional>
<element name="height"><text /></element>
</optional>
<optional>
<ref name="element-description" />
</optional>
</interleave>
 
</element>
</optional>
<optional>
<element name="cloud">
<attribute name="domain" />
<attribute name="port" />
<attribute name="path" />
<attribute name="registerProcedure" />
<attribute name="protocol" />
 
</element>
</optional>
<optional>
<element name="textInput">
<interleave>
<ref name="element-title" />
<ref name="element-description" />
<element name="name"><text /></element>
<ref name="element-link" />
 
</interleave>
</element>
</optional>
<optional>
<element name="skipHours">
<oneOrMore>
<element name="hour">
<choice>
<value>0</value>
 
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
<value>5</value>
<value>6</value>
 
<value>7</value>
<value>8</value>
<value>9</value>
<value>10</value>
<value>11</value>
<value>12</value>
 
<value>13</value>
<value>14</value>
<value>15</value>
<value>16</value>
<value>17</value>
<value>18</value>
 
<value>19</value>
<value>20</value>
<value>21</value>
<value>22</value>
<value>23</value>
</choice>
 
</element>
</oneOrMore>
</element>
</optional>
<optional>
<element name="skipDays">
<oneOrMore>
<element name="day">
<choice>
 
<value>0</value>
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
<value>5</value>
 
<value>6</value>
<value>7</value>
<value>8</value>
<value>9</value>
<value>10</value>
<value>11</value>
 
<value>12</value>
<value>13</value>
<value>14</value>
<value>15</value>
<value>16</value>
<value>17</value>
 
<value>18</value>
<value>19</value>
<value>20</value>
<value>21</value>
<value>22</value>
<value>23</value>
 
<value>24</value>
<value>25</value>
<value>26</value>
<value>27</value>
<value>28</value>
<value>29</value>
 
<value>30</value>
<value>31</value>
</choice>
</element>
</oneOrMore>
</element>
</optional>
<optional>
 
<element name="ttl"><text /></element>
</optional>
<zeroOrMore>
<element name="item">
<interleave>
<choice>
<ref name="element-title" />
<ref name="element-description" />
<interleave>
 
<ref name="element-title" />
<ref name="element-description" />
</interleave>
</choice>
<optional>
<ref name="element-link" />
</optional>
<optional>
<element name="author"><text /></element>
 
</optional>
<optional>
<ref name="element-category" />
</optional>
<optional>
<element name="comments"><text /></element>
</optional>
<optional>
<element name="enclosure">
 
<attribute name="url" />
<attribute name="length" />
<attribute name="type" />
<text />
</element>
</optional>
<optional>
<element name="guid">
<optional>
 
<attribute name="isPermaLink">
<choice>
<value>true</value>
<value>false</value>
</choice>
</attribute>
</optional>
<text />
 
</element>
</optional>
<optional>
<element name="pubDate"><text /></element>
</optional>
<optional>
<element name="source">
<attribute name="url" />
<text />
 
</element>
</optional>
</interleave>
</element>
</zeroOrMore>
</interleave>
</element>
</element>
</define>
 
</grammar>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/xml_feed_parser/1.0.4/XmlFeedParser.php
New file
0,0 → 1,304
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Key gateway class for XML_Feed_Parser package
*
* PHP versions 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category XML
* @package XML_Feed_Parser
* @author James Stewart <james@jystewart.net>
* @copyright 2005 James Stewart <james@jystewart.net>
* @license http://www.gnu.org/copyleft/lesser.html GNU LGPL
* @version CVS: $Id: Parser.php 304308 2010-10-11 12:05:50Z clockwerx $
* @link http://pear.php.net/package/XML_Feed_Parser/
*/
 
/**
* This is the core of the XML_Feed_Parser package. It identifies feed types
* and abstracts access to them. It is an iterator, allowing for easy access
* to the entire feed.
*
* @author James Stewart <james@jystewart.net>
* @version Release: @package_version@
* @package XML_Feed_Parser
*/
class XmlFeedParser implements Iterator {
/**
* This is where we hold the feed object
* @var Object
*/
private $feed;
 
/**
* To allow for extensions, we make a public reference to the feed model
* @var DOMDocument
*/
public $model;
/**
* A map between entry ID and offset
* @var array
*/
protected $idMappings = array();
 
/**
* A storage space for Namespace URIs.
* @var array
*/
private $feedNamespaces = array(
'rss2' => array(
'http://backend.userland.com/rss',
'http://backend.userland.com/rss2',
'http://blogs.law.harvard.edu/tech/rss'));
/**
* Detects feed types and instantiate appropriate objects.
*
* Our constructor takes care of detecting feed types and instantiating
* appropriate classes. For now we're going to treat Atom 0.3 as Atom 1.0
* but raise a warning. I do not intend to introduce full support for
* Atom 0.3 as it has been deprecated, but others are welcome to.
*
* @param string $feed XML serialization of the feed
* @param bool $strict Whether or not to validate the feed
* @param bool $suppressWarnings Trigger errors for deprecated feed types?
* @param bool $tidy Whether or not to try and use the tidy library on input
*/
function __construct($feed, $strict = false, $suppressWarnings = true, $tidy = true) {
$this->model = new DOMDocument;
if (! $this->model->loadXML($feed)) {
if (extension_loaded('tidy') && $tidy) {
$tidy = new tidy;
$tidy->parseString($feed, array('input-xml' => true, 'output-xml' => true));
$tidy->cleanRepair();
if (! $this->model->loadXML((string) $tidy)) {
throw new XmlFeedParserException("Entrée invalide : le flux n'est pas du XML valide");
}
} else {
throw new XmlFeedParserException("Entrée invalide : le flux n'est pas du XML valide");
}
}
 
/* detect feed type */
$doc_element = $this->model->documentElement;
$error = false;
 
switch (true) {
case ($doc_element->namespaceURI == 'http://www.w3.org/2005/Atom'):
$class = 'XmlFeedParserAtom';
break;
case ($doc_element->namespaceURI == 'http://purl.org/atom/ns#'):
$class = 'XmlFeedParserAtom';
$error = "Atom 0.3 est déprécié, le parseur en version 1.0 sera utilisé mais toutes les options ne seront pas disponibles.";
break;
case ($doc_element->namespaceURI == 'http://purl.org/rss/1.0/'
|| ($doc_element->hasChildNodes() && $doc_element->childNodes->length > 1
&& $doc_element->childNodes->item(1)->namespaceURI == 'http://purl.org/rss/1.0/')):
$class = 'XmlFeedParserRss1';
break;
case ($doc_element->namespaceURI == 'http://purl.org/rss/1.1/'
|| ($doc_element->hasChildNodes()
&& $doc_element->childNodes->length > 1
&& $doc_element->childNodes->item(1)->namespaceURI == 'http://purl.org/rss/1.1/')):
$class = 'XmlFeedParserRss11';
break;
case (($doc_element->hasChildNodes()
&& $doc_element->childNodes->length > 1
&& $doc_element->childNodes->item(1)->namespaceURI == 'http://my.netscape.com/rdf/simple/0.9/')
|| $doc_element->namespaceURI == 'http://my.netscape.com/rdf/simple/0.9/'):
$class = 'XmlFeedParserRss09';
break;
case ($doc_element->tagName == 'rss'
and $doc_element->hasAttribute('version')
&& $doc_element->getAttribute('version') == 0.91):
$error = 'RSS 0.91 has been superceded by RSS2.0. Using RSS2.0 parser.';
$class = 'XmlFeedParserRss2';
break;
case ($doc_element->tagName == 'rss'
and $doc_element->hasAttribute('version')
&& $doc_element->getAttribute('version') == 0.92):
$error = 'RSS 0.92 has been superceded by RSS2.0. Using RSS2.0 parser.';
$class = 'XmlFeedParserRss2';
break;
case (in_array($doc_element->namespaceURI, $this->feedNamespaces['rss2'])
|| $doc_element->tagName == 'rss'):
if (! $doc_element->hasAttribute('version') || $doc_element->getAttribute('version') != 2) {
$error = 'RSS version not specified. Parsing as RSS2.0';
}
$class = 'XmlFeedParserRss2';
break;
default:
throw new XmlFeedParserException('Type de flux de syndicaton inconnu');
break;
}
 
if (! $suppressWarnings && ! empty($error)) {
trigger_error($error, E_USER_WARNING);
}
 
/* Instantiate feed object */
$this->feed = new $class($this->model, $strict);
}
 
/**
* Proxy to allow feed element names to be used as method names
*
* For top-level feed elements we will provide access using methods or
* attributes. This function simply passes on a request to the appropriate
* feed type object.
*
* @param string $call - the method being called
* @param array $attributes
*/
function __call($call, $attributes) {
$attributes = array_pad($attributes, 5, false);
list($a, $b, $c, $d, $e) = $attributes;
return $this->feed->$call($a, $b, $c, $d, $e);
}
 
/**
* Proxy to allow feed element names to be used as attribute names
*
* To allow variable-like access to feed-level data we use this
* method. It simply passes along to __call() which in turn passes
* along to the relevant object.
*
* @param string $val - the name of the variable required
*/
function __get($val) {
return $this->feed->$val;
}
 
/**
* Provides iteration functionality.
*
* Of course we must be able to iterate... This function simply increases
* our internal counter.
*/
function next() {
if (isset($this->current_item) &&
$this->current_item <= $this->feed->numberEntries - 1) {
++$this->current_item;
} else if (! isset($this->current_item)) {
$this->current_item = 0;
} else {
return false;
}
}
 
/**
* Return XML_Feed_Type object for current element
*
* @return XML_Feed_Parser_Type Object
*/
function current() {
return $this->getEntryByOffset($this->current_item);
}
 
/**
* For iteration -- returns the key for the current stage in the array.
*
* @return int
*/
function key() {
return $this->current_item;
}
 
/**
* For iteration -- tells whether we have reached the
* end.
*
* @return bool
*/
function valid() {
return $this->current_item < $this->feed->numberEntries;
}
 
/**
* For iteration -- resets the internal counter to the beginning.
*/
function rewind() {
$this->current_item = 0;
}
 
/**
* Provides access to entries by ID if one is specified in the source feed.
*
* As well as allowing the items to be iterated over we want to allow
* users to be able to access a specific entry. This is one of two ways of
* doing that, the other being by offset. This method can be quite slow
* if dealing with a large feed that hasn't yet been processed as it
* instantiates objects for every entry until it finds the one needed.
*
* @param string $id Valid ID for the given feed format
* @return XML_Feed_Parser_Type|false
*/
function getEntryById($id) {
if (isset($this->idMappings[$id])) {
return $this->getEntryByOffset($this->idMappings[$id]);
}
 
/*
* Since we have not yet encountered that ID, let's go through all the
* remaining entries in order till we find it.
* This is a fairly slow implementation, but it should work.
*/
return $this->feed->getEntryById($id);
}
 
/**
* Retrieve entry by numeric offset, starting from zero.
*
* As well as allowing the items to be iterated over we want to allow
* users to be able to access a specific entry. This is one of two ways of
* doing that, the other being by ID.
*
* @param int $offset The position of the entry within the feed, starting from 0
* @return XML_Feed_Parser_Type|false
*/
function getEntryByOffset($offset) {
if ($offset < $this->feed->numberEntries) {
if (isset($this->feed->entries[$offset])) {
return $this->feed->entries[$offset];
} else {
try {
$this->feed->getEntryByOffset($offset);
} catch (Exception $e) {
return false;
}
$id = $this->feed->entries[$offset]->getID();
$this->idMappings[$id] = $offset;
return $this->feed->entries[$offset];
}
} else {
return false;
}
}
 
/**
* Retrieve version details from feed type class.
*
* @return void
* @author James Stewart
*/
function version() {
return $this->feed->version;
}
/**
* Returns a string representation of the feed.
*
* @return String
**/
function __toString() {
return $this->feed->__toString();
}
}
?>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/celw-v1.1/widget/modules/photo/bibliotheque/Cache.php
New file
0,0 → 1,128
<?php
class Cache {
private $actif = null;
private $dossier_stockage = null;
private $duree_de_vie = null;
public function __construct($dossier_stockage = null, $duree_de_vie = null, $activation = true) {
$this->actif = ($activation) ? true : false;
if ($this->actif) {
$this->dossier_stockage = $dossier_stockage;
if (is_null($dossier_stockage)) {
$this->dossier_stockage = self::getDossierTmp();
}
$this->duree_de_vie = $duree_de_vie;
if (is_null($duree_de_vie)) {
$this->duree_de_vie = 3600*24;
}
}
}
public function charger($id) {
$contenu = false;
if ($this->actif) {
$chemin_fichier_cache = $this->dossier_stockage.DIRECTORY_SEPARATOR.$id.'.txt';
if (file_exists($chemin_fichier_cache ) && (time() - @filemtime($chemin_fichier_cache) < $this->duree_de_vie)) {
$contenu = file_get_contents($chemin_fichier_cache);
}
}
return $contenu;
}
public function sauver($id, $contenu) {
if ($this->actif) {
$chemin_fichier_cache = $this->dossier_stockage.DIRECTORY_SEPARATOR.$id.'.txt';
if (!file_exists($chemin_fichier_cache) || (time() - @filemtime($chemin_fichier_cache) > $this->duree_de_vie)) {
$fh = fopen($chemin_fichier_cache,'w+');
if ($fh) {
fputs($fh, $contenu);
fclose($fh);
}
}
}
}
/**
* Détermine le dossier système temporaire et détecte si nous y avons accès en lecture et écriture.
*
* Inspiré de Zend_File_Transfer_Adapter_Abstract & Zend_Cache
*
* @return string|false le chemine vers le dossier temporaire ou false en cas d'échec.
*/
private static function getDossierTmp() {
$dossier_tmp = false;
foreach (array($_ENV, $_SERVER) as $environnement) {
foreach (array('TMPDIR', 'TEMP', 'TMP', 'windir', 'SystemRoot') as $cle) {
if (isset($environnement[$cle])) {
if (($cle == 'windir') or ($cle == 'SystemRoot')) {
$dossier = realpath($environnement[$cle] . '\\temp');
} else {
$dossier = realpath($environnement[$cle]);
}
if (self::etreAccessibleEnLectureEtEcriture($dossier)) {
$dossier_tmp = $dossier;
break 2;
}
}
}
}
if ( ! $dossier_tmp) {
$dossier_televersement_tmp = ini_get('upload_tmp_dir');
if ($dossier_televersement_tmp) {
$dossier = realpath($dossier_televersement_tmp);
if (self::etreAccessibleEnLectureEtEcriture($dossier)) {
$dossier_tmp = $dossier;
}
}
}
if ( ! $dossier_tmp) {
if (function_exists('sys_get_temp_dir')) {
$dossier = sys_get_temp_dir();
if (self::etreAccessibleEnLectureEtEcriture($dossier)) {
$dossier_tmp = $dossier;
}
}
}
if ( ! $dossier_tmp) {
// Tentative de création d'un fichier temporaire
$fichier_tmp = tempnam(md5(uniqid(rand(), TRUE)), '');
if ($fichier_tmp) {
$dossier = realpath(dirname($fichier_tmp));
unlink($fichier_tmp);
if (self::etreAccessibleEnLectureEtEcriture($dossier)) {
$dossier_tmp = $dossier;
}
}
}
if ( ! $dossier_tmp && self::etreAccessibleEnLectureEtEcriture('/tmp')) {
$dossier_tmp = '/tmp';
}
if ( ! $dossier_tmp && self::etreAccessibleEnLectureEtEcriture('\\temp')) {
$dossier_tmp = '\\temp';
}
return $dossier_tmp;
}
/**
* Vérifie si le fichier ou dossier est accessible en lecture et écriture.
*
* @param $ressource chemin vers le dossier ou fichier à tester
* @return boolean true si la ressource est accessible en lecture et écriture.
*/
protected static function etreAccessibleEnLectureEtEcriture($ressource){
$accessible = false;
if (is_readable($ressource) && is_writable($ressource)) {
$accessible = true;
}
return $accessible;
}
}
?>
/tags/celw-v1.1/widget/modules/photo
New file
Property changes:
Added: svn:ignore
+config.ini
/tags/celw-v1.1/widget/modules/observation/config.defaut.ini
New file
0,0 → 1,18
[photo]
; Chemin pour l'autoload à ajouter
autoload = "bibliotheque/;bibliotheque/xml_feed_parser/1.0.4/;bibliotheque/xml_feed_parser/1.0.4/parsers/"
; URL ou chemin du flux RSS contenant les liens vers les photos
fluxRssUrl = "http://www.tela-botanica.org/service:cel:CelSyndicationObservation/multicriteres/atom"
; Squelette d'url pour accéder à la fiche eFlore
efloreUrlTpl = "http://www.tela-botanica.org/eflore/BDNFF/4.02/nn/%s/cel"
; Nombre de vignette à afficher : nombre de vignettes par ligne et nombre de lignes séparés par une vigule (ex. : 4,3).
vignette = 4,3
 
 
[observation.cache]
; Active/Désactive le cache
activation = true
; Dossier où stocker les fichiers de cache du widget
stockageDossier = "/tmp"
; Durée de vie du fichier de cache
dureeDeVie = 86400
/tags/celw-v1.1/widget/modules/observation/bibliotheque/Cache.php
New file
0,0 → 1,128
<?php
class Cache {
private $actif = null;
private $dossier_stockage = null;
private $duree_de_vie = null;
public function __construct($dossier_stockage = null, $duree_de_vie = null, $activation = true) {
$this->actif = ($activation) ? true : false;
if ($this->actif) {
$this->dossier_stockage = $dossier_stockage;
if (is_null($dossier_stockage)) {
$this->dossier_stockage = self::getDossierTmp();
}
$this->duree_de_vie = $duree_de_vie;
if (is_null($duree_de_vie)) {
$this->duree_de_vie = 3600*24;
}
}
}
public function charger($id) {
$contenu = false;
if ($this->actif) {
$chemin_fichier_cache = $this->dossier_stockage.DIRECTORY_SEPARATOR.$id.'.txt';
if (file_exists($chemin_fichier_cache ) && (time() - @filemtime($chemin_fichier_cache) < $this->duree_de_vie)) {
$contenu = file_get_contents($chemin_fichier_cache);
}
}
return $contenu;
}
public function sauver($id, $contenu) {
if ($this->actif) {
$chemin_fichier_cache = $this->dossier_stockage.DIRECTORY_SEPARATOR.$id.'.txt';
if (!file_exists($chemin_fichier_cache) || (time() - @filemtime($chemin_fichier_cache) > $this->duree_de_vie)) {
$fh = fopen($chemin_fichier_cache,'w+');
if ($fh) {
fputs($fh, $contenu);
fclose($fh);
}
}
}
}
/**
* Détermine le dossier système temporaire et détecte si nous y avons accès en lecture et écriture.
*
* Inspiré de Zend_File_Transfer_Adapter_Abstract & Zend_Cache
*
* @return string|false le chemine vers le dossier temporaire ou false en cas d'échec.
*/
private static function getDossierTmp() {
$dossier_tmp = false;
foreach (array($_ENV, $_SERVER) as $environnement) {
foreach (array('TMPDIR', 'TEMP', 'TMP', 'windir', 'SystemRoot') as $cle) {
if (isset($environnement[$cle])) {
if (($cle == 'windir') or ($cle == 'SystemRoot')) {
$dossier = realpath($environnement[$cle] . '\\temp');
} else {
$dossier = realpath($environnement[$cle]);
}
if (self::etreAccessibleEnLectureEtEcriture($dossier)) {
$dossier_tmp = $dossier;
break 2;
}
}
}
}
if ( ! $dossier_tmp) {
$dossier_televersement_tmp = ini_get('upload_tmp_dir');
if ($dossier_televersement_tmp) {
$dossier = realpath($dossier_televersement_tmp);
if (self::etreAccessibleEnLectureEtEcriture($dossier)) {
$dossier_tmp = $dossier;
}
}
}
if ( ! $dossier_tmp) {
if (function_exists('sys_get_temp_dir')) {
$dossier = sys_get_temp_dir();
if (self::etreAccessibleEnLectureEtEcriture($dossier)) {
$dossier_tmp = $dossier;
}
}
}
if ( ! $dossier_tmp) {
// Tentative de création d'un fichier temporaire
$fichier_tmp = tempnam(md5(uniqid(rand(), TRUE)), '');
if ($fichier_tmp) {
$dossier = realpath(dirname($fichier_tmp));
unlink($fichier_tmp);
if (self::etreAccessibleEnLectureEtEcriture($dossier)) {
$dossier_tmp = $dossier;
}
}
}
if ( ! $dossier_tmp && self::etreAccessibleEnLectureEtEcriture('/tmp')) {
$dossier_tmp = '/tmp';
}
if ( ! $dossier_tmp && self::etreAccessibleEnLectureEtEcriture('\\temp')) {
$dossier_tmp = '\\temp';
}
return $dossier_tmp;
}
/**
* Vérifie si le fichier ou dossier est accessible en lecture et écriture.
*
* @param $ressource chemin vers le dossier ou fichier à tester
* @return boolean true si la ressource est accessible en lecture et écriture.
*/
protected static function etreAccessibleEnLectureEtEcriture($ressource){
$accessible = false;
if (is_readable($ressource) && is_writable($ressource)) {
$accessible = true;
}
return $accessible;
}
}
?>
/tags/celw-v1.1/widget/modules/observation/squelettes/observation.tpl.html
New file
0,0 → 1,112
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Observations publiques du CEL - Tela Botanica</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Content-style-type" content="text/css" />
<meta http-equiv="Content-script-type" content="text/javascript" />
<meta http-equiv="Content-language" content="fr" />
<meta name="revisit-after" content="15 days" />
<meta name="robots" content="index,follow" />
<meta name="author" content="Jean-Pascal MILCENT, Grégoire DUCHÉ" />
<meta name="keywords" content="Tela Botanica, observation, CEL" />
<meta name="description" content="Widget de présentation des dernières observations publiées sur le Carnet en Ligne de Tela Botanica" />
 
<!-- Spécial mobile -->
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<!-- Favicones -->
<link rel="icon" type="image/png" href="http://www.tela-botanica.org/sites/commun/generique/images/favicones/tela_botanica.png" />
<link rel="shortcut icon" type="image/x-icon" href="http://www.tela-botanica.org/sites/commun/generique/images/favicones/tela_botanica.ico" />
<!-- Feuilles de styles -->
<link rel="stylesheet" type="text/css" href="http://www.tela-botanica.org/commun/jquery/fancybox/1.3.4/jquery.fancybox-1.3.4.css" media="screen" />
<link rel="stylesheet" type="text/css" href="<?=$url_css?>observation.css" media="screen" />
<!-- Javascript : bibliothèques -->
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/1.4.4/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/fancybox/1.3.4/jquery.fancybox-1.3.4.js"></script>
</head>
<body>
<!-- WIDGET:CEL:OBSERVATION - DEBUT -->
<div id="cel-observation-contenu">
<?php if (isset($erreurs) || isset($informations)) : ?>
<h1>Erreur &amp; informations</h1>
<p>Impossible d'afficher le flux.</p>
<!-- Affichage des erreurs et messages d'information : -->
<?php if ($erreurs) : ?>
<?php foreach ($erreurs as $erreur) : ?>
<p class="erreur"><?=$erreur;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php if ($informations) : ?>
<?php foreach ($informations as $information) : ?>
<p class="info"><?=$information;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php else : ?>
<h1>
Dernières observations du
<a href="http://www.tela-botanica.org/appli:cel" title="Carnet en Ligne" onclick="window.open(this.href);return false;">
CEL
</a>
<a href="<?=$flux_rss_url?>" id="cel-observation-flux" title="Suivre les observations"
onclick="window.open(this.href);return false;">
<img src="http://www.tela-botanica.org/sites/commun/generique/images/rss.png" alt="Suivre les observations" />
</a>
</h1>
<div id="cel-liste-observation">
<?php foreach ($items as $item) : ?>
<div id="cel-observation-<?=$item['guid']?>" class="cel-observation" rel="<?=$item['guid']?>" >
<img id="imPlus-<?=$item['guid']?>" width="10" height="10"
name="imPlus-<?=$item['guid']?>" title="Voir les informations complémentaires" alt="+"
src="http://www.tela-botanica.org/sites/commun/generique/images/plus.png" />
<img id="imMoins-<?=$item['guid']?>" width="10" height="10" class="imMoins"
name="imMoins-<?=$item['guid']?>" title="Cacher les informations complémentaires" alt="+"
src="http://www.tela-botanica.org/sites/commun/generique/images/moins.png" />
<strong>
<a href="<?=$item['eflore_url']?>" onclick="window.open(this.href);return false;"
title="Cliquez pour accéder à la fiche eFlore">
<?=$item['titre']?>
</a>
</strong><br />
<span class="cel-img-date">Publiée le <?=$item['date']?></span><br />
<div id="cel-info-<?=$item['guid']?>" class="cel-infos">
<?=$item['description']?>
</div>
</div>
<?php endforeach; ?>
</div>
<p id="cel-observation-date-generation" class="discretion nettoyage">Au <?=strftime('%A %d %B %Y à %H:%M:%S')?></p>
<script type="text/Javascript">
// Function pour cacher / afficher le détail des observations
$(document).ready(function() {
 
$('.cel-infos').hide();
$('.imMoins').hide();
$('.cel-observation').hover(function() {
var id_obs = $(this).attr("rel");
$('#cel-info-'+id_obs).show();
$('#imPlus-'+id_obs).hide();
$('#imMoins-'+id_obs).show();
},
function() {
var id_obs = $(this).attr("rel");
$('#cel-info-'+id_obs).hide();
$('#imPlus-'+id_obs).show();
$('#imMoins-'+id_obs).hide();
});
 
});
</script>
<?php endif; ?>
</div>
<!-- WIDGET:CEL:OBSERVATION - FIN -->
</body>
</html>
/tags/celw-v1.1/widget/modules/observation/squelettes/observation_ajax.tpl.html
New file
0,0 → 1,75
<div id="cel-observation-contenu">
<?php if (isset($erreurs) || isset($informations)) : ?>
<h1>Erreur &amp; informations</h1>
<p>Impossible d'afficher le flux.</p>
<!-- Affichage des erreurs et messages d'information : -->
<?php if ($erreurs) : ?>
<?php foreach ($erreurs as $erreur) : ?>
<p class="erreur"><?=$erreur;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php if ($informations) : ?>
<?php foreach ($informations as $information) : ?>
<p class="info"><?=$information;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php else : ?>
<h1>
Dernières observations du
<a href="http://www.tela-botanica.org/appli:cel" title="Carnet en Ligne" onclick="window.open(this.href);return false;">
CEL
</a>
<a href="<?=$flux_rss_url?>" id="cel-observation-flux" title="Suivre les observations"
onclick="window.open(this.href);return false;">
<img src="http://www.tela-botanica.org/sites/commun/generique/images/rss.png" alt="Suivre les observations" />
</a>
</h1>
<div id="cel-liste-observation">
<?php foreach ($items as $item) : ?>
<div id="cel-observation-<?=$item['guid']?>" class="cel-observation" rel="<?=$item['guid']?>" >
<img id="imPlus-<?=$item['guid']?>" width="10" height="10"
name="imPlus-<?=$item['guid']?>" title="Voir les informations complémentaires" alt="+"
src="http://www.tela-botanica.org/sites/commun/generique/images/plus.png" />
<img id="imMoins-<?=$item['guid']?>" width="10" height="10" class="imMoins"
name="imMoins-<?=$item['guid']?>" title="Cacher les informations complémentaires" alt="+"
src="http://www.tela-botanica.org/sites/commun/generique/images/moins.png" />
<strong>
<a href="<?=$item['eflore_url']?>" onclick="window.open(this.href);return false;"
title="Cliquez pour accéder à la fiche eFlore">
<?=$item['titre']?>
</a>
</strong><br />
<span class="cel-img-date">Publiée le <?=$item['date']?></span><br />
<div id="cel-info-<?=$item['guid']?>" class="cel-infos">
<?=$item['description']?>
</div>
</div>
<?php endforeach; ?>
</div>
<p id="cel-observation-date-generation" class="discretion nettoyage">Au <?=strftime('%A %d %B %Y à %H:%M:%S')?></p>
<script type="text/Javascript">
// Function pour cacher / afficher le détail des observations
$(document).ready(function() {
 
$('.cel-infos').hide();
$('.imMoins').hide();
$('.cel-observation').hover(function() {
var id_obs = $(this).attr("rel");
$('#cel-info-'+id_obs).show();
$('#imPlus-'+id_obs).hide();
$('#imMoins-'+id_obs).show();
},
function() {
var id_obs = $(this).attr("rel");
$('#cel-info-'+id_obs).hide();
$('#imPlus-'+id_obs).show();
$('#imMoins-'+id_obs).hide();
});
 
});
</script>
<?php endif; ?>
</div>
/tags/celw-v1.1/widget/modules/observation/squelettes/css/observation.css
New file
0,0 → 1,80
@charset "UTF-8";
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Widget */
#cel-observation-contenu{
position:relative;
padding:0 5px;
margin:5px auto;
font-family:Arial,verdana,sans-serif;
font-size:12px;
background-color:#4A4B4C;
color:#CCC;
}
#cel-observation-contenu h1 {
margin:5px;
padding:0;
font-size:1.6em;
color:white;
background-color:transparent;
background-image:none;
text-transform:none;
text-align:left;
}
#cel-observation-contenu h1 a{
color:#CCC;
}
#cel-observation-contenu h1 #cel-observation-flux{
width:16px;
height:20px;
}
#cel-observation-contenu img {
border:0;
padding:0;
margin:0;
}
#cel-observation-contenu a, #cel-observation-contenu a:active, #cel-observation-contenu a:visited {
border-bottom:1px dotted #666;
color:#CCC;
text-decoration:none;
background-image:none;
}
#cel-observation-contenu a:active {
outline:none;
}
#cel-observation-contenu a:focus {
outline:thin dotted;
}
#cel-observation-contenu a:hover {
color:#56B80E;
border-bottom:1px dotted #56B80E;
}
#cel-observation-date-generation{
text-align:right;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Général */
#cel-observation-contenu .discretion {
color:grey;
font-family:arial;
font-size:11px;
font-weight:bold;
}
#cel-observation-contenu .nettoyage {
clear:both;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Galerie observations CEL */
#cel-observation-contenu .cel-observation {
width:99%;
float:left;
padding:2px;
border:1px solid white;
}
#cel-observation-contenu .cel-observation h2{
font-size:1em;
}
 
#cel-observation-contenu .cel-infos{
color:white;
}
 
/tags/celw-v1.1/widget/modules/observation/Observation.php
New file
0,0 → 1,153
<?php
// declare(encoding='UTF-8');
/**
* Service affichant les dernières observations publiques du CEL.
* 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=AideCELWidget
*
* Paramètres :
* ===> vignette = [0-9]+,[0-9]+ [par défaut : 4,3]
* Indique le nombre de vignette par ligne et le nombre de ligne.
*
* @author Delphine <jpm@tela-botanica.org>
* @author Jean-Pascal MILCENT <jpm@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) 2011, Tela Botanica (accueil@tela-botanica.org)
*/
class Observation extends WidgetCommun {
const DS = DIRECTORY_SEPARATOR;
const SERVICE_DEFAUT = 'observation';
private $flux_rss_url = null;
private $eflore_url_tpl = null;
/**
* Méthode appelée par défaut pour charger ce widget.
*/
public function executer() {
$retour = null;
// Pour la création de l'id du cache nous ne tenons pas compte du paramètre de l'url callback
unset($this->parametres['callback']);
extract($this->parametres);
 
if (!isset($mode)) {
$mode = self::SERVICE_DEFAUT;
}
$this->eflore_url_tpl = $this->config['observation']['efloreUrlTpl'];
$this->flux_rss_url = $this->config['observation']['fluxRssUrl'];
$cache_activation = $this->config['observation.cache']['activation'];
$cache_stockage = $this->config['observation.cache']['stockageDossier'];
$ddv = $this->config['observation.cache']['dureeDeVie'];
$cache = new Cache($cache_stockage, $ddv, $cache_activation);
$id_cache = 'observation-'.hash('adler32', print_r($this->parametres, true));
if (! $contenu = $cache->charger($id_cache)) {
$methode = $this->traiterNomMethodeExecuter($mode);
if (method_exists($this, $methode)) {
$retour = $this->$methode();
} else {
$this->messages[] = "Ce type de service '$methode' n'est pas disponible.";
}
if (is_null($retour)) {
$contenu = 'Un problème est survenu : '.print_r($this->messages, true);
} else {
$squelette = dirname(__FILE__).self::DS.'squelettes'.self::DS.$retour['squelette'].'.tpl.html';
$contenu = $this->traiterSquelettePhp($squelette, $retour['donnees']);
$cache->sauver($id_cache, $contenu);
}
}
if (isset($_GET['callback'])) {
$this->envoyerJsonp(array('contenu' => $contenu));
} else {
$this->envoyer($contenu);
}
}
private function executerAjax() {
$widget = $this->executerObservation();
$widget['squelette'] = 'observation_ajax';
return $widget;
}
private function executerObservation() {
$widget = null;
extract($this->parametres);
$max_obs = (isset($max_obs) && preg_match('/^[0-9]+,[0-9]+$/', $max_obs)) ? $max_obs : '10';
$this->flux_rss_url .= $this->traiterParametres();
if (file_get_contents($this->flux_rss_url, false) != false) {
$xml = file_get_contents($this->flux_rss_url);
if ($xml) {
try {
$flux = new XmlFeedParser($xml);
$widget['donnees']['flux_rss_url'] = $this->flux_rss_url;
$widget['donnees']['url_css'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/observation/squelettes/css/');
$widget['donnees']['colonne'] = 1;
$num = 0;
foreach ($flux as $entree) {
if ($num == $max_obs) {
break;
}
$item = array();
// Formatage date
$date = $entree->updated ? $entree->updated : null;
$date = $entree->pubDate ? $entree->pubDate : $date;
$item['date'] = strftime('%A %d %B %Y', $date);
// Formatage titre
$item['titre'] = $entree->title;
$item['nn'] = '';
$item['eflore_url'] = '#';
if (preg_match('/\[nn([0-9]+)\]/', $entree->title, $match)) {
$item['nn'] = $match[1];
$item['eflore_url'] = sprintf($this->eflore_url_tpl, $item['nn']);
}
// Récupération du GUID
if (preg_match('/urn:lsid:tela-botanica.org:cel:obs([0-9]+)$/', $entree->id, $match)) {
$item['guid'] = (int) $match[1];
} else {
$item['guid'] = $entree->id;
}
$item['description'] = $entree->content;
$widget['donnees']['items'][$num++] = $item;
}
$widget['squelette'] = 'observation';
} catch (XmlFeedParserException $e) {
trigger_error('Flux invalide : '.$e->getMessage(), E_USER_WARNING);
}
} else {
$this->messages[] = "Fichier xml invalide.";
}
} else {
$this->messages[] = "L'URI, $this->flux_rss_url, est invalide.";
}
return $widget;
}
private function traiterParametres() {
$parametres_flux = '?';
$criteres = array('utilisateur', 'commune', 'dept', 'taxon', 'commentaire', 'date', 'projet');
foreach($this->parametres as $nom_critere => $valeur_critere) {
if (in_array($nom_critere, $criteres)) {
$valeur_critere = str_replace(' ', '%20', $valeur_critere);
$parametres_flux .= $nom_critere.'='.$valeur_critere.'&';
}
}
if ($parametres_flux == '?') {
$parametres_flux = '';
} else {
$parametres_flux = rtrim($parametres_flux, '&');
}
return $parametres_flux;
}
}
?>
/tags/celw-v1.1/widget/modules/saisie/configurations/biodiversite34_taxons.tsv
New file
0,0 → 1,44
nom_sel num_nom_sel nom_ret num_nom_ret num_taxon famille nom_fr nom_fr_autre
Pancratium maritimum L. 47379 Pancratium maritimum L. 47379 5834 Amaryllidaceae Lis de mer
Echinophora spinosa L. 23444 Echinophora spinosa L. 23444 166 Apiaceae Panais épineux
Calystegia soldanella (L.) Roem. & Schult. 12352 Calystegia soldanella (L.) Roem. & Schult. 12352 2450 Convolvulaceae Liseron de mer
Eryngium maritimum L. 25390 Eryngium maritimum L. 25390 173 Apiaceae Panicaut
Althaea officinalis L. 3752 Althaea officinalis L. 3752 3806 Malvaceae Guimauve
Narcissus tazetta L. 43691 Narcissus tazetta L. 43691 5824 Amaryllidaceae Narcisse à bouquet
Anacamptis palustris (Jacq.) Bateman, Pridgeon & Chase 4317 Anacamptis palustris (Jacq.) Bateman, Pridgeon & Chase 4317 6542 Orchidaceae Orchis des marais
Legousia speculum-veneris (L.) Chaix 38202 Legousia speculum-veneris (L.) Chaix 38202 1920 Campanulaceae Miroir de Vénus
Centaurea cyanus L. 15139 Centaurea cyanus L. 15139 576 Asteraceae Bleuet
Nigella damascena L. 44101 Nigella damascena L. 44101 4465 Ranunculaceae Nigelle de Damas
Echinops ritro L. 75102 Echinops ritro L. 75102 30094 Asteraceae Oursin bleu
Ecballium elaterium (L.) A.Rich. 75101 Ecballium elaterium (L.) 75101 30093 Cucurbitaceae Concombre d'âne
Cortaderia selloana (Schult. & Schult.f.) Asch. & Graebn. 19053 Cortaderia selloana (Schult. & Schult.f.) Asch. & Graebn. 19053 6742 Poaceae Herbe de la pampa
Convolvulus althaeoides L. 18732 Convolvulus althaeoides L. 18732 2452 Convolvulaceae Liseron de Provence Fausse guimauve
Narcissus assoanus Dufour 43518 Narcissus assoanus Dufour 43518 5806 Amaryllidaceae Narcisse d'Asso
Lavandula stoechas L. 75211 Lavandula stoechas L. 75211 30203 Lamiaceae Lavande stéchade
Trifolium stellatum L. 69418 Trifolium stellatum L. 69418 14839 Fabaceae Trèfle étoilé
Cneorum tricoccon L. 18308 Cneorum tricoccon L. 18308 2446 Cneoraceae Camélée Garoupe
Amanita ovoidea Amanite ovoide
Leuzea conifera (L.) DC. 38821 Leuzea conifera (L.) DC. 38821 1050 Asteraceae Leuzée conifère Pomme-de-pin
Populus alba L. 51965 Populus alba L. 51965 5124 Salicaceae Peuplier blanc
Iris pseudacorus L. 35960 Iris pseudacorus L. 35960 6103 Iridaceae Iris faux acore
Robinia pseudoacacia L. 56245 Robinia pseudoacacia L. 56245 3124 Fabaceae Acacia Robinier faux acacia
Parnassia palustris L. 47942 Parnassia palustris L. 47942 5203 Parnassiaceae Parnassie des marais
Alisma plantago-aquatica L. 2871 Alisma plantago-aquatica L. 2871 5785 Alismataceae Plantain d'eau
Quercus suber L. 54585 Quercus suber L. 54585 3297 Fagaceae Chêne-liège
Buxus sempervirens L. 11691 Buxus sempervirens L. 11691 1842 Buxaceae Buis
Sorbus torminalis (L.) Crantz 65340 Sorbus torminalis (L.) Crantz 65340 4996 Rosaceae Alisier torminal
Smilax aspera L. 64818 Smilax aspera L. 64818 6383 Smilacaceae Salsepareille
Ruscus aculeatus L. 58960 Ruscus aculeatus L. 58960 6367 Ruscaceae Fragon faux houx
Quercus pubescens Willd. 54438 Quercus pubescens Willd. 54438 13623 Fagaceae Chêne pubescent
Arbutus unedo L. 6055 Arbutus unedo L. 6055 2648 Ericaceae Arbousier
Ailanthus altissima (Mill.) Swingle 2088 Ailanthus altissima (Mill.) Swingle 2088 5537 Simaroubaceae Faux Vernis du Japon
Colchicum multiflorum Brot. 18564 Colchicum multiflorum Brot. 18564 6293 Colchicaceae Colchique d'automne Safran des prés
Carlina acanthifolia All. 14560 Carlina acanthifolia All. 14560 548 Asteraceae Chardon du Larzac (baromêtre) Carline à feuilles d'acanthe
Hormathophylla spinosa (L.) Küpfer 34932 Hormathophylla spinosa (L.) Küpfer 34932 1689 Brassicaceae Alysson épineux
Dactylorhiza latifolia (L.) Baumann & Künkele 21395 Dactylorhiza latifolia (L.) Baumann & Künkele 21395 9693 Orchidaceae Orchis sureau
Ilex aquifolium L. 35676 Ilex aquifolium L. 35676 326 Aquifoliaceae Houx
Scilla lilio-hyacinthus L. 61487 Scilla lilio-hyacinthus L. 61487 6376 Hyacinthaceae Scille lis-jacinthe
Lobaria pulmonaria Lichen pulmonaire
Adiantum capillus-veneris L. 817 Adiantum capillus-veneris L. 817 7327 Adiantaceae Capillaire de Montpellier
Acanthus mollis L. 74930 Acanthus mollis L. 74930 29922 Acanthaceae Acanthe molle
Bothriochloa barbinodis (Lag.) Herter 9977 Bothriochloa barbinodis (Lag.) Herter 9977 6775 Poaceae Pied-de-poule
/tags/celw-v1.1/widget/modules/saisie/configurations/biodiversite34.ini
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/celw-v1.1/widget/modules/saisie/configurations/biodiversite34.ini
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/celw-v1.1/widget/modules/saisie/squelettes/biodiversite34/biodiversite34.tpl.html
New file
0,0 → 1,196
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Biodiversité 34</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Content-style-type" content="text/css" />
<meta http-equiv="Content-script-type" content="text/javascript" />
<meta http-equiv="Content-language" content="fr" />
<meta name="revisit-after" content="15 days" />
<meta name="robots" content="index,follow" />
<meta name="author" content="Delphine CAUQUIL, Jean-Pascal MILCENT" />
<meta name="keywords" content="Tela Botanica, Biodiversité34, CG34, CEL" />
<meta name="description" content="Widget de saisie simplifié pour le projet Biodiversité 34" />
 
<!-- Favicones -->
<link rel="icon" type="image/png" href="http://www.tela-botanica.org/sites/commun/generique/images/favicones/tela_botanica.png" />
<link rel="shortcut icon" type="image/x-icon" href="http://www.tela-botanica.org/sites/commun/generique/images/favicones/tela_botanica.ico" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<!-- Javascript : bibliothèques -->
<!-- Google Map v3 -->
<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3.5&amp;sensor=true&amp;language=fr&amp;region=FR"></script>
<!-- Jquery -->
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/1.6.2/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/jquery-ui/1.8.13/js/jquery-ui-1.8.13.custom.min.js"></script>
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/jquery-ui/1.8.13/js/jquery.ui.datepicker-fr.js"></script>
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/fancybox/1.3.4/jquery.fancybox-1.3.4.pack.js"></script>
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/validate/1.8.1/jquery.validate.min.js"></script>
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/validate/1.8.1/messages_fr.js"></script>
<script type="text/javascript" src="http://www.tela-botanica.org/commun/proj4js/1.0.1/proj4js-compressed.js"></script>
<script src="<?=$url_base?>saisie?projet=biodiversite34&service=taxons" type="text/javascript"></script>
<script type="text/javascript" src="<?=$url_base?>modules/saisie/squelettes/biodiversite34/js/biodiversite34.js"></script>
<!-- CSS -->
<link href="<?=$url_base?>modules/saisie/squelettes/biodiversite34/css/biodiversite34.css" rel="stylesheet" type="text/css" media="screen" />
<link rel="stylesheet" href="http://www.tela-botanica.org/commun/jquery/jquery-ui/1.8.13/css/ui-darkness/jquery-ui-1.8.13.custom.css" type="text/css" media="screen" />
<link rel="stylesheet" href="http://www.tela-botanica.org/commun/jquery/fancybox/1.3.4/jquery.fancybox-1.3.4.css" type="text/css" media="screen" />
</head>
 
<body>
<h1>Biodiversité 34</h1>
<h2>Saisie des observations</h2>
<form id="saisie-obs" action="#">
<fieldset id="partie-identification">
<legend>1. Identification</legend>
<ul>
<li>
<label for="prenom"><span class="obligatoire" title="Champ obligatoire">*</span> Prénom</label>
<input id="prenom" name="prenom" type="text" value=""/>
</li>
<li>
<label for="nom"><span class="obligatoire" title="Champ obligatoire">*</span> NOM</label>
<input id="nom" name="nom" type="text" value=""/>
</li>
<li>
<label for="courriel"><span class="obligatoire" title="Champ obligatoire">*</span> Courriel</label>
<input id="courriel" name="courriel" type="text" value=""/>
</li>
<li>
<label for="courriel_confirmation"><span class="obligatoire" title="Champ obligatoire">*</span> Courriel (confirmation)</label>
<input id="courriel_confirmation" name="courriel_confirmation" type="text" value=""/>
</li>
</ul>
</fieldset>
<fieldset id="partie-station">
<legend>2. Station / Localisation</legend>
<input id="commune_nom" name="commune_nom" type="hidden" value="" />
<input id="commune_code_insee" name="commune_code_insee" type="hidden" value="" />
<ul>
<li>
<label for="milieu"><span class="obligatoire" title="Champ obligatoire">*</span> Milieu</label>
<select id="milieu" name="milieu">
<option value="">Sélectionner un milieu</option>
<?php foreach ($milieux as $milieu => $description) : ?>
<option value="<?=$milieu?>" <?=($description != '') ? 'title="'.$description.'"': '' ?>><?=$milieu?></option>
<?php endforeach; ?>
</select>
</li>
<li><a id="localiser-gg-map" href="#gg-map-localisation">Localiser votre station sur une carte Google Map</a></li>
<li id="partie-lat-lon">
<label for="latitude"><span class="obligatoire" title="Champ obligatoire">*</span> Latitude</label>
<input id="latitude" name="latitude" type="text" value=""/>
<label for="longitude"><span class="obligatoire" title="Champ obligatoire">*</span> Longitude</label>
<input id="longitude" name="longitude" type="text" value=""/>
<span id="lat-lon-info" class="info">(WGS84)</span>
</li>
</ul>
</fieldset>
<fieldset id="partie-observation">
<legend>3. Observation</legend>
<ul>
<li>
<label for="date"><span class="obligatoire" title="Champ obligatoire">*</span> Date</label>
<input id="date" name="date" type="text" value="" />
</li>
<li>
<label for="taxon"><span class="obligatoire" title="Champ obligatoire">*</span> Espèce</label>
<select id="taxon" name="taxon">
<option value="">Sélectionner un taxon</option>
<?php foreach ($taxons as $taxon) : ?>
<option value="<?=$taxon['num_nom_sel']?>" title="<?=$taxon['nom_sel'].($taxon['nom_fr_autre'] != '' ? ' - '.$taxon['nom_fr_autre'] : '' )?>"><?=$taxon['nom_fr']?></option>
<?php endforeach; ?>
</select>
</li>
<li>
<label for="notes">Notes</label>
<textarea id="notes" name="notes"></textarea>
</li>
</ul>
<button id="ajouter-obs" type="button">Ajouter</button>
</fieldset>
</form>
<h2>Liste des observations à transmettre</h2>
<form action="#">
<table id="liste-obs">
<thead><tr><th>Numéro</th><th>Date</th><th>Nom</th><th>Milieu</th><th>Latitude</th><th>Longitude</th><th>Notes</th><th>Suppression</th></tr></thead>
<tbody></tbody>
</table>
<button id="tramsmettre-obs" type="button">Transmettre</button>
</form>
<div id="gg-map" style="display: none;">
<div id="gg-map-localisation">
<div id="gg-map-carte">Carte en cours de chargement...</div>
<ul id="gg-map-info">
<li>
<span class="champ">Marqueur de station</span>
<span id="marqueur-statut">Déplacer le marqueur sur le centre de votre station.</span>
</li>
<li>
<span class="champ">Coordonnées du marqueur</span>
<span id="marqueur-coordonnees"><span title="Système géodésique mondial, révision de 1984 - Coordonnées non projetées">WGS84 : <span id="marqueur-wgs84">&nbsp;</span></span> / <span title="Système géodésique RGF93 - Coordonnées en projection Lambert 93">Lambert 93 : <span id="marqueur-lambert93">&nbsp;</span></span></span>
</li>
<li>
<span class="champ">Commune</span>
<span id="marqueur-commune">
<span id="commune-nom" class="commune-info">&nbsp;</span>
(<span id="commune-code-insee" class="commune-info" title="Code INSEE de la commune">&nbsp;</span>)
</span>
<span class="champ">Adresse</span>
<span id="marqueur-adresse">&nbsp;</span>
</li>
</ul>
<form id="gg-map-form">
<button id="valider-coordonnees" type="button">Valider</button>
<button id="annuler-coordonnees" type="button">Annuler</button>
</form>
</div>
</div>
</div>
<div id="dialogue-bloquer-copier-coller" style="display: none;" title="Information copier/coller">
<p>
Merci de ne pas copier/coller votre courriel.<br/>
La double saisie permet de vérifier l'absence d'erreurs.
</p>
</div>
<div id="dialogue-zero-obs" style="display: none;" title="Information aucune observation">
<p>
Veuillez saisir des observations pour les transmettres.
</p>
</div>
<div id="dialogue-form-invalide" style="display: none;" title="Validation du formulaire">
<p>Certains champs n'ont pas été saisis correctement, veuillez vérifier les champs saisis.</p>
</div>
<div id="dialogue-obs-transaction" style="display: none;" title="Transmission des observations">
</div>
<div id="dialogue-erreur" style="display: none;" title="Erreur">
</div>
<!-- Stats : Google Analytics -->
<script type="text/javascript">
//<![CDATA[
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-20092557-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
//]]>
</script>
</body>
</html>
/tags/celw-v1.1/widget/modules/saisie/squelettes/biodiversite34/biodiversite34_taxons.tpl.js
New file
0,0 → 1,0
var taxons = <?=$taxons?>;
/tags/celw-v1.1/widget/modules/saisie/squelettes/biodiversite34/css/biodiversite34.css
New file
0,0 → 1,167
@CHARSET "UTF-8";
body {
padding:0;
margin:0;
width:100%;
height:100%;
font-family:Arial;
font-size:12px;
background-color:#4A4B4C;
color:#CCC;
}
h1 {
font-size:1.6em;
}
h2 {
font-size:1.4em;
}
a, a:active, a:visited {
border-bottom:1px dotted #666;
color:#CCC;
text-decoration:none;
}
a:active {
outline:none;
}
a:focus {
outline:thin dotted;
}
a:hover {
color:#56B80E;
border-bottom:1px dotted #56B80E;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Présentation des listes de définitions */
dl {
width:100%;
}
dt {
float:left;
font-weight:bold;
text-align:top left;
margin-right:0.3em;
}
dd {
width:auto;
margin:0.5em 0;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Tableau : */
table {
border:1px solid gray;
border-collapse:collapse;
}
table thead, table tfoot, table tbody {
background-color:Gainsboro;
border:1px solid gray;
color:black;
}
table tbody {
background-color:#FFF;
}
table th {
font-family:monospace;
border:1px dotted gray;
padding:5px;
background-color:Gainsboro;
}
table td {
font-family:arial;
border:1px dotted gray;
padding:5px;
text-align:left;
}
table caption {
font-family:sans-serif;
}
legend {
font-size:1.2em;
color:#CCC;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Générique */
.nettoyage{
clear:both;
}
hr.nettoyage{
visibility:hidden;
}
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Formulaire */
fieldset {
width:800px;
}
label{
width:140px;
display:block;
float:left;
}
input, select, textarea {
width:240px;
}
#saisie-obs fieldset{
margin-top:10px;
border:0;
display:block;
}
#saisie-obs ul {
list-style-type:none;
margin:0;
padding:0;
}
#saisie-obs li {
margin:5px;
}
#partie-station label {
width:70px;
display:block;
float:left;
}
#latitude, #longitude {
width:70px;
float:left;
}
#latitude {
margin-right:5px;
}
#lat-lon-info {
margin-left:5px;
}
.obligatoire {
color:red;
}
label.error {
display:inline;
float:none;
color:red;
padding-left:.5em;
}
 
/*+-----------------------------------------------------------------------------------------------------------------+*/
/* Carte Google Map */
#gg-map-localisation {
background-color:#4A4B4C;
color:#CCC;
}
#gg-map-carte {
width:100%;
}
#gg-map-info {
list-style-type:none;
padding: 5px 0;
margin:0;
}
#gg-map-info li {
margin:0 0 0 5px;
}
#gg-map-form {
padding:0;
margin:0 5px;
}
#gg-map-form button {
margin:5px;
}
.champ {
color:#56B80E;
font-weight:bold;
}
/tags/celw-v1.1/widget/modules/saisie/squelettes/biodiversite34/js/biodiversite34.js
New file
0,0 → 1,437
//+---------------------------------------------------------------------------------------------------------+
// GÉNÉRAL
// Mettre à true pour afficher les messages de débogage
var DEBUG = false;
// URL du web service réalisant l'insertion des données dans la base du CEL.
var URL_SERVICE_CEL = "http://www.tela-botanica.org/service:cel:CelWidgetSaisie";
// Squelette d'URL du web service d'eFlore fournissant les noms de communes.
var URL_SERVICE_NOM_COMMUNE = "http://www.tela-botanica.org/service:eflore:osm/0.1/nom-commune?lon={lon}&lat={lat}";
/**
* Stope l'évènement courrant quand on clique sur un lien.
* Utile pour Chrome, Safari...
* @param evenement
* @return
*/
function arreter(evenement) {
if (evenement.stopPropagation) {
evenement.stopPropagation();
}
return false;
}
 
//+---------------------------------------------------------------------------------------------------------+
// FORMULAIRE
 
$(function() {
$("#saisie-obs").validate({
rules: {
prenom : "required",
nom : "required",
courriel : {
required : true,
email : true},
courriel_confirmation : {
required : true,
equalTo: "#courriel"
},
milieu : "required",
latitude : {
required: true,
range: [-90, 90]},
longitude : {
required: true,
range: [-180, 180]},
date : {
required: true,
date: true},
taxon : "required"
}
});
$("#date").datepicker({
onClose: function(dateText, inst) {$("#saisie-obs").valid();}
});
$("#courriel_confirmation").bind('paste', function(e) {
$("#dialogue-bloquer-copier-coller").dialog();
return false;
});
$("#localiser-gg-map").fancybox({
'modal' : true,
'autoDimensions' : true,
'titleShow' : false,
'onClosed' : function() {
$("#gg-map").hide();
},
'onStart' : function(e) {
arreter(e);
$("#gg-map-localisation").height($(window).height() - 100);
$("#gg-map-carte").height($(window).height() - 200);
$("#gg-map-localisation").width($(window).width() - 100);
},
'onComplete' : function() {
initialiserCarte();
}
});
$("#valider-coordonnees").click(function(e) {
var coordonnees = $("#marqueur-coordonnees").data('latLon');
if (coordonnees != undefined) {
$("#latitude").val(coordonnees.lat);
$("#longitude").val(coordonnees.lon);
}
var commune = $("#marqueur-commune").data('commune');
if (commune != undefined) {
$("#commune_nom").val(commune.nom);
$("#commune_code_insee").val(commune.codeInsee);
}
$.fancybox.close();
$("#saisie-obs").valid();
});
$("#annuler-coordonnees").bind('click', function(e) {
$.fancybox.close();
$("#saisie-obs").valid()
});
var obsNumero = 0;
$("#ajouter-obs").bind('click', function(e) {
if ($("#saisie-obs").valid() == false) {
$("#dialogue-form-invalide").dialog();
} else {
obsNumero = obsNumero + 1;
$("#liste-obs tbody").append(
'<tr id="obs'+obsNumero+'" class="obs">'+
'<td>'+obsNumero+'</td>'+
'<td>'+$("#date").val()+'</td>'+
'<td>'+$("#taxon option:selected").text()+'</td>'+
'<td>'+$("#milieu option:selected").text()+'</td>'+
'<td>'+$("#latitude").val()+'</td>'+
'<td>'+$("#longitude").val()+'</td>'+
'<td>'+$("#notes").val()+'</td>'+
'<td><button class="supprimer-obs" value="'+obsNumero+'" title="'+obsNumero+'">Supprimer</button></td>'+
'</tr>');
var numNomSel = $("#taxon").val();
$("#liste-obs").data('obsId'+obsNumero, {
'date' : $("#date").val(),
'num_nom_sel' : numNomSel,
'nom_sel' : taxons[numNomSel]['nom_sel'],
'nom_ret' : taxons[numNomSel]['nom_ret'],
'num_nom_ret' : taxons[numNomSel]['num_nom_ret'],
'num_taxon' : taxons[numNomSel]['num_taxon'],
'famille' : taxons[numNomSel]['famille'],
'nom_fr' : taxons[numNomSel]['nom_fr'],
'milieu' : $("#milieu option:selected").val(),
'latitude' : $("#latitude").val(),
'longitude' : $("#longitude").val(),
'commune_nom' : $("#commune_nom").val(),
'commune_code_insee' : $("#commune_code_insee").val(),
'notes' : $("#notes").val()});
}
});
$(".supprimer-obs").live('click', function() {
var obsId = $(this).val();
// Problème avec IE 6 et 7
if (obsId == "Supprimer") {
obsId = $(this).attr("title");
}
$('#obs'+obsId).remove();
$("#liste-obs").removeData('obsId'+obsId)
});
$("#tramsmettre-obs").click(function(e) {
var observations = $("#liste-obs").data();
if (observations == undefined || jQuery.isEmptyObject(observations)) {
$("#dialogue-zero-obs").dialog();
} else if ($("#saisie-obs").valid() == false) {
$("#dialogue-form-invalide").dialog();
} else {
observations['projet'] = 'Biodiversite34';
var utilisateur = new Object();
utilisateur.prenom = $("#prenom").val();
utilisateur.nom = $("#nom").val();
utilisateur.courriel = $("#courriel").val();
observations['utilisateur'] = utilisateur;
var erreurMsg = "";
$.ajax({
url : URL_SERVICE_CEL,
type : "POST",
data : observations,
dataType : "json",
beforeSend : function() {
$(".msg").remove();
$(".msg-erreur").remove();
$(".msg-debug").remove();
},
success : function(data, textStatus, jqXHR) {
$("#dialogue-obs-transaction").append('<p class="msg">Vos observations ont bien été transmises.</p>');
},
statusCode : {
500 : function(jqXHR, textStatus, errorThrown) {
erreurMsg += "Erreur 500 :\ntype : "+textStatus+' '+errorThrown+"\n";
reponse = jQuery.parseJSON(jqXHR.responseText);
if (reponse != null) {
$.each(reponse, function (cle, valeur) {
erreurMsg += valeur + "\n";
});
}
if (DEBUG) {
$("#dialogue-obs-transaction").append('<pre class="msg-erreur">'+erreurMsg+'</pre>');
}
}
},
error : function(jqXHR, textStatus, errorThrown) {
erreurMsg += "Erreur Ajax :\ntype : "+textStatus+' '+errorThrown+"\n";
reponse = jQuery.parseJSON(jqXHR.responseText);
if (reponse != null) {
$.each(reponse, function (cle, valeur) {
erreurMsg += valeur + "\n";
});
}
if (DEBUG) {
$("#dialogue-obs-transaction").append('<pre class="msg-erreur">'+erreurMsg+'</pre>');
}
},
complete : function(jqXHR, textStatus) {
var debugMsg = '';
if (jqXHR.getResponseHeader("X-DebugJrest-Data") != '') {
debugInfos = jQuery.parseJSON(jqXHR.getResponseHeader("X-DebugJrest-Data"));
if (debugInfos != null) {
$.each(debugInfos, function (cle, valeur) {
debugMsg += valeur + "\n";
});
}
}
if (erreurMsg != '') {
$("#dialogue-obs-transaction").append('<p class="msg">'+
'Une erreur est survenue lors de la transmission de vos observations.'+'<br />'+
'Vous pouvez signaler le disfonctionnement à <a href="'+
'mailto:cel@tela-botanica.org'+'?'+
'subject=Disfonctionnement du widget de saisie Biodiversite34'+
"&body="+erreurMsg+"\nDébogage :\n"+debugMsg+
'">cel@tela-botanica.org</a>.'+
'</p>');
}
if (DEBUG) {
$("#dialogue-obs-transaction").append('<pre class="msg-debug">Débogage : '+debugMsg+'</pre>');
}
$("#dialogue-obs-transaction").dialog();
$("#liste-obs").removeData();
$('.obs').remove();
obsNumero = 0;
}
});
}
return false;
});
});
 
//+---------------------------------------------------------------------------------------------------------+
// GOOGLE MAP
 
var geocoder;
var latLng;
var map;
var marker;
var osmMapType;
function initialiserCarte() {
geocoder = new google.maps.Geocoder();
latLng = new google.maps.LatLng(43.577, 3.455);
map = new google.maps.Map(document.getElementById('gg-map-carte'), {
zoom: 9,
mapTypeId: google.maps.MapTypeId.HYBRID,
mapTypeControlOptions: {
mapTypeIds: ['OSM', google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.HYBRID, google.maps.MapTypeId.SATELLITE, google.maps.MapTypeId.TERRAIN]}
});
 
// Ajout de la couche OSM à la carte
osmMapType = new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
return "http://tile.openstreetmap.org/" +
zoom + "/" + coord.x + "/" + coord.y + ".png";
},
tileSize: new google.maps.Size(256, 256),
isPng: true,
alt: "OpenStreetMap",
name: "OSM",
maxZoom: 19
});
map.mapTypes.set('OSM', osmMapType);
// Ajout des limites de communes
ctaLayer = new google.maps.KmlLayer('http://www.tela-botanica.org/commun/google/map/3/kmz/communes/34.kmz', {preserveViewport: true});
ctaLayer.setMap(map);
// Définition du marqueur
marker = new google.maps.Marker({
position: latLng,
title: 'Ma station',
map: map,
draggable: true
});
deplacerMarker(latLng);
// Tentative de géolocalisation
if(navigator.geolocation) { // Try W3C Geolocation (Preferred)
navigator.geolocation.getCurrentPosition(function(position) {
(DEBUG) ? console.log("Géolocalisation OK.") : '';
latLng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
deplacerMarker(latLng);
map.setCenter(latLng);
}, function(erreur) {
(DEBUG) ? console.log("Géolocalisation échouée : "+erreur.code+" = "+erreur.message) : '';
});
} else { //Browser doesn't support Geolocation
(DEBUG) ? console.log("Navigateur ne supportant pas la géolocalisation. Localisation par défaut.") : '';
}
deplacerMarker(latLng);
map.setCenter(latLng);
// Add des évènements concernant le marqueur
google.maps.event.addListener(marker, 'dragstart', function() {
mettreAJourMarkerAdresse('Marqueur de station début du déplacement...');
});
google.maps.event.addListener(marker, 'drag', function() {
mettreAJourMarkerStatut('Marqueur de station en cours de déplacement...');
mettreAJourMarkerPosition(marker.getPosition());
});
google.maps.event.addListener(marker, 'dragend', function() {
mettreAJourMarkerStatut('Marqueur de station déplacé (glisser/déposer).');
mettreAJourMarkerPosition(marker.getPosition());
geocoderPosition(marker.getPosition());
trouverCommune(marker.getPosition());
});
google.maps.event.addListener(map, 'click', function(event) {
deplacerMarker(event.latLng);
});
}
 
function deplacerMarker(latLon) {
if (marker != undefined) {
marker.setPosition(latLon);
mettreAJourMarkerStatut('Marqueur de station déplacé (clic).');
mettreAJourMarkerPosition(marker.getPosition());
geocoderPosition(marker.getPosition());
trouverCommune(marker.getPosition());
}
}
 
function geocoderPosition(pos) {
if (geocoder != undefined) {
geocoder.geocode({
latLng: pos
}, function(responses, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (responses && responses.length > 0) {
mettreAJourMarkerAdresse(responses[0].formatted_address);
} else {
mettreAJourMarkerAdresse("Impossible de trouver d'adresse pour cette position.");
}
} else {
mettreAJourMarkerAdresse("Un problème de géolocalisation est survenu : "+status+".");
}
});
}
}
 
function trouverCommune(pos) {
$(function() {
var urlNomCommuneFormatee = URL_SERVICE_NOM_COMMUNE.replace('{lat}', pos.lat()).replace('{lon}', pos.lng());
$.ajax({
url : urlNomCommuneFormatee,
type : "GET",
dataType : "json",
beforeSend : function() {
$(".commune-info").empty();
$("#dialogue-erreur").empty();
},
success : function(data, textStatus, jqXHR) {
$(".commune-info").empty();
$("#commune-nom").append(data.nom);
$("#commune-code-insee").append(data.codeINSEE);
$("#marqueur-commune").data('commune', {'nom' : data.nom, 'codeInsee' : data.codeINSEE});
},
statusCode : {
500 : function(jqXHR, textStatus, errorThrown) {
if (DEBUG) {
$("#dialogue-erreur").append('<p id="msg">Un problème est survenu lors de l\'appel au service fournissante le nom des communes.</p>');
reponse = jQuery.parseJSON(jqXHR.responseText);
var erreurMsg = "";
if (reponse != null) {
$.each(reponse, function (cle, valeur) {
erreurMsg += valeur + "<br />";
});
}
$("#dialogue-erreur").append('<p class="msg-erreur">Erreur 500 : '+errorThrown+"<br />"+erreurMsg+'</p>');
}
}
},
error : function(jqXHR, textStatus, errorThrown) {
if (DEBUG) {
$("#dialogue-erreur").append('<p class="msg">Une erreur Ajax est survenue lors de la transmission de vos observations.</p>');
reponse = jQuery.parseJSON(jqXHR.responseText);
var erreurMsg = "";
if (reponse != null) {
$.each(reponse, function (cle, valeur) {
erreurMsg += valeur + "<br />";
});
}
$("#dialogue-erreur").append('<p class="msg-erreur">Erreur Ajax : '+errorThrown+' (type : '+textStatus+') <br />'+erreurMsg+'</p>');
}
},
complete : function(jqXHR, textStatus) {
if (DEBUG && jqXHR.getResponseHeader("X-DebugJrest-Data") != '') {
var debugMsg = "";
debugInfos = jQuery.parseJSON(jqXHR.getResponseHeader("X-DebugJrest-Data"));
if (debugInfos != null) {
$.each(debugInfos, function (cle, valeur) {
debugMsg += valeur + "<br />";
});
$("#dialogue-erreur").append('<pre class="msg-debug msg">Débogage : '+debugMsg+'</pre>');
}
}
if ($("#dialogue-erreur .msg").length > 0) {
$("#dialogue-erreur").dialog();
}
}
});
});
}
 
function mettreAJourMarkerStatut(str) {
document.getElementById('marqueur-statut').innerHTML = str;
}
 
function mettreAJourMarkerPosition(latLng) {
var lat = latLng.lat().toFixed(5);
var lon = latLng.lng().toFixed(5);
document.getElementById('marqueur-wgs84').innerHTML = [lat, lon].join(', ');
$("#marqueur-coordonnees").data('latLon', {'lat' : lat, 'lon' : lon});
Proj4js.defs["EPSG:4326"] = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs";
Proj4js.defs["EPSG:2154"]="+title=RGF93 / Lambert-93 +proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ";
var source = new Proj4js.Proj('EPSG:4326');// Coordonnées source : WGS 84
var dest = new Proj4js.Proj('EPSG:2154');// Coordonnées destination : Lambert 93
var p = new Proj4js.Point(lon+','+lat);//lon+','+lat any object will do as long as it has 'x' and 'y' properties
Proj4js.transform(source, dest, p);
//Proj4js.reportError = function(msg) {alert(msg);}
//console.log(p.toString());
document.getElementById('marqueur-lambert93').innerHTML = [p.x.toFixed(0)+' '+dest.units, p.y.toFixed(0)+' '+dest.units].join(', ');
}
 
function mettreAJourMarkerAdresse(str) {
document.getElementById('marqueur-adresse').innerHTML = str;
}
 
/tags/celw-v1.1/widget/modules/saisie/Saisie.php
New file
0,0 → 1,137
<?php
// declare(encoding='UTF-8');
/**
* Widget fournissant des interfaces de saisies simplifiée pour différent projets.
* 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=AideCELWidgetSaisie
*
* Paramètres :
* ===> projet = chaine [par défaut : Biodiversite34]
* Indique quel projet nous voulons charger
*
* @author Jean-Pascal MILCENT <jpm@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) 2010, Tela Botanica (accueil@tela-botanica.org)
*/
class Saisie extends WidgetCommun {
const DS = DIRECTORY_SEPARATOR;
const PROJET_DEFAUT = 'biodiversite34';
private $projet = null;
private $configProjet = null;
/**
* Méthode appelée par défaut pour charger ce widget.
*/
public function executer() {
$retour = null;
extract($this->parametres);
 
if (!isset($projet)) {
$this->projet = self::PROJET_DEFAUT;
} else {
$this->projet = $projet;
}
$this->chargerConfigProjet();
$service = (isset($service)) ? $service : $this->projet;
$methode = $this->traiterNomMethodeExecuter($service);
if (method_exists($this, $methode)) {
$retour = $this->$methode();
} else {
$this->messages[] = "Ce type de service '$methode' n'est pas disponible.";
}
 
if (is_null($retour)) {
$contenu = 'Un problème est survenu : '.print_r($this->messages, true);
} else {
$ext = (isset($retour['squelette_ext'])) ? $retour['squelette_ext'] : '.tpl.html';
$squelette = dirname(__FILE__).self::DS.'squelettes'.self::DS.$this->projet.self::DS.$retour['squelette'].$ext;
$contenu = $this->traiterSquelettePhp($squelette, $retour['donnees']);
}
$this->envoyer($contenu);
}
private function chargerConfigProjet() {
$fichier_config = dirname(__FILE__).self::DS.'configurations'.self::DS.$this->projet.'.ini';
if (file_exists($fichier_config)) {
if (!$this->configProjet = parse_ini_file($fichier_config)) {
$this->messages[] = "Le fichier ini '$fichier_config' du projet n'a pu être chargé.";
}
} else {
$this->messages[] = "Le fichier ini '$fichier_config' du projet n'existe pas.";
}
}
public function executerBiodiversite34() {
$widget['squelette'] = $this->projet;
$widget['donnees'] = array();
$widget['donnees']['url_base'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], '');
$widget['donnees']['taxons'] = $this->recupererListeTaxonBiodiversite34();
$widget['donnees']['milieux'] = $this->parserMilieuxBiodiversite34();
return $widget;
}
public function executerTaxons() {
$widget['squelette'] = $this->projet.'_taxons';
$widget['squelette_ext'] = '.tpl.js';
$widget['donnees'] = array();
$methode = 'recupererListeTaxon'.str_replace(' ', '', ucwords(str_replace('-', ' ', strtolower($this->projet))));
$taxons = $this->$methode();
$taxons_tries = array();
foreach ($taxons as $taxon) {
$taxons_tries[$taxon['num_nom_sel']] = $taxon;
}
$widget['donnees']['taxons'] = json_encode($taxons_tries);
return $widget;
}
private function parserMilieuxBiodiversite34() {
$infosMilieux = array();
$milieux = explode('|', $this->configProjet['milieux']);
foreach ($milieux as $milieu) {
$details = explode(';', $milieu);
if (isset($details[1])) {
$infosMilieux[$details[0]] = $details[1];
} else {
$infosMilieux[$details[0]] = '';
}
}
ksort($infosMilieux);
return $infosMilieux;
}
private function recupererListeTaxonBiodiversite34() {
$taxons = null;
$fichier_tsv = dirname(__FILE__).self::DS.'configurations'.self::DS.'biodiversite34_taxons.tsv';
if (file_exists($fichier_tsv) && is_readable($fichier_tsv)) {
$taxons = $this->decomposerFichierTsv($fichier_tsv);
} else {
$this->debug[] = "Impossible d'ouvrir le fichier '$fichier_tsv'.";
}
$taxons_tries = self::trierTableauMd($taxons, array('nom_fr' => SORT_ASC));
return $taxons_tries;
}
private function decomposerFichierTsv($fichier, $delimiter = "\t"){
$header = NULL;
$data = array();
if (($handle = fopen($fichier, 'r')) !== FALSE) {
while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
if (!$header) {
$header = $row;
} else {
$data[] = array_combine($header, $row);
}
}
fclose($handle);
}
return $data;
}
}
/tags/celw-v1.1/widget/modules/stats/Stats.php
New file
0,0 → 1,219
<?php
/**
* Widget fournissant des stats graphiques du CEL.
* Encodage en entrée : utf8
* Encodage en sortie : utf8
*
* @author Jean-Pascal MILCENT <jpm@clapas.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 © 2010, Jean-Pascal MILCENT
*/
class Stats extends WidgetCommun {
const PAGE_DEFAUT = 'defaut';
const MODE_DEFAUT = 'defaut';
const MODE_UTILISATEUR = 'utilisateur';
private $page;
private $mode;
/**
* Méthode appelée avec une requête de type GET.
*/
public function executer() {
$retour = null;
extract($this->parametres);
$this->mode = (isset($mode)) ? $mode : self::MODE_DEFAUT;
$this->page = (isset($page)) ? $page : self::PAGE_DEFAUT;
$methode = $this->traiterNomMethodeExecuter($this->page);
if (method_exists($this, $methode)) {
$retour = $this->$methode();
} else {
$this->messages[] = "Ce type de carte '$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__).DIRECTORY_SEPARATOR.'squelettes'.DIRECTORY_SEPARATOR.$retour['squelette'].'.tpl.html';
$html = $this->traiterSquelettePhp($squelette, $retour['donnees']);
$this->envoyer($html);
}
}
 
/**
* Stats par défaut
*/
public function executerDefaut() {
$widget = null;
switch ($this->mode) {
case self::MODE_DEFAUT :
$widget['donnees'] = (array) $this->recupererStatsTxtNombres();
$widget['squelette'] = 'stats';
break;
case self::MODE_UTILISATEUR :
if ($this->authentifierUtilisateur()) {
$widget['donnees'] = (array) $this->recupererStatsTxtNombres();
$widget['donnees']['utilisateur'] = $this->getAuthIdentifiant();
$widget['donnees']['utilisateur_nom_prenom'] = $this->recupererPrenomNomIdentifie();
$widget['squelette'] = 'stats_utilisateur';
}
break;
default :
$this->messages[] = "Le mode '{$this->mode}' est inconnu.";
}
if (!is_null($widget)) {
$widget['donnees']['url_service'] = sprintf($this->config['chemins']['baseURLServicesCelTpl'], 'CelStatistique');
$widget['donnees']['filtres'] = $this->parametres;
}
return $widget;
}
private function recupererPrenomNomIdentifie() {
$nom = '';
if ($this->getAuthIdentifiant() != null) {
$infos_utilisateur = $this->recupererUtilisateursNomPrenom(array($this->getAuthIdentifiant()));
if (array_key_exists($this->getAuthIdentifiant(), $infos_utilisateur)) {
$utilisateur = (array) $infos_utilisateur[$this->getAuthIdentifiant()];
$nom = $utilisateur['prenom'].' '.$utilisateur['nom'];
} else {
$nom = $this->getAuthIdentifiant();
}
}
return $nom;
}
public function executerNombres() {
$widget = null;
switch ($this->mode) {
case self::MODE_DEFAUT :
$widget['donnees'] = (array) $this->recupererStatsTxtNombres();
break;
case self::MODE_UTILISATEUR :
if ($this->authentifierUtilisateur()) {
$widget['donnees'] = (array) $this->recupererStatsTxtNombres();
$widget['donnees']['utilisateur_nom_prenom'] = $this->recupererPrenomNomIdentifie();
}
break;
default:
$this->messages[] = "Le mode '{$this->mode}' est inconnu.";
}
if (!is_null($widget)) {
$widget['squelette'] = 'stats_nbres';
$widget['donnees']['filtres'] = $this->parametres;
}
return $widget;
}
private function recupererStatsTxtNombres() {
// Récupération des données au format Json
$service = "CelStatistiqueTxt/Nombres";
$parametres = array();
if (isset($this->parametres['mode']) && $this->parametres['mode'] == self::MODE_UTILISATEUR && $this->getAuthIdentifiant() != null) {
$parametres[] = 'utilisateur='.$this->getAuthIdentifiant();
}
if (isset($this->parametres['num_taxon'])) {
$parametres[] = 'num_taxon='.$this->parametres['num_taxon'];
}
if (isset($this->parametres['taxon'])) {
$parametres[] = 'taxon='.$this->parametres['taxon'];
}
$service .= (count($parametres) > 0) ? '?'.implode('&', $parametres) : '';
$url = sprintf($this->config['chemins']['baseURLServicesCelTpl'], $service);
$json = $this->getDao()->consulter($url);
return (array) json_decode($json);
}
public function executerListeTaxonsNbrePhotos() {
$widget = null;
$widget['donnees']['taxons'] = $this->recupererStatsTxtListeTaxonsNbrePhotos();
$widget['donnees']['utilisateur'] = $this->getAuthIdentifiant();
$widget['donnees']['filtres'] = $this->parametres;
$widget['squelette'] = 'liste_taxons_nbre_photos';
return $widget;
}
private function recupererStatsTxtListeTaxonsNbrePhotos() {
// Récupération des données au format Json
$service = "CelStatistiqueTxt/ListeTaxonsNbrePhotos";
$parametres = array();
if (isset($this->parametres['mode']) && $this->parametres['mode'] == self::MODE_UTILISATEUR && $this->getAuthIdentifiant() != null) {
$parametres[] = 'utilisateur='.$this->getAuthIdentifiant();
}
if (isset($this->parametres['num_taxon'])) {
$parametres[] = 'num_taxon='.$this->parametres['num_taxon'];
}
if (isset($this->parametres['taxon'])) {
$parametres[] = 'taxon='.$this->parametres['taxon'];
}
if (isset($this->parametres['start'])) {
$parametres[] = 'start='.$this->parametres['start'];
}
if (isset($this->parametres['limit'])) {
$parametres[] = 'limit='.$this->parametres['limit'];
}
$service .= (count($parametres) > 0) ? '?'.implode('&', $parametres) : '';
$url = sprintf($this->config['chemins']['baseURLServicesCelTpl'], $service);
$json = $this->getDao()->consulter($url);
return (array) json_decode($json);
}
public function executerListeUtilisateursNbrePhotos() {
$widget = null;
$utilisateurs = $this->recupererStatsTxtListeUtilisateursNbrePhotos();
if (isset($utilisateurs)) {
$noms = $this->recupererUtilisateursIdentite(array_keys($utilisateurs));
foreach ($utilisateurs as $courriel => $infos) {
if (array_key_exists($courriel, $noms)) {
$nom_infos = (array) $noms[$courriel];
$nom_fmt = $nom_infos['intitule'];
$widget['donnees']['utilisateurs'][$nom_fmt] = $infos;
}
}
}
$widget['donnees']['filtres'] = $this->parametres;
$widget['squelette'] = 'liste_utilisateurs_nbre_photos';
return $widget;
}
private function recupererStatsTxtListeUtilisateursNbrePhotos() {
// Récupération des données au format Json
$service = "CelStatistiqueTxt/ListeUtilisateursNbrePhotos";
if (isset($this->parametres['mode']) && $this->parametres['mode'] == self::MODE_UTILISATEUR && $this->getAuthIdentifiant() != null) {
$this->getDao()->ajouterParametre('utilisateur', $this->getAuthIdentifiant());
}
if (isset($this->parametres['num_taxon'])) {
$this->getDao()->ajouterParametre('num_taxon', $this->parametres['num_taxon']);
}
if (isset($this->parametres['taxon'])) {
$this->getDao()->ajouterParametre('taxon', $this->parametres['taxon']);
}
if (isset($this->parametres['start'])) {
$this->getDao()->ajouterParametre('start', $this->parametres['start']);
}
if (isset($this->parametres['limit'])) {
$this->getDao()->ajouterParametre('limit', $this->parametres['limit']);
}
if (isset($this->parametres['tag'])) {
$this->getDao()->ajouterParametre('tag', $this->parametres['tag']);
}
$url = sprintf($this->config['chemins']['baseURLServicesCelTpl'], $service);
$json = $this->getDao()->consulter($url);
return (array) json_decode($json);
}
}
/tags/celw-v1.1/widget/modules/stats/squelettes/liste_taxons_nbre_photos.tpl.html
New file
0,0 → 1,52
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Content-style-type" content="text/css" />
<meta http-equiv="Content-script-type" content="text/javascript" />
<meta http-equiv="Content-language" content="fr" />
<meta name="revisit-after" content="15 days" />
<meta name="robots" content="index,follow" />
<meta name="author" content="Jean-Pascal MILCENT" />
<meta name="keywords" content="Statistiques, CEL, Tela Botanica, photo, liste, taxon" />
<meta name="description" content="Liste des taxons possédant le plus grand nombre de photographies publiques dans le Carnet en Ligne (CEL)" />
<title>Liste des taxons possédant le plus grand nombre de photographies publiques</title>
<style>
img{display:block;margin:0.5em;border:1px solid black;}
hr.nettoyeur {clear:both;width:0;}
.flottant-gauche img{float:left;}
</style>
<!-- Stats : Google Analytics -->
<script type="text/javascript">
//<![CDATA[
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-20092557-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
//]]>
</script>
</head>
<body>
<h1>Liste des taxons possédant le plus grand nombre de photographies publiques</h1>
<div class="flottant-gauche">
<?php include('filtres.tpl.html') ?>
<p>Classement / Nom retenu du taxon / Nombre de photographies</p>
<ol>
<?php foreach ($taxons as $taxon => $nbre) : ?>
<li><?=$taxon?> : <?=$nbre?></li>
<?php endforeach; ?>
</ol>
</div>
<hr class="nettoyeur" />
<div class="flottant-gauche">
<?php include('navigation.tpl.html') ?>
</div>
</body>
</html>
/tags/celw-v1.1/widget/modules/stats/squelettes/stats.tpl.html
New file
0,0 → 1,89
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Content-style-type" content="text/css" />
<meta http-equiv="Content-script-type" content="text/javascript" />
<meta http-equiv="Content-language" content="fr" />
<meta name="revisit-after" content="15 days" />
<meta name="robots" content="index,follow" />
<meta name="author" content="Jean-Pascal MILCENT" />
<meta name="keywords" content="Statistiques, CEL, Tela Botanica, graphiques" />
<meta name="description" content="Graphiques et statistiques sur les observations et images du Carnet en Ligne (CEL)" />
<title>Statistiques du Carnet En Ligne</title>
<style>
img{display:block;margin:0.5em;border:1px solid black;}
hr.nettoyeur {clear:both;width:0;}
.flottant-gauche img{float:left;}
</style>
<!-- Stats : Google Analytics -->
<script type="text/javascript">
//<![CDATA[
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-20092557-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
//]]>
</script>
</head>
<body>
<?php $i=0;?>
<h1>Statistiques du CEL</h1>
<?php include('filtres.tpl.html') ?>
<div class="flottant-gauche">
<?php include('nbres.tpl.html') ?>
</div>
<hr class="nettoyeur" />
<div class="flottant-gauche">
<h2>Observations - Activité</h2>
<img src="<?=$url_service?>/UtilisationJournaliere?serveur=<?=$i++?>/<?=date("Y-m-d", (time() - 86400))?>" alt="Intensité d'utilisation pour la journée d'hier" />
<img src="<?=$url_service?>/UtilisationJournaliere?serveur=<?=$i++?>" alt="Intensité d'utilisation pour aujourd'hui" />
</div>
<hr class="nettoyeur" />
<div class="flottant-gauche">
<h2>Observations - Données</h2>
<img src="<?=$url_service?>/NbreObsIdVsTest?serveur=<?=$i++?>" alt="Nombre d'observations identifiées versus tests" />
<img src="<?=$url_service?>/NbreObsPublicVsPrivee?serveur=<?=$i++?>" alt="Nombre d'observations publiques versus privées" />
<img src="<?=$url_service?>/NbreObsDetermineeVsInconnue?serveur=<?=$i++?>" alt="Nombre d'observations déterminées versus inconnues" />
<hr class="nettoyeur" />
<img src="<?=$url_service?>/NbreObsAvecIndicationGeo?serveur=<?=$i++?>" alt="Nombre d'observations avec indications géographiques" />
</div>
<hr class="nettoyeur" />
<div>
<h2>Observations - Évolution</h2>
<img src="<?=$url_service?>/EvolObsParMoisGlissant?serveur=<?=$i++?>" alt="Évolutions des observation sur le dernier mois glissant" />
<img src="<?=$url_service?>/EvolObsParMois?serveur=<?=$i++?>" alt="Évolutions des observation par mois" />
<img src="<?=$url_service?>/EvolObsParAn?serveur=<?=$i++?>" alt="Évolutions des observation par an" />
</div>
<hr class="nettoyeur" />
<div class="flottant-gauche">
<h2>Utilisateurs</h2>
<img src="<?=$url_service?>/NuagePointsObsParHeureEtJourSemaine?serveur=<?=$i++?>" alt="Nuage de points d'observation par heure et jour de la semaine" />
<img src="<?=$url_service?>/NuagePointsObsAnciennete?serveur=<?=$i++?>" alt="Répartition des utilisateurs en fonction du nombre d'observations et de l'ancienneté" />
<hr class="nettoyeur" />
<img src="<?=$url_service?>/NbreObsParUtilisateur?serveur=<?=$i++?>" alt="Nombre d'observations par utilisateur" />
<img src="<?=$url_service?>/NbreObsParUtilisateurEtTest?serveur=<?=$i++?>" alt="Nombre d'observations par utilisateur et test" />
<hr class="nettoyeur" />
<img src="<?=$url_service?>/EvolUtilisateurParMois?serveur=<?=$i++?>" alt="Nombre d'observations par utilisateur et test" />
</div>
<hr class="nettoyeur" />
<div>
<h2>Images</h2>
<img src="<?=$url_service?>/EvolImgParMoisGlissant?serveur=<?=$i++?>" alt="Évolutions du dépôt d'images par mois glissant" />
<img src="<?=$url_service?>/EvolImgParMois?serveur=<?=$i++?>" alt="Évolutions du dépôt d'images par mois" />
<img src="<?=$url_service?>/EvolImgLieesParMois?serveur=<?=$i++?>" alt="Évolutions des images liées aux observations par mois" />
<img src="<?=$url_service?>/EvolImgParAn?serveur=<?=$i++?>" alt="Évolutions du dépôt d'images par an" />
</div>
<hr class="nettoyeur" />
<div class="flottant-gauche">
<?php include('navigation.tpl.html') ?>
</div>
</body>
</html>
/tags/celw-v1.1/widget/modules/stats/squelettes/liste_utilisateurs_nbre_photos.tpl.html
New file
0,0 → 1,56
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Content-style-type" content="text/css" />
<meta http-equiv="Content-script-type" content="text/javascript" />
<meta http-equiv="Content-language" content="fr" />
<meta name="revisit-after" content="15 days" />
<meta name="robots" content="index,follow" />
<meta name="author" content="Jean-Pascal MILCENT" />
<meta name="keywords" content="Statistiques, CEL, Tela Botanica, photo, liste, utilisateurs" />
<meta name="description" content="Liste des utilisateurs possédant le plus grand nombre de photographies publiques dans le Carnet en Ligne (CEL)" />
<title>Liste des utilisateurs possédant le plus grand nombre de photographies publiques</title>
<style>
img{display:block;margin:0.5em;border:1px solid black;}
hr.nettoyeur {clear:both;width:0;}
.flottant-gauche img{float:left;}
</style>
<!-- Stats : Google Analytics -->
<script type="text/javascript">
//<![CDATA[
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-20092557-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
//]]>
</script>
</head>
<body>
<h1>Liste des utilisateurs possédant le plus grand nombre de photographies publiques</h1>
<div class="flottant-gauche">
<?php include('filtres.tpl.html') ?>
<?php if (isset($utilisateurs)) : ?>
<p>Classement / Utilisateur / Nombre de photographies</p>
<ol>
<?php foreach ($utilisateurs as $nomPrenom => $nbre) : ?>
<li><?=$nomPrenom?> : <?=$nbre?></li>
<?php endforeach; ?>
</ol>
<?php else : ?>
<p>Aucun résultat ne correspond à vos filtres</p>
<?php endif; ?>
</div>
<hr class="nettoyeur" />
<div class="flottant-gauche">
<?php include('navigation.tpl.html') ?>
</div>
</body>
</html>
/tags/celw-v1.1/widget/modules/stats/squelettes/navigation.tpl.html
New file
0,0 → 1,6
<ul>
<li><a href="/widget:cel:stats">Stats globales</a> (<a href="/widget:cel:stats?mode=<?=Stats::MODE_UTILISATEUR?>">les miennes</a>)</li>
<li><a href="/widget:cel:stats?page=nombres">Nombres</a> (<a href="/widget:cel:stats?page=nombres&mode=<?=Stats::MODE_UTILISATEUR?>">les miens</a>)</li>
<li><a href="/widget:cel:stats?page=liste-utilisateurs-nbre-photos">Liste des utilisateurs ayant le plus de photographies publiques</a></li>
<li><a href="/widget:cel:stats?page=liste-taxons-nbre-photos">Liste des taxons ayant le plus de photographies publiques</a></li>
</ul>
/tags/celw-v1.1/widget/modules/stats/squelettes/stats_nbres.tpl.html
New file
0,0 → 1,48
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Content-style-type" content="text/css" />
<meta http-equiv="Content-script-type" content="text/javascript" />
<meta http-equiv="Content-language" content="fr" />
<meta name="revisit-after" content="15 days" />
<meta name="robots" content="index,follow" />
<meta name="author" content="Jean-Pascal MILCENT" />
<meta name="keywords" content="Statistiques, CEL, Tela Botanica, graphiques" />
<meta name="description" content="Graphiques et statistiques sur les observations et images du Carnet en Ligne (CEL)" />
<title>Statistiques du Carnet En Ligne</title>
<style>
img{display:block;margin:0.5em;border:1px solid black;}
hr.nettoyeur {clear:both;width:0;}
.flottant-gauche img{float:left;}
</style>
<!-- Stats : Google Analytics -->
<script type="text/javascript">
//<![CDATA[
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-20092557-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
//]]>
</script>
</head>
<body>
<?php $i=0;?>
<h1>Statistiques du CEL <?=(isset($utilisateur_nom_prenom) ? '- '.$utilisateur_nom_prenom : '')?> <?=(isset($taxon) ? '- '.$taxon : '')?></h1>
<?php include('filtres.tpl.html') ?>
<div class="flottant-gauche">
<?php include('nbres.tpl.html')?>
</div>
<hr class="nettoyeur" />
<div class="flottant-gauche">
<?php include('navigation.tpl.html') ?>
</div>
</body>
</html>
/tags/celw-v1.1/widget/modules/stats/squelettes/filtres.tpl.html
New file
0,0 → 1,14
<?php if (array_key_exists('taxon', $filtres) || array_key_exists('num_taxon', $filtres) || array_key_exists('tag', $filtres)) : ?>
<h2>Filtes actifs</h2>
<ul>
<?php if (array_key_exists('taxon', $filtres)) : ?>
<li>nom du taxon=<?=$filtres['taxon']?></li>
<?php endif; ?>
<?php if (array_key_exists('num_taxon', $filtres)) : ?>
<li>numéro du taxon=<?=$filtres['num_taxon']?></li>
<?php endif; ?>
<?php if (array_key_exists('tag', $filtres)) : ?>
<li>Mots-clés des images=<?=$filtres['tag']?></li>
<?php endif; ?>
</ul>
<?php endif; ?>
/tags/celw-v1.1/widget/modules/stats/squelettes/stats_utilisateur.tpl.html
New file
0,0 → 1,80
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Content-style-type" content="text/css" />
<meta http-equiv="Content-script-type" content="text/javascript" />
<meta http-equiv="Content-language" content="fr" />
<meta name="revisit-after" content="15 days" />
<meta name="robots" content="index,follow" />
<meta name="author" content="Jean-Pascal MILCENT" />
<meta name="keywords" content="Statistiques, CEL, Tela Botanica, graphiques" />
<meta name="description" content="Graphiques et statistiques sur les observations et images du Carnet en Ligne (CEL)" />
<title>Statistiques du Carnet En Ligne</title>
<style>
img{display:block;margin:0.5em;border:1px solid black;}
hr.nettoyeur {clear:both;width:0;}
.flottant-gauche img{float:left;}
</style>
<!-- Stats : Google Analytics -->
<script type="text/javascript">
//<![CDATA[
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-20092557-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
//]]>
</script>
</head>
<body>
<?php $i=0;?>
<h1>Statistiques du CEL de <?=$utilisateur_nom_prenom?></h1>
<div class="flottant-gauche">
<?php include('nbres.tpl.html')?>
</div>
<div class="flottant-gauche">
<h2>Observations - Activité</h2>
<img src="<?=$url_service?>/UtilisationJournaliere/<?=date("Y-m-d", (time() - 86400))?>?serveur=<?=$i++?>&amp;utilisateur=<?=$utilisateur?>" alt="Intensité d'utilisation pour la journée d'hier" />
<img src="<?=$url_service?>/UtilisationJournaliere?serveur=<?=$i++?>&amp;utilisateur=<?=$utilisateur?>" alt="Intensité d'utilisation pour aujourd'hui" />
</div>
<hr class="nettoyeur" />
<div class="flottant-gauche">
<h2>Observations - Données</h2>
<img src="<?=$url_service?>/NbreObsPublicVsPrivee?serveur=<?=$i++?>&amp;utilisateur=<?=$utilisateur?>" alt="Nombre d'observations publiques versus privées" />
<img src="<?=$url_service?>/NbreObsDetermineeVsInconnue?serveur=<?=$i++?>&amp;utilisateur=<?=$utilisateur?>" alt="Nombre d'observations déterminées versus inconnues" />
<hr class="nettoyeur" />
<img src="<?=$url_service?>/NbreObsAvecIndicationGeo?serveur=<?=$i++?>&amp;utilisateur=<?=$utilisateur?>" alt="Nombre d'observations avec indications géographiques" />
</div>
<hr class="nettoyeur" />
<div>
<h2>Observations - Évolution</h2>
<img src="<?=$url_service?>/EvolObsParMoisGlissant?serveur=<?=$i++?>&amp;utilisateur=<?=$utilisateur?>" alt="Évolutions des observation sur le dernier mois glissant" />
<img src="<?=$url_service?>/EvolObsParMois?serveur=<?=$i++?>&amp;utilisateur=<?=$utilisateur?>" alt="Évolutions des observation par mois" />
<img src="<?=$url_service?>/EvolObsParAn?serveur=<?=$i++?>&amp;utilisateur=<?=$utilisateur?>" alt="Évolutions des observation par an" />
</div>
<hr class="nettoyeur" />
<div class="flottant-gauche">
<h2>Utilisateurs</h2>
<img src="<?=$url_service?>/NuagePointsObsParHeureEtJourSemaine?serveur=<?=$i++?>&amp;utilisateur=<?=$utilisateur?>" alt="Nuage de points d'observation par heure et jour de la semaine" />
</div>
<hr class="nettoyeur" />
<div>
<h2>Images</h2>
<img src="<?=$url_service?>/EvolImgParMoisGlissant?serveur=<?=$i++?>&amp;utilisateur=<?=$utilisateur?>" alt="Évolutions du dépôt d'images par mois glissant" />
<img src="<?=$url_service?>/EvolImgParMois?serveur=<?=$i++?>&amp;utilisateur=<?=$utilisateur?>" alt="Évolutions du dépôt d'images par mois" />
<img src="<?=$url_service?>/EvolImgLieesParMois?serveur=<?=$i++?>&amp;utilisateur=<?=$utilisateur?>" alt="Évolutions des images liées aux observations par mois" />
<img src="<?=$url_service?>/EvolImgParAn?serveur=<?=$i++?>&amp;utilisateur=<?=$utilisateur?>" alt="Évolutions du dépôt d'images par an" />
</div>
<hr class="nettoyeur" />
<div class="flottant-gauche">
<?php include('navigation.tpl.html') ?>
</div>
</body>
</html>
/tags/celw-v1.1/widget/modules/stats/squelettes/nbres.tpl.html
New file
0,0 → 1,10
<h2>Nombres</h2>
<ul>
<li>Nombre d'observations publiques / total : <strong><?=number_format($observationsPubliques, 0, ',', ' ')?></strong> / <strong><?=number_format($observations, 0, ',', ' ')?></strong></li>
<li>Nombre d'images : <strong><?=number_format($images, 0, ',', ' ')?></strong></li>
<li>Nombre d'images liées aux observations : <strong><?=number_format($imagesLiees, 0, ',', ' ')?></strong></li>
<li>Nombre d'observations liées aux images : <strong><?=number_format($observationsLiees, 0, ',', ' ')?></strong></li>
<li>Moyenne images par observation : <strong><?=number_format($moyImagesParObs, 2, ',', ' ')?></strong></li>
<li title="Hors observations géoréférencées mais non liées à une commune.">Nombre de communes possédant des observations : <strong><?=number_format($communes, 0, ',', ' ')?></strong></li>
<li>Nombre d'observations par communes (mini / moyenne / maxi) : <strong><?=number_format($observationsParCommunesMin, 0, ',', ' ')?></strong> / <strong><?=number_format($observationsParCommunesMoyenne, 2, ',', ' ')?></strong> / <strong><?=number_format($observationsParCommunesMax, 0, ',', ' ')?></strong></li>
</ul>
/tags/celw-v1.1/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&parametre2=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);
}
}
}
?>
/tags/celw-v1.1/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/
/tags/celw-v1.1/widget/.
New file
Property changes:
Added: svn:ignore
+.settings
+.buildpath
+.project
+widget.ini.php