Subversion Repositories Applications.referentiel

Compare Revisions

No changes between revisions

Ignore whitespace Rev 5 → Rev 6

/trunk/jrest/.htaccess
New file
0,0 → 1,7
#AddHandler x-httpd-php5 .php
AddDefaultCharset UTF-8
 
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*$ index.php/
/trunk/jrest/JRest.php
New file
0,0 → 1,299
<?php
// In : utf8 url_encoded (get et post)
// Out : utf8
 
// TODO : gerer les retours : dans ce controleur : code retour et envoi ...
class JRest {
 
/** Parsed configuration file */
private $config;
 
/** The HTTP request method used. */
private $method = 'GET';
 
/** The HTTP request data sent (if any). */
private $requestData = NULL;
 
/** Nom resource. */
private $resource = NULL;
 
/** Identifiant unique resource. */
private $uid = NULL;
 
/**
* Constructor. Parses the configuration file "JRest.ini", grabs any request data sent, records the HTTP
* request method used and parses the request URL to find out the requested resource
* @param str iniFile Configuration file to use
*/
public function JRest($iniFile = 'jrest.ini.php') {
$this->config = parse_ini_file($iniFile, TRUE);
if (isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD']) && isset($_SERVER['QUERY_STRING'])) {
if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > 0) {
$this->requestData = '';
$httpContent = fopen('php://input', 'r');
while ($data = fread($httpContent, 1024)) {
$this->requestData .= $data;
}
fclose($httpContent);
}
if (strlen($_SERVER['QUERY_STRING']) == 0) {
$len = strlen($_SERVER['REQUEST_URI']);
} else {
$len = -(strlen($_SERVER['QUERY_STRING']) + 1);
}
$urlString = substr($_SERVER['REQUEST_URI'], strlen($this->config['settings']['baseURL']), $len);
 
$urlParts = explode('/', $urlString);
 
if (isset($urlParts[0])) $this->resource = $urlParts[0];
if (count($urlParts) > 1 && $urlParts[1] != '') {
array_shift($urlParts);
foreach ($urlParts as $uid) {
if ($uid != '') {
$this->uid[] = urldecode($uid);
}
}
}
 
$this->method = $_SERVER['REQUEST_METHOD'];
} else {
trigger_error('I require the server variables REQUEST_URI, REQUEST_METHOD and QUERY_STRING to work.', E_USER_ERROR);
}
}
 
/**
* Execute the request.
*/
function exec() {
switch ($this->method) {
case 'GET':
$this->get();
break;
case 'POST':
$this->post();
break;
case 'DELETE':
$this->delete();
break;
case 'PUT':
$this->add();
break;
}
}
 
/**
* Execute a GET request. A GET request fetches a list of resource when no resource name is given, a list of element
* when a resource name is given, or a resource element when a resource and resource unique identifier are given. It does not change the
* database contents.
*/
private function get() {
if ($this->resource) {
$resource_file = 'services/'.ucfirst($this->resource).'.php';
$resource_class = ucfirst($this->resource);
if (file_exists($resource_file)) {
include_once $resource_file;
if (class_exists($resource_class)) {
$service = new $resource_class($this->config);
if ($this->uid) { // get a resource element
if (method_exists($service, 'getElement')) {
$service->getElement($this->uid);
}
} elseif (method_exists($service, 'getRessource')) { // get all elements of a ressource
$service->getRessource();
}
}
}
} else { // get resources
// include set.jrest.php, instanticiation et appel
}
}
 
private function post() {
$pairs = array();
// Récupération des paramètres passés dans le contenu de la requête HTTP (= POST)
if ($this->requestData) {
$pairs = $this->parseRequestData();
}
 
// Ajout des informations concernant l'upload de fichier passées dans la variable $_FILE
if(isset($_FILES)) {
foreach ($_FILES as $v) {
$pairs[$v['name']] = $v;
}
 
// Ne pas effacer cette ligne ! Elle est indispensable pour les services du Carnet en ligne
// qui n'utilisent que le tableau pairs dans les posts
$pairs = array_merge($pairs, $_POST);
}
 
// gestion du contenu du post
if(isset($_POST))
{
// Safari ne sait pas envoyer des DELETE avec gwt...
// Nous utilisons le parametre "action" passé dans le POST qui doit contenir DELETE pour lancer la supression
if ($pairs['action'] == 'DELETE') {
$this->delete();
return;
}
 
if (count($pairs) != 0) {
if ($this->uid) { // get a resource element
$resource_file = 'services/'.ucfirst($this->resource).'.php';
$resource_class = ucfirst($this->resource);
if (file_exists($resource_file)) {
include_once $resource_file;
if (class_exists($resource_class)) {
$service = new $resource_class($this->config);
if (method_exists($service,'updateElement')) { // Update element
// TODO : a voir le retour ...
if ($service->updateElement($this->uid, $pairs)) {
$this->created();
}
}
}
}
} else { // get all elements of a ressource
$this->add($pairs);
}
} else {
$this->lengthRequired();
}
}
}
 
private function delete() {
$resource_file = 'services/'.ucfirst($this->resource).'.php';
$resource_class = ucfirst($this->resource);
if (file_exists($resource_file)) {
include_once $resource_file;
if (class_exists($resource_class)) {
$service = new $resource_class($this->config);
if ($this->uid) { // get a resource element
if (method_exists($service, 'deleteElement')) { // Delete element
if ($service->deleteElement($this->uid)) {
$this->noContent();
}
}
}
}
}
}
 
private function add($pairs = null) {
if (is_null($pairs)) {
$pairs = array();
// Récupération des paramètres passés dans le contenu de la requête HTTP (= POST)
// FIXME : vérifier que l'on récupère bien les données passées par PUT
if ($this->requestData) {
$pairs = $this->parseRequestData();
}
}
 
if (count($pairs) != 0) {
$resource_file = 'services/'.ucfirst($this->resource).'.php';
$resource_class = ucfirst($this->resource);
if (file_exists($resource_file)) {
include_once $resource_file;
if (class_exists($resource_class)) {
$service = new $resource_class($this->config);
if (method_exists($service,'createElement')) { // Create a new element
if ($service->createElement($pairs)) {
$this->created();
}
}
}
}
} else {
$this->lengthRequired();
}
}
 
/**
* Parse the HTTP request data.
* @return str[] Array of name value pairs
*/
private function parseRequestData() {
$values = array();
$pairs = explode('&', $this->requestData);
foreach ($pairs as $pair) {
$parts = explode('=', $pair);
if (isset($parts[0]) && isset($parts[1])) {
$parts[1] = rtrim(urldecode($parts[1]));
$values[$parts[0]] = $parts[1];
}
}
return $values;
}
 
/**
* Send a HTTP 201 response header.
*/
private function created($url = FALSE) {
header('HTTP/1.0 201 Created');
if ($url) {
header('Location: '.$url);
}
}
 
/**
* Send a HTTP 204 response header.
*/
private function noContent() {
header('HTTP/1.0 204 No Content');
}
 
/**
* Send a HTTP 400 response header.
*/
private function badRequest() {
header('HTTP/1.0 400 Bad Request');
}
 
/**
* Send a HTTP 401 response header.
*/
private function unauthorized($realm = 'JRest') {
if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) {
header('WWW-Authenticate: Basic realm="'.$realm.'"');
}
header('HTTP/1.0 401 Unauthorized');
}
 
/**
* Send a HTTP 404 response header.
*/
private function notFound() {
header('HTTP/1.0 404 Not Found');
}
 
/**
* Send a HTTP 405 response header.
*/
private function methodNotAllowed($allowed = 'GET, HEAD') {
header('HTTP/1.0 405 Method Not Allowed');
header('Allow: '.$allowed);
}
 
/**
* Send a HTTP 406 response header.
*/
private function notAcceptable() {
header('HTTP/1.0 406 Not Acceptable');
echo join(', ', array_keys($this->config['renderers']));
}
 
/**
* Send a HTTP 411 response header.
*/
private function lengthRequired() {
header('HTTP/1.0 411 Length Required');
}
 
/**
* Send a HTTP 500 response header.
*/
private function internalServerError() {
header('HTTP/1.0 500 Internal Server Error');
}
}
?>
/trunk/jrest/index.php
New file
0,0 → 1,27
<?php
require 'JRest.php';
 
/**
* La fonction __autoload() 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.
*/
function __autoload($classe) {
if (class_exists($classe)) {
return null;
}
$chemins = array('', 'services/');
foreach ($chemins as $chemin) {
$chemin = $chemin.$classe.'.php';
if (file_exists($chemin)) {
require_once $chemin;
}
}
}
 
$jRest = new JRest();
$jRest->exec();
?>
/trunk/jrest/jrest.ini.php.defaut
New file
0,0 → 1,13
;<?/*
[settings]
baseURL = "/referentiel/jrest/"
 
; Default
[database]
phptype = mysqli
username = root
password =
hostspec = localhost
database = referentiels
 
;*/?>
/trunk/jrest/services/Ref.php
New file
0,0 → 1,134
<?php
/**
* Classe mère abstraite contenant les méthodes génériques des services des Référentiels.
* Encodage en entrée : utf8
* Encodage en sortie : utf8
*
* @category Php 5.2
* @package Referentiel
* @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>
* @copyright 2010 Tela-Botanica
* @version $Id$
*/
abstract class Ref {
public $config;
protected $bdd;
protected $messages = array();
protected $debug = array();
protected $distinct = false;
protected $orderby = null;
protected $formatRetour = 'objet';
protected $start = 0;
protected $limit = 150;
public function __construct($config, $demarrer_session = true) {
// Tableau contenant la config de Jrest
$this->config = $config;
// Connection à la base de données
$this->bdd = $this->connecterPDO($this->config, 'database');
// Nettoyage du $_GET (sécurité)
if (isset($_GET)) {
$get_params = array('orderby', 'distinct', 'start', 'limit', 'formatRetour');
foreach ($get_params as $get) {
$verifier = array('NULL', "\n", "\r", "\\", "'", '"', "\x00", "\x1a", ';');
$_GET[$get] = str_replace($verifier, '', $_GET[$get]);
if (isset($_GET[$get]) && $_GET[$get] != '') {
$this->$get = $_GET[$get];
} else {
$_GET[$get] = null;
}
}
}
}
 
/**
* Méthode appelée quand aucun paramètre n'est passé dans l'url et avec une requête de type GET.
*/
public function getRessource() {
$this->getElement(array());
}
protected function envoyer($donnees = null, $mime = 'text/html', $encodage = 'utf-8', $json = true) {
// 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 = $this->messages;
} else {
$sortie = $donnees;
if (is_null($donnees)) {
$sortie = 'OK';
}
}
 
// Gestion de l'envoie du déboguage
$this->envoyerDebogage();
// Encodage au format et JSON et envoie sur la sortie standard
$contenu = $json ? json_encode($sortie) : $sortie;
$this->envoyerContenu($encodage, $mime, $contenu);
}
protected 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));
}
}
protected function envoyerContenu($encodage, $mime, $contenu) {
header("Content-Type: $mime; charset=$encodage");
print $contenu;
}
private function connecterPDO($config, $base = 'database') {
$cfg = $config[$base];
$dsn = $cfg['phptype'].':dbname='.$cfg['database'].';host='.$cfg['hostspec'];
try {
$PDO = new PDO($dsn, $cfg['username'], $cfg['password']);
} catch (PDOException $e) {
echo 'La connexion à la base de donnée via PDO a échouée : ' . $e->getMessage();
}
// Passe en UTF-8 la connexion à la BDD
$PDO->exec("SET NAMES 'utf8'");
// Affiche les erreurs détectées par PDO (sinon mode silencieux => aucune erreur affiché)
$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $PDO;
}
protected function getTxt($id) {
$sortie = '';
switch ($id) {
case 'sql_erreur' : $sortie = 'Requête echec. Fichier : "%s". Ligne : "%s". Message : %s'; break;
default : $sortie = $id;
}
return $sortie;
}
protected function traiterParametresUrl($params_attendu, $params, $pourBDD = true) {
$sortie = array();
foreach ($params_attendu as $num => $nom) {
if (isset($params[$num]) && $params[$num] != '*') {
if ($pourBDD) {
$params[$num] = $this->bdd->quote($params[$num]);
}
$sortie[$nom] = $params[$num];
}
}
return $sortie;
}
}
?>
/trunk/jrest/services/RefReferentiel.php
New file
0,0 → 1,90
<?php
/**
* Service fournissant des données de la table contenant le référentiel de travail.
* Encodage en entrée : utf8
* Encodage en sortie : utf8
*
* @category Php 5.2
* @package Referentiel
* @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>
* @copyright 2010 Tela-Botanica
* @version $Id$
*/
class RefReferentiel extends Ref {
/**
* Méthode principale appelée avec une requête de type GET.
*/
public function getElement($param = array()) {
// Initialisation des variables
$info = array();
// Nour recherchons le type de requête demandé
$p = $this->traiterParametresUrl(array('type', 'projet'), $param, false);
$type = $p['type'];
$projet = $p['projet'];
if (!is_null($type)) {
if (!is_null($projet)) {
$methode = 'getElement'.$type;
if (method_exists($this, $methode)) {
//array_shift($param);
$info = $this->$methode($projet);
} else {
$this->messages[] = "Le type d'information demandé '$type' n'est pas disponible.";
}
} else {
$this->messages[] = "Veuillez préciser le nom de code du projet comme premier paramêtre (ex. : bdnff).";
}
} else {
$this->messages[] = "Veuillez préciser le type de requête.";
}
// Envoie sur la sortie standard
$this->envoyer($info);
}
/* Méthode pour récupérer les noms d'un référentiel.
* Appelée avec les paramêtres d'url suivant :
* /RefReferentiel/tout/code_du_referentiel
*/
public function getElementTout($projet) {
$requete = ($this->distinct ? 'SELECT DISTINCT' : 'SELECT').' * '.
"FROM `$projet` ".
'ORDER BY '.((!is_null($this->orderby)) ? $this->orderby : 'num_nom ASC').' ';
//"LIMIT $this->start, $this->limit ";
// Récupération des résultats
try {
$donnees = $this->bdd->query($requete)->fetchAll(PDO::FETCH_ASSOC);
if ($donnees === false) {
$this->messages[] = "La requête a retourné aucun résultat.";
}
} catch (PDOException $e) {
$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage());
}
return $donnees;
}
/* Méthode pour récupérer le nombre de noms présents dans un référentiel.
* Appelée avec les paramêtres d'url suivant :
* /RefReferentiel/nombre/code_du_referentiel
*/
public function getElementNombre($projet) {
$requete = 'SELECT COUNT(*) AS nbre '.
"FROM `$projet` ";
// Récupération des résultats
try {
$nbre = $this->bdd->query($requete)->fetchColumn();
if ($nbre === false) {
$this->messages[] = "La requête a retourné aucun résultat.";
}
} catch (PDOException $e) {
$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage());
}
return $nbre;
}
}
?>
/trunk/jrest/services/RefTableStructure.php
New file
0,0 → 1,88
<?php
/**
* Service fournissant des informations sur la structure d'une table des référentiels.
* Encodage en entrée : utf8
* Encodage en sortie : utf8
*
* @category Php 5.2
* @package Referentiel
* @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>
* @copyright 2010 Tela-Botanica
* @version $Id$
*/
class RefTableStructure extends Ref {
/**
* Méthode principale appelée avec une requête de type GET.
*/
public function getElement($param = array()) {
// Initialisation des variables
$info = array();
// Nour recherchons le type de requête demandé
$p = $this->traiterParametresUrl(array('type', 'table'), $param, false);
$type = $p['type'];
$table = $p['table'];
if (!is_null($type)) {
if (!is_null($table)) {
$methode = 'getElement'.$type;
if (method_exists($this, $methode)) {
//array_shift($param);
$info = $this->$methode($table);
} else {
$this->messages[] = "Le type d'information demandé '$type' n'est pas disponible.";
}
} else {
$this->messages[] = "Veuillez préciser le nom de la table comme premier paramêtre.";
}
} else {
$this->messages[] = "Veuillez préciser le type de requête.";
}
// Envoie sur la sortie standard
$this->envoyer($info);
}
/* Méthode pour récupérer des informations sur les colonnes d'une table.
* Appelée avec les paramêtres d'url suivant :
* /RefTableStructure/colonnes/nom_de_la_table
*/
public function getElementColonnes($table) {
$requete = "SHOW COLUMNS FROM `$table` ";
// Récupération des résultats
try {
$donnees = $this->bdd->query($requete)->fetchAll(PDO::FETCH_ASSOC);
if ($donnees === false) {
$this->messages[] = "La requête a retourné aucun résultat.";
}
$info['colonnes'] = $donnees;
} catch (PDOException $e) {
$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage());
}
return $info;
}
/* Méthode pour récupérer un tableau d'analyse de la table.
* Appelée avec les paramêtres d'url suivant :
* /RefTableStructure/analyse/nom_de_la_table
*/
public function getElementAnalyse($table) {
$requete = "SELECT * FROM `$table` PROCEDURE ANALYSE ( )";
// Récupération des résultats
try {
$donnees = $this->bdd->query($requete)->fetchAll(PDO::FETCH_ASSOC);
if ($donnees === false) {
$this->messages[] = "La requête a retourné aucun résultat.";
}
$info['analyses'] = $donnees;
} catch (PDOException $e) {
$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage());
}
return $info;
}
}
?>
/trunk/modeles/ReferentielDao.php
New file
0,0 → 1,64
<?php
// declare(encoding='UTF-8');
/**
* Modèle d'accès à la base de données des Référentiels.
* Permet d'accèder au données d'un référentiel.
*
* @package Referentiel
* @category Php 5.2
* @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 ReferentielDao extends AppliModele {
const SERVICE = 'RefReferentiel';
/**
* Retourne l'ensemble des information sur les colonnes d'une table.
*
* @param string le nom de la table.
* @return array un tableau contenant les informations sur les colonnes de la table.
*/
public function getTout($code_projet) {
$url = $this->url_jrest.self::SERVICE."/Tout/$code_projet";
$json = file_get_contents($url);
$noms = json_decode($json, true);
/*
$noms = array();
$pas = 20000;
$max = $this->getNombre($code_projet);
for ($i = 0; $i < $max; $i = $i + $pas) {
$start = ($i != 0) ? ($i+1): $i;
$limit = $i + $pas;
$url_limitee = $url."?start=$start&limit=$limit";
Debug::printr("Récupération des données de $start à $limit");
$json = file_get_contents($url_limitee);
$enregistrements = json_decode($json, true);
$noms = array_merge($noms, $enregistrements);
}*/
return $noms;
}
/**
* Retourne le nombre de noms présents dans la table de travail du référentiel.
*
* @param string le code du référentiel.
* @return int le nombre de noms.
*/
public function getNombre($code_projet) {
$url = $this->url_jrest.self::SERVICE."/Nombre/$code_projet";
$json = file_get_contents($url);
$nbre = json_decode($json, true);
return $nbre;
}
}
?>
/trunk/modeles/AppliModele.php
New file
0,0 → 1,53
<?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.
* Elle est abstraite donc doit obligatoirement être étendue.
*
* @category Php5
* @package Referentiel
* @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$
*/
abstract class AppliModele extends Modele {
protected $distinction = '0';
protected $limite_debut = null;
protected $limite_nbre = null;
protected $url_jrest = null;
public function __construct() {
parent::__construct();
$this->url_jrest = config::get('url_jrest');
}
public function avoirLimitation() {
$limitation = false;
if (!is_null($this->limite_debut) && !is_null($this->limite_nbre)) {
$limitation = true;
}
return $limitation;
}
public function setDistinction($distinct) {
$this->distinction = $distinct;
}
public function getDistinction() {
return $this->distinction;
}
public function setLimitation($limite_debut, $limite_nbre) {
$this->limite_debut = $limite_debut;
$this->limite_nbre = $limite_nbre;
}
public function getLimiteDebut() {
return $this->limite_debut;
}
public function getLimiteNbre() {
return $this->limite_nbre;
}
}
/trunk/modeles/TableStructureDao.php
New file
0,0 → 1,45
<?php
// declare(encoding='UTF-8');
/**
* Modèle d'accès à la base de données des Référentiels.
* Service concernant les tests
*
* @package Referentiel
* @category Php 5.2
* @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 TableStructureDao extends AppliModele {
const SERVICE = 'RefTableStructure';
/**
* Retourne l'ensemble des information sur les colonnes d'une table.
*
* @param string le nom de la table.
* @return array un tableau contenant les informations sur les colonnes de la table.
*/
public function getColonnes($table) {
$url = $this->url_jrest.self::SERVICE."/colonnes/$table";
$json = file_get_contents($url);
$donnees = json_decode($json, true);
return $donnees['colonnes'];
}
/**
* Retourne l'ensemble des information d'analyse de la structure d'une table.
*
* @param string le nom de la table.
* @return array un tableau contenant les informations de l'analyse de la table.
*/
public function getAnalyse($table) {
$url = $this->url_jrest.self::SERVICE."/analyse/$table";
$json = file_get_contents($url);
$donnees = json_decode($json, true);
return $donnees['analyses'];
}
}
?>
/trunk/A_LIRE.txt
New file
0,0 → 1,4
Cette application nécessite le framework de Tela Botanica pour fonctionner.
Il est disponible ici : http://svn.tela-botanica.net/websvn/listing.php?repname=Applications.framework
 
L'ensemble des fichiers de l'application sont dans l'encodage UTF-8.
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/trunk/configurations/config.default.ini
New file
0,0 → 1,46
; +------------------------------------------------------------------------------------------------------+
; Général
; Séparateur de dossier
ds = DIRECTORY_SEPARATOR
 
; +------------------------------------------------------------------------------------------------------+
; Info sur l'application
info.nom = Consultation des Collections
; Abréviation de l'application
info.abr = REF
; Version du Framework nécessaire au fonctionnement de cette application
info.framework.version = 0.2
;Encodage de l'application
appli_encodage = "UTF-8"
; Nom de domaine pour l'URL de base de l'application : 162.38.234.6
domaine = "localhost"
; URL de base de l'application, si elle est laissée vide, l'application fonctionnera en Stand-alone
url_base = "http://{ref:domaine}/referentiel/index.php"
; Mettre à true si l'application nécessite de s'identifier.
identification = false
 
; +------------------------------------------------------------------------------------------------------+
; Paramètrage de la session
; Devons nous démarrer une session : oui (true) ou non (false)
session_demarrage = "php:true"
; Définition du nom de la session à utiliser
session_nom = "referentiel"
 
; +------------------------------------------------------------------------------------------------------+
; Débogage
; Indique si oui ou non on veut afficher le débogage.
fw_debogage = true
; Indique si oui ou non on veut lancer le chronométrage
chronometrage = true
 
; +------------------------------------------------------------------------------------------------------+
; Spécifique à l'application
; Url du Jrest utilisé pour les services web fournissant les données à l'application
url_jrest = "http://localhost/referentiel/jrest/"
 
; +------------------------------------------------------------------------------------------------------+
; Spécifique au module Consultation
; Nombre de résultats par page par défaut
resultat_par_page_defaut = "50"
; Nombre de résultats par page, choix proposés
resultat_par_page_choix = "20,50,100,200"
/trunk/configurations/referentiel_v2.1.ini
New file
0,0 → 1,40
version = 2.1
champs = "num_nom,num_nom_retenu,num_tax_sup,rang,nom_complet,nom_supra_generique,genre,epithete_infra_generique,epithete_sp,type_epithete,epithete_infra_sp,cultivar_groupe,cultivar,nom_commercial,auteur,annee,biblio_origine,notes,nom_addendum,homonyme,basionyme,synonyme_proparte,synonyme_douteux,synonyme_mal_applique,synonyme_orthographique,biblio_statut,hybride_parent_01,hybride_parent_01_notes,hybride_parent_02,hybride_parent_02_notes,nom_francais,presence,statut_origine,statut_introduction,statut_culture"
champs_type = "num_nom=INT,
num_nom_retenu=INT,
num_tax_sup=INT,
rang=INT,
nom_complet=VARCHAR,
nom_supra_generique=VARCHAR,
genre=VARCHAR,
epithete_infra_generique=VARCHAR,
epithete_sp=VARCHAR,
type_epithete=VARCHAR,
epithete_infra_sp=VARCHAR,
cultivar_groupe=VARCHAR,
cultivar=VARCHAR,
nom_commercial=VARCHAR,
auteur=VARCHAR,
annee=INT,
biblio_origine=VARCHAR,
notes=TEXT,
nom_addendum=VARCHAR,
homonyme=INT,
basionyme=INT,
synonyme_proparte=VARCHAR,
synonyme_douteux=BOOL,
synonyme_mal_applique=BOOL,
synonyme_orthographique=INT,
biblio_statut=TEXT,
hybride_parent_01=INT,
hybride_parent_01_notes=TEXT,
hybride_parent_02=INT,
hybride_parent_02_notes=TEXT,
nom_francais=VARCHAR,
presence=VARCHAR,
statut_origine=VARCHAR,
statut_introduction=VARCHAR,
statut_culture=VARCHAR"
rangs = "10,20,30,40,50,55,40,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300,310,320,340,350,360,370,380,390,400,410,420,430"
rang_genre="220"
rang_sp="290"
/trunk/configurations/.htaccess
New file
0,0 → 1,2
# Ce fichier est là pour éviter l'accès au fichier .ini depuis un navigateur.
deny from all
/trunk/framework.defaut.php
New file
0,0 → 1,6
<?php
// Inclusion du Framework
// Renomer ce fichier en "framework.php"
// Indiquyer ci-dessous le chemin vers le fichier autoload.inc.php de la bonne version du Framework
require_once '/framework/0.2/autoload.inc.php';
?>
/trunk/referentiel.php
New file
0,0 → 1,52
<?php
// declare(encoding='UTF-8');
/**
* Application permettant de tester, versionner et consulter les référentiels de travail.
* Fichier principal d'initialisation.
*
* @category PHP5
* @package Referentiel
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
* @copyright 2010 Tela-Botanica
* @license GPL-v3 et CECILL-v2
* @version SVN:$Id$
*/
// Autoload pour cette application
function __autoload($nom_classe) {
// Tableau des chemins à inclure pour trouver une classe relatif à ce fichier
$chemins = array(
'bibliotheque'.DS.'noyau',
'bibliotheque'.DS.'pear',
'bibliotheque'.DS.'utilitaires',
'composants');
foreach ($chemins as $chemin) {
$fichier_a_inclure = dirname(__FILE__).DS.$chemin.DS.$nom_classe.'.php';
if (file_exists($fichier_a_inclure)) {
include_once $fichier_a_inclure;
return null;
}
}
}
 
// Le fichier autoload.inc.php du Framework de Tela Botanica doit être appelée avant tout autre chose dans l'application.
// Sinon, rien ne sera chargé.
// Chemin du fichier chargeant le framework requis
$framework = dirname(__FILE__).'/framework.php';
if (!file_exists($framework)) {
$e = "Veuillez paramêtrer l'emplacement et la version du Framework dans le fichier $framework";
trigger_error($e, E_USER_ERROR);
} else {
// Inclusion du Framework
require_once $framework;
// Ajout d'information concernant cette application
Application::setChemin(__FILE__);// Obligatoire
Application::setInfo(Config::get('info'));
// Lancement du débogage si nécessaire
if (Config::get('chronometrage')) {
Chronometre::chrono(basename(__FILE__).' - début');
}
// Lancement de l'application
Referentiel::initialiser();
}
?>
/trunk/.htaccess
New file
0,0 → 1,2
#AddHandler x-httpd-php5 .php
#AddDefaultCharset UTF-8
/trunk/bibliotheque/pear/A_LIRE.txt
New file
0,0 → 1,4
Paquetages PEAR :
PEAR -> 1.6.2
Pager -> 2.4.4
Auth -> 1.5.4
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/trunk/bibliotheque/pear/PEAR.php
New file
0,0 → 1,1108
<?php
/**
* PEAR, the PHP Extension and Application Repository
*
* PEAR class and PEAR_Error class
*
* PHP versions 4 and 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 pear
* @package PEAR
* @author Sterling Hughes <sterling@php.net>
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: PEAR.php 10 2010-03-05 14:15:42Z jpm $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**#@+
* ERROR constants
*/
define('PEAR_ERROR_RETURN', 1);
define('PEAR_ERROR_PRINT', 2);
define('PEAR_ERROR_TRIGGER', 4);
define('PEAR_ERROR_DIE', 8);
define('PEAR_ERROR_CALLBACK', 16);
/**
* WARNING: obsolete
* @deprecated
*/
define('PEAR_ERROR_EXCEPTION', 32);
/**#@-*/
define('PEAR_ZE2', (function_exists('version_compare') &&
version_compare(zend_version(), "2-dev", "ge")));
 
if (substr(PHP_OS, 0, 3) == 'WIN') {
define('OS_WINDOWS', true);
define('OS_UNIX', false);
define('PEAR_OS', 'Windows');
} else {
define('OS_WINDOWS', false);
define('OS_UNIX', true);
define('PEAR_OS', 'Unix'); // blatant assumption
}
 
// instant backwards compatibility
if (!defined('PATH_SEPARATOR')) {
if (OS_WINDOWS) {
define('PATH_SEPARATOR', ';');
} else {
define('PATH_SEPARATOR', ':');
}
}
 
$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN;
$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE;
$GLOBALS['_PEAR_destructor_object_list'] = array();
$GLOBALS['_PEAR_shutdown_funcs'] = array();
$GLOBALS['_PEAR_error_handler_stack'] = array();
 
@ini_set('track_errors', true);
 
/**
* Base class for other PEAR classes. Provides rudimentary
* emulation of destructors.
*
* If you want a destructor in your class, inherit PEAR and make a
* destructor method called _yourclassname (same name as the
* constructor, but with a "_" prefix). Also, in your constructor you
* have to call the PEAR constructor: $this->PEAR();.
* The destructor method will be called without parameters. Note that
* at in some SAPI implementations (such as Apache), any output during
* the request shutdown (in which destructors are called) seems to be
* discarded. If you need to get any debug information from your
* destructor, use error_log(), syslog() or something similar.
*
* IMPORTANT! To use the emulated destructors you need to create the
* objects by reference: $obj =& new PEAR_child;
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.6.1
* @link http://pear.php.net/package/PEAR
* @see PEAR_Error
* @since Class available since PHP 4.0.2
* @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear
*/
class PEAR
{
// {{{ properties
 
/**
* Whether to enable internal debug messages.
*
* @var bool
* @access private
*/
var $_debug = false;
 
/**
* Default error mode for this object.
*
* @var int
* @access private
*/
var $_default_error_mode = null;
 
/**
* Default error options used for this object when error mode
* is PEAR_ERROR_TRIGGER.
*
* @var int
* @access private
*/
var $_default_error_options = null;
 
/**
* Default error handler (callback) for this object, if error mode is
* PEAR_ERROR_CALLBACK.
*
* @var string
* @access private
*/
var $_default_error_handler = '';
 
/**
* Which class to use for error objects.
*
* @var string
* @access private
*/
var $_error_class = 'PEAR_Error';
 
/**
* An array of expected errors.
*
* @var array
* @access private
*/
var $_expected_errors = array();
 
// }}}
 
// {{{ constructor
 
/**
* Constructor. Registers this object in
* $_PEAR_destructor_object_list for destructor emulation if a
* destructor object exists.
*
* @param string $error_class (optional) which class to use for
* error objects, defaults to PEAR_Error.
* @access public
* @return void
*/
function PEAR($error_class = null)
{
$classname = strtolower(get_class($this));
if ($this->_debug) {
print "PEAR constructor called, class=$classname\n";
}
if ($error_class !== null) {
$this->_error_class = $error_class;
}
while ($classname && strcasecmp($classname, "pear")) {
$destructor = "_$classname";
if (method_exists($this, $destructor)) {
global $_PEAR_destructor_object_list;
$_PEAR_destructor_object_list[] = &$this;
if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
register_shutdown_function("_PEAR_call_destructors");
$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
}
break;
} else {
$classname = get_parent_class($classname);
}
}
}
 
// }}}
// {{{ destructor
 
/**
* Destructor (the emulated type of...). Does nothing right now,
* but is included for forward compatibility, so subclass
* destructors should always call it.
*
* See the note in the class desciption about output from
* destructors.
*
* @access public
* @return void
*/
function _PEAR() {
if ($this->_debug) {
printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));
}
}
 
// }}}
// {{{ getStaticProperty()
 
/**
* If you have a class that's mostly/entirely static, and you need static
* properties, you can use this method to simulate them. Eg. in your method(s)
* do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar');
* You MUST use a reference, or they will not persist!
*
* @access public
* @param string $class The calling classname, to prevent clashes
* @param string $var The variable to retrieve.
* @return mixed A reference to the variable. If not set it will be
* auto initialised to NULL.
*/
function &getStaticProperty($class, $var)
{
static $properties;
if (!isset($properties[$class])) {
$properties[$class] = array();
}
if (!array_key_exists($var, $properties[$class])) {
$properties[$class][$var] = null;
}
return $properties[$class][$var];
}
 
// }}}
// {{{ registerShutdownFunc()
 
/**
* Use this function to register a shutdown method for static
* classes.
*
* @access public
* @param mixed $func The function name (or array of class/method) to call
* @param mixed $args The arguments to pass to the function
* @return void
*/
function registerShutdownFunc($func, $args = array())
{
// if we are called statically, there is a potential
// that no shutdown func is registered. Bug #6445
if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
register_shutdown_function("_PEAR_call_destructors");
$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
}
$GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
}
 
// }}}
// {{{ isError()
 
/**
* Tell whether a value is a PEAR error.
*
* @param mixed $data the value to test
* @param int $code if $data is an error object, return true
* only if $code is a string and
* $obj->getMessage() == $code or
* $code is an integer and $obj->getCode() == $code
* @access public
* @return bool true if parameter is an error
*/
function isError($data, $code = null)
{
if (is_a($data, 'PEAR_Error')) {
if (is_null($code)) {
return true;
} elseif (is_string($code)) {
return $data->getMessage() == $code;
} else {
return $data->getCode() == $code;
}
}
return false;
}
 
// }}}
// {{{ setErrorHandling()
 
/**
* Sets how errors generated by this object should be handled.
* Can be invoked both in objects and statically. If called
* statically, setErrorHandling sets the default behaviour for all
* PEAR objects. If called in an object, setErrorHandling sets
* the default behaviour for that object.
*
* @param int $mode
* One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
* PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION.
*
* @param mixed $options
* When $mode is PEAR_ERROR_TRIGGER, this is the error level (one
* of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
*
* When $mode is PEAR_ERROR_CALLBACK, this parameter is expected
* to be the callback function or method. A callback
* function is a string with the name of the function, a
* callback method is an array of two elements: the element
* at index 0 is the object, and the element at index 1 is
* the name of the method to call in the object.
*
* When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is
* a printf format string used when printing the error
* message.
*
* @access public
* @return void
* @see PEAR_ERROR_RETURN
* @see PEAR_ERROR_PRINT
* @see PEAR_ERROR_TRIGGER
* @see PEAR_ERROR_DIE
* @see PEAR_ERROR_CALLBACK
* @see PEAR_ERROR_EXCEPTION
*
* @since PHP 4.0.5
*/
 
function setErrorHandling($mode = null, $options = null)
{
if (isset($this) && is_a($this, 'PEAR')) {
$setmode = &$this->_default_error_mode;
$setoptions = &$this->_default_error_options;
} else {
$setmode = &$GLOBALS['_PEAR_default_error_mode'];
$setoptions = &$GLOBALS['_PEAR_default_error_options'];
}
 
switch ($mode) {
case PEAR_ERROR_EXCEPTION:
case PEAR_ERROR_RETURN:
case PEAR_ERROR_PRINT:
case PEAR_ERROR_TRIGGER:
case PEAR_ERROR_DIE:
case null:
$setmode = $mode;
$setoptions = $options;
break;
 
case PEAR_ERROR_CALLBACK:
$setmode = $mode;
// class/object method callback
if (is_callable($options)) {
$setoptions = $options;
} else {
trigger_error("invalid error callback", E_USER_WARNING);
}
break;
 
default:
trigger_error("invalid error mode", E_USER_WARNING);
break;
}
}
 
// }}}
// {{{ expectError()
 
/**
* This method is used to tell which errors you expect to get.
* Expected errors are always returned with error mode
* PEAR_ERROR_RETURN. Expected error codes are stored in a stack,
* and this method pushes a new element onto it. The list of
* expected errors are in effect until they are popped off the
* stack with the popExpect() method.
*
* Note that this method can not be called statically
*
* @param mixed $code a single error code or an array of error codes to expect
*
* @return int the new depth of the "expected errors" stack
* @access public
*/
function expectError($code = '*')
{
if (is_array($code)) {
array_push($this->_expected_errors, $code);
} else {
array_push($this->_expected_errors, array($code));
}
return sizeof($this->_expected_errors);
}
 
// }}}
// {{{ popExpect()
 
/**
* This method pops one element off the expected error codes
* stack.
*
* @return array the list of error codes that were popped
*/
function popExpect()
{
return array_pop($this->_expected_errors);
}
 
// }}}
// {{{ _checkDelExpect()
 
/**
* This method checks unsets an error code if available
*
* @param mixed error code
* @return bool true if the error code was unset, false otherwise
* @access private
* @since PHP 4.3.0
*/
function _checkDelExpect($error_code)
{
$deleted = false;
 
foreach ($this->_expected_errors AS $key => $error_array) {
if (in_array($error_code, $error_array)) {
unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
$deleted = true;
}
 
// clean up empty arrays
if (0 == count($this->_expected_errors[$key])) {
unset($this->_expected_errors[$key]);
}
}
return $deleted;
}
 
// }}}
// {{{ delExpect()
 
/**
* This method deletes all occurences of the specified element from
* the expected error codes stack.
*
* @param mixed $error_code error code that should be deleted
* @return mixed list of error codes that were deleted or error
* @access public
* @since PHP 4.3.0
*/
function delExpect($error_code)
{
$deleted = false;
 
if ((is_array($error_code) && (0 != count($error_code)))) {
// $error_code is a non-empty array here;
// we walk through it trying to unset all
// values
foreach($error_code as $key => $error) {
if ($this->_checkDelExpect($error)) {
$deleted = true;
} else {
$deleted = false;
}
}
return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
} elseif (!empty($error_code)) {
// $error_code comes alone, trying to unset it
if ($this->_checkDelExpect($error_code)) {
return true;
} else {
return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
}
} else {
// $error_code is empty
return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
}
}
 
// }}}
// {{{ raiseError()
 
/**
* This method is a wrapper that returns an instance of the
* configured error class with this object's default error
* handling applied. If the $mode and $options parameters are not
* specified, the object's defaults are used.
*
* @param mixed $message a text error message or a PEAR error object
*
* @param int $code a numeric error code (it is up to your class
* to define these if you want to use codes)
*
* @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
* PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION.
*
* @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter
* specifies the PHP-internal error level (one of
* E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
* If $mode is PEAR_ERROR_CALLBACK, this
* parameter specifies the callback function or
* method. In other error modes this parameter
* is ignored.
*
* @param string $userinfo If you need to pass along for example debug
* information, this parameter is meant for that.
*
* @param string $error_class The returned error object will be
* instantiated from this class, if specified.
*
* @param bool $skipmsg If true, raiseError will only pass error codes,
* the error message parameter will be dropped.
*
* @access public
* @return object a PEAR error object
* @see PEAR::setErrorHandling
* @since PHP 4.0.5
*/
function &raiseError($message = null,
$code = null,
$mode = null,
$options = null,
$userinfo = null,
$error_class = null,
$skipmsg = false)
{
// The error is yet a PEAR error object
if (is_object($message)) {
$code = $message->getCode();
$userinfo = $message->getUserInfo();
$error_class = $message->getType();
$message->error_message_prefix = '';
$message = $message->getMessage();
}
 
if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
if ($exp[0] == "*" ||
(is_int(reset($exp)) && in_array($code, $exp)) ||
(is_string(reset($exp)) && in_array($message, $exp))) {
$mode = PEAR_ERROR_RETURN;
}
}
// No mode given, try global ones
if ($mode === null) {
// Class error handler
if (isset($this) && isset($this->_default_error_mode)) {
$mode = $this->_default_error_mode;
$options = $this->_default_error_options;
// Global error handler
} elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
$mode = $GLOBALS['_PEAR_default_error_mode'];
$options = $GLOBALS['_PEAR_default_error_options'];
}
}
 
if ($error_class !== null) {
$ec = $error_class;
} elseif (isset($this) && isset($this->_error_class)) {
$ec = $this->_error_class;
} else {
$ec = 'PEAR_Error';
}
if ($skipmsg) {
$a = &new $ec($code, $mode, $options, $userinfo);
return $a;
} else {
$a = &new $ec($message, $code, $mode, $options, $userinfo);
return $a;
}
}
 
// }}}
// {{{ throwError()
 
/**
* Simpler form of raiseError with fewer options. In most cases
* message, code and userinfo are enough.
*
* @param string $message
*
*/
function &throwError($message = null,
$code = null,
$userinfo = null)
{
if (isset($this) && is_a($this, 'PEAR')) {
$a = &$this->raiseError($message, $code, null, null, $userinfo);
return $a;
} else {
$a = &PEAR::raiseError($message, $code, null, null, $userinfo);
return $a;
}
}
 
// }}}
function staticPushErrorHandling($mode, $options = null)
{
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
$def_mode = &$GLOBALS['_PEAR_default_error_mode'];
$def_options = &$GLOBALS['_PEAR_default_error_options'];
$stack[] = array($def_mode, $def_options);
switch ($mode) {
case PEAR_ERROR_EXCEPTION:
case PEAR_ERROR_RETURN:
case PEAR_ERROR_PRINT:
case PEAR_ERROR_TRIGGER:
case PEAR_ERROR_DIE:
case null:
$def_mode = $mode;
$def_options = $options;
break;
 
case PEAR_ERROR_CALLBACK:
$def_mode = $mode;
// class/object method callback
if (is_callable($options)) {
$def_options = $options;
} else {
trigger_error("invalid error callback", E_USER_WARNING);
}
break;
 
default:
trigger_error("invalid error mode", E_USER_WARNING);
break;
}
$stack[] = array($mode, $options);
return true;
}
 
function staticPopErrorHandling()
{
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
$setmode = &$GLOBALS['_PEAR_default_error_mode'];
$setoptions = &$GLOBALS['_PEAR_default_error_options'];
array_pop($stack);
list($mode, $options) = $stack[sizeof($stack) - 1];
array_pop($stack);
switch ($mode) {
case PEAR_ERROR_EXCEPTION:
case PEAR_ERROR_RETURN:
case PEAR_ERROR_PRINT:
case PEAR_ERROR_TRIGGER:
case PEAR_ERROR_DIE:
case null:
$setmode = $mode;
$setoptions = $options;
break;
 
case PEAR_ERROR_CALLBACK:
$setmode = $mode;
// class/object method callback
if (is_callable($options)) {
$setoptions = $options;
} else {
trigger_error("invalid error callback", E_USER_WARNING);
}
break;
 
default:
trigger_error("invalid error mode", E_USER_WARNING);
break;
}
return true;
}
 
// {{{ pushErrorHandling()
 
/**
* Push a new error handler on top of the error handler options stack. With this
* you can easily override the actual error handler for some code and restore
* it later with popErrorHandling.
*
* @param mixed $mode (same as setErrorHandling)
* @param mixed $options (same as setErrorHandling)
*
* @return bool Always true
*
* @see PEAR::setErrorHandling
*/
function pushErrorHandling($mode, $options = null)
{
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
if (isset($this) && is_a($this, 'PEAR')) {
$def_mode = &$this->_default_error_mode;
$def_options = &$this->_default_error_options;
} else {
$def_mode = &$GLOBALS['_PEAR_default_error_mode'];
$def_options = &$GLOBALS['_PEAR_default_error_options'];
}
$stack[] = array($def_mode, $def_options);
 
if (isset($this) && is_a($this, 'PEAR')) {
$this->setErrorHandling($mode, $options);
} else {
PEAR::setErrorHandling($mode, $options);
}
$stack[] = array($mode, $options);
return true;
}
 
// }}}
// {{{ popErrorHandling()
 
/**
* Pop the last error handler used
*
* @return bool Always true
*
* @see PEAR::pushErrorHandling
*/
function popErrorHandling()
{
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
array_pop($stack);
list($mode, $options) = $stack[sizeof($stack) - 1];
array_pop($stack);
if (isset($this) && is_a($this, 'PEAR')) {
$this->setErrorHandling($mode, $options);
} else {
PEAR::setErrorHandling($mode, $options);
}
return true;
}
 
// }}}
// {{{ loadExtension()
 
/**
* OS independant PHP extension load. Remember to take care
* on the correct extension name for case sensitive OSes.
*
* @param string $ext The extension name
* @return bool Success or not on the dl() call
*/
function loadExtension($ext)
{
if (!extension_loaded($ext)) {
// if either returns true dl() will produce a FATAL error, stop that
if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
return false;
}
if (OS_WINDOWS) {
$suffix = '.dll';
} elseif (PHP_OS == 'HP-UX') {
$suffix = '.sl';
} elseif (PHP_OS == 'AIX') {
$suffix = '.a';
} elseif (PHP_OS == 'OSX') {
$suffix = '.bundle';
} else {
$suffix = '.so';
}
return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
}
return true;
}
 
// }}}
}
 
// {{{ _PEAR_call_destructors()
 
function _PEAR_call_destructors()
{
global $_PEAR_destructor_object_list;
if (is_array($_PEAR_destructor_object_list) &&
sizeof($_PEAR_destructor_object_list))
{
reset($_PEAR_destructor_object_list);
if (PEAR::getStaticProperty('PEAR', 'destructlifo')) {
$_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
}
while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
$classname = get_class($objref);
while ($classname) {
$destructor = "_$classname";
if (method_exists($objref, $destructor)) {
$objref->$destructor();
break;
} else {
$classname = get_parent_class($classname);
}
}
}
// Empty the object list to ensure that destructors are
// not called more than once.
$_PEAR_destructor_object_list = array();
}
 
// Now call the shutdown functions
if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
call_user_func_array($value[0], $value[1]);
}
}
}
 
// }}}
/**
* Standard PEAR error class for PHP 4
*
* This class is supserseded by {@link PEAR_Exception} in PHP 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Gregory Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.6.1
* @link http://pear.php.net/manual/en/core.pear.pear-error.php
* @see PEAR::raiseError(), PEAR::throwError()
* @since Class available since PHP 4.0.2
*/
class PEAR_Error
{
// {{{ properties
 
var $error_message_prefix = '';
var $mode = PEAR_ERROR_RETURN;
var $level = E_USER_NOTICE;
var $code = -1;
var $message = '';
var $userinfo = '';
var $backtrace = null;
 
// }}}
// {{{ constructor
 
/**
* PEAR_Error constructor
*
* @param string $message message
*
* @param int $code (optional) error code
*
* @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN,
* PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,
* PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION
*
* @param mixed $options (optional) error level, _OR_ in the case of
* PEAR_ERROR_CALLBACK, the callback function or object/method
* tuple.
*
* @param string $userinfo (optional) additional user/debug info
*
* @access public
*
*/
function PEAR_Error($message = 'unknown error', $code = null,
$mode = null, $options = null, $userinfo = null)
{
if ($mode === null) {
$mode = PEAR_ERROR_RETURN;
}
$this->message = $message;
$this->code = $code;
$this->mode = $mode;
$this->userinfo = $userinfo;
if (!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {
$this->backtrace = debug_backtrace();
if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
unset($this->backtrace[0]['object']);
}
}
if ($mode & PEAR_ERROR_CALLBACK) {
$this->level = E_USER_NOTICE;
$this->callback = $options;
} else {
if ($options === null) {
$options = E_USER_NOTICE;
}
$this->level = $options;
$this->callback = null;
}
if ($this->mode & PEAR_ERROR_PRINT) {
if (is_null($options) || is_int($options)) {
$format = "%s";
} else {
$format = $options;
}
printf($format, $this->getMessage());
}
if ($this->mode & PEAR_ERROR_TRIGGER) {
trigger_error($this->getMessage(), $this->level);
}
if ($this->mode & PEAR_ERROR_DIE) {
$msg = $this->getMessage();
if (is_null($options) || is_int($options)) {
$format = "%s";
if (substr($msg, -1) != "\n") {
$msg .= "\n";
}
} else {
$format = $options;
}
die(sprintf($format, $msg));
}
if ($this->mode & PEAR_ERROR_CALLBACK) {
if (is_callable($this->callback)) {
call_user_func($this->callback, $this);
}
}
if ($this->mode & PEAR_ERROR_EXCEPTION) {
trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING);
eval('$e = new Exception($this->message, $this->code);throw($e);');
}
}
 
// }}}
// {{{ getMode()
 
/**
* Get the error mode from an error object.
*
* @return int error mode
* @access public
*/
function getMode() {
return $this->mode;
}
 
// }}}
// {{{ getCallback()
 
/**
* Get the callback function/method from an error object.
*
* @return mixed callback function or object/method array
* @access public
*/
function getCallback() {
return $this->callback;
}
 
// }}}
// {{{ getMessage()
 
 
/**
* Get the error message from an error object.
*
* @return string full error message
* @access public
*/
function getMessage()
{
return ($this->error_message_prefix . $this->message);
}
 
 
// }}}
// {{{ getCode()
 
/**
* Get error code from an error object
*
* @return int error code
* @access public
*/
function getCode()
{
return $this->code;
}
 
// }}}
// {{{ getType()
 
/**
* Get the name of this error/exception.
*
* @return string error/exception name (type)
* @access public
*/
function getType()
{
return get_class($this);
}
 
// }}}
// {{{ getUserInfo()
 
/**
* Get additional user-supplied information.
*
* @return string user-supplied information
* @access public
*/
function getUserInfo()
{
return $this->userinfo;
}
 
// }}}
// {{{ getDebugInfo()
 
/**
* Get additional debug information supplied by the application.
*
* @return string debug information
* @access public
*/
function getDebugInfo()
{
return $this->getUserInfo();
}
 
// }}}
// {{{ getBacktrace()
 
/**
* Get the call backtrace from where the error was generated.
* Supported with PHP 4.3.0 or newer.
*
* @param int $frame (optional) what frame to fetch
* @return array Backtrace, or NULL if not available.
* @access public
*/
function getBacktrace($frame = null)
{
if (defined('PEAR_IGNORE_BACKTRACE')) {
return null;
}
if ($frame === null) {
return $this->backtrace;
}
return $this->backtrace[$frame];
}
 
// }}}
// {{{ addUserInfo()
 
function addUserInfo($info)
{
if (empty($this->userinfo)) {
$this->userinfo = $info;
} else {
$this->userinfo .= " ** $info";
}
}
 
// }}}
// {{{ toString()
 
/**
* Make a string representation of this object.
*
* @return string a string with an object summary
* @access public
*/
function toString() {
$modes = array();
$levels = array(E_USER_NOTICE => 'notice',
E_USER_WARNING => 'warning',
E_USER_ERROR => 'error');
if ($this->mode & PEAR_ERROR_CALLBACK) {
if (is_array($this->callback)) {
$callback = (is_object($this->callback[0]) ?
strtolower(get_class($this->callback[0])) :
$this->callback[0]) . '::' .
$this->callback[1];
} else {
$callback = $this->callback;
}
return sprintf('[%s: message="%s" code=%d mode=callback '.
'callback=%s prefix="%s" info="%s"]',
strtolower(get_class($this)), $this->message, $this->code,
$callback, $this->error_message_prefix,
$this->userinfo);
}
if ($this->mode & PEAR_ERROR_PRINT) {
$modes[] = 'print';
}
if ($this->mode & PEAR_ERROR_TRIGGER) {
$modes[] = 'trigger';
}
if ($this->mode & PEAR_ERROR_DIE) {
$modes[] = 'die';
}
if ($this->mode & PEAR_ERROR_RETURN) {
$modes[] = 'return';
}
return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
'prefix="%s" info="%s"]',
strtolower(get_class($this)), $this->message, $this->code,
implode("|", $modes), $levels[$this->level],
$this->error_message_prefix,
$this->userinfo);
}
 
// }}}
}
 
/*
* Local Variables:
* mode: php
* tab-width: 4
* c-basic-offset: 4
* End:
*/
?>
/trunk/bibliotheque/pear/Pager/HtmlWidgets.php
New file
0,0 → 1,229
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Contains the Pager_HtmlWidgets class
*
* PHP versions 4 and 5
*
* LICENSE: Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l dot alberton at quipo dot it>
* @copyright 2003-2006 Lorenzo Alberton
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
* @version CVS: $Id: HtmlWidgets.php 10 2010-03-05 14:15:42Z jpm $
* @link http://pear.php.net/package/Pager
*/
 
/**
* Two constants used to guess the path- and file-name of the page
* when the user doesn't set any other value
*/
class Pager_HtmlWidgets
{
var $pager = null;
// {{{ constructor
function Pager_HtmlWidgets(&$pager)
{
$this->pager =& $pager;
}
// }}}
// {{{ getPerPageSelectBox()
 
/**
* Returns a string with a XHTML SELECT menu,
* useful for letting the user choose how many items per page should be
* displayed. If parameter useSessions is TRUE, this value is stored in
* a session var. The string isn't echoed right now so you can use it
* with template engines.
*
* @param integer $start
* @param integer $end
* @param integer $step
* @param boolean $showAllData If true, perPage is set equal to totalItems.
* @param array (or string $optionText for BC reasons)
* - 'optionText': text to show in each option.
* Use '%d' where you want to see the number of pages selected.
* - 'attributes': (html attributes) Tag attributes or
* HTML attributes (id="foo" pairs), will be inserted in the
* <select> tag
* - 'checkMaxLimit': if true, Pager checks if $end is bigger
* than $totalItems, and doesn't show the extra select options
* @return string xhtml select box
* @access public
*/
function getPerPageSelectBox($start=5, $end=30, $step=5, $showAllData=false, $extraParams=array())
{
// FIXME: needs POST support
$optionText = '%d';
$attributes = '';
$checkMaxLimit = false;
if (is_string($extraParams)) {
//old behavior, BC maintained
$optionText = $extraParams;
} else {
if (array_key_exists('optionText', $extraParams)) {
$optionText = $extraParams['optionText'];
}
if (array_key_exists('attributes', $extraParams)) {
$attributes = $extraParams['attributes'];
}
if (array_key_exists('checkMaxLimit', $extraParams)) {
$checkMaxLimit = $extraParams['checkMaxLimit'];
}
}
 
if (!strstr($optionText, '%d')) {
return $this->pager->raiseError(
$this->pager->errorMessage(ERROR_PAGER_INVALID_PLACEHOLDER),
ERROR_PAGER_INVALID_PLACEHOLDER
);
}
$start = (int)$start;
$end = (int)$end;
$step = (int)$step;
if (!empty($_SESSION[$this->pager->_sessionVar])) {
$selected = (int)$_SESSION[$this->pager->_sessionVar];
} else {
$selected = $this->pager->_perPage;
}
if ($checkMaxLimit && $this->pager->_totalItems > 0 && $this->pager->_totalItems < $end) {
$end = $this->pager->_totalItems;
}
 
$tmp = '<select name="'.$this->pager->_sessionVar.'"';
if (!empty($attributes)) {
$tmp .= ' '.$attributes;
}
$tmp .= '>';
$last = $start;
for ($i=$start; $i<=$end; $i+=$step) {
$last = $i;
$tmp .= '<option value="'.$i.'"';
if ($i == $selected) {
$tmp .= ' selected="selected"';
}
$tmp .= '>'.sprintf($optionText, $i).'</option>';
}
if ($showAllData && $last != $this->pager->_totalItems) {
$tmp .= '<option value="'.$this->pager->_totalItems.'"';
if ($this->pager->_totalItems == $selected) {
$tmp .= ' selected="selected"';
}
$tmp .= '>';
if (empty($this->pager->_showAllText)) {
$tmp .= str_replace('%d', $this->pager->_totalItems, $optionText);
} else {
$tmp .= $this->pager->_showAllText;
}
$tmp .= '</option>';
}
$tmp .= '</select>';
return $tmp;
}
 
// }}}
// {{{ getPageSelectBox()
 
/**
* Returns a string with a XHTML SELECT menu with the page numbers,
* useful as an alternative to the links
*
* @param array - 'optionText': text to show in each option.
* Use '%d' where you want to see the number of pages selected.
* - 'autoSubmit': if TRUE, add some js code to submit the
* form on the onChange event
* @param string $extraAttributes (html attributes) Tag attributes or
* HTML attributes (id="foo" pairs), will be inserted in the
* <select> tag
* @return string xhtml select box
* @access public
*/
function getPageSelectBox($params = array(), $extraAttributes = '')
{
$optionText = '%d';
if (array_key_exists('optionText', $params)) {
$optionText = $params['optionText'];
}
 
if (!strstr($optionText, '%d')) {
return $this->pager->raiseError(
$this->pager->errorMessage(ERROR_PAGER_INVALID_PLACEHOLDER),
ERROR_PAGER_INVALID_PLACEHOLDER
);
}
$tmp = '<select name="'.$this->pager->_urlVar.'"';
if (!empty($extraAttributes)) {
$tmp .= ' '.$extraAttributes;
}
if (!empty($params['autoSubmit'])) {
if ($this->pager->_httpMethod == 'GET') {
$selector = '\' + '.'this.options[this.selectedIndex].value + \'';
if ($this->pager->_append) {
$href = '?' . $this->pager->_http_build_query_wrapper($this->pager->_linkData);
$href = htmlentities($this->pager->_url). preg_replace(
'/(&|&amp;|\?)('.$this->pager->_urlVar.'=)(\d+)/',
'\\1\\2'.$selector,
htmlentities($href)
);
} else {
$href = htmlentities($this->pager->_url . str_replace('%d', $selector, $this->pager->_fileName));
}
$tmp .= ' onchange="document.location.href=\''
. $href .'\''
. '"';
} elseif ($this->pager->_httpMethod == 'POST') {
$tmp .= " onchange='"
. $this->pager->_generateFormOnClick($this->pager->_url, $this->pager->_linkData)
. "'";
$tmp = preg_replace(
'/(input\.name = \"'.$this->pager->_urlVar.'\"; input\.value =) \"(\d+)\";/',
'\\1 this.options[this.selectedIndex].value;',
$tmp
);
}
}
$tmp .= '>';
$start = 1;
$end = $this->pager->numPages();
$selected = $this->pager->getCurrentPageID();
for ($i=$start; $i<=$end; $i++) {
$tmp .= '<option value="'.$i.'"';
if ($i == $selected) {
$tmp .= ' selected="selected"';
}
$tmp .= '>'.sprintf($optionText, $i).'</option>';
}
$tmp .= '</select>';
return $tmp;
}
// }}}
}
?>
/trunk/bibliotheque/pear/Pager/Pager_savebc.php
New file
0,0 → 1,3
<?php
require_once 'Pager.php';
?>
/trunk/bibliotheque/pear/Pager/Common.php
New file
0,0 → 1,1539
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Contains the Pager_Common class
*
* PHP versions 4 and 5
*
* LICENSE: Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l dot alberton at quipo dot it>
* @author Richard Heyes <richard@phpguru.org>
* @copyright 2003-2006 Lorenzo Alberton, Richard Heyes
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
* @version CVS: $Id: Common.php 10 2010-03-05 14:15:42Z jpm $
* @link http://pear.php.net/package/Pager
*/
 
/**
* Two constants used to guess the path- and file-name of the page
* when the user doesn't set any other value
*/
if (substr($_SERVER['PHP_SELF'], -1) == '/') {
$http = !empty($_SERVER['HTTPS']) ? 'https://' : 'http://';
define('CURRENT_FILENAME', '');
define('CURRENT_PATHNAME', $http.$_SERVER['HTTP_HOST'].str_replace('\\', '/', $_SERVER['PHP_SELF']));
} else {
define('CURRENT_FILENAME', preg_replace('/(.*)\?.*/', '\\1', basename($_SERVER['PHP_SELF'])));
define('CURRENT_PATHNAME', str_replace('\\', '/', dirname($_SERVER['PHP_SELF'])));
}
/**
* Error codes
*/
define('PAGER_OK', 0);
define('ERROR_PAGER', -1);
define('ERROR_PAGER_INVALID', -2);
define('ERROR_PAGER_INVALID_PLACEHOLDER', -3);
define('ERROR_PAGER_INVALID_USAGE', -4);
define('ERROR_PAGER_NOT_IMPLEMENTED', -5);
 
/**
* Pager_Common - Common base class for [Sliding|Jumping] Window Pager
* Extend this class to write a custom paging class
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l dot alberton at quipo dot it>
* @author Richard Heyes <richard@phpguru.org>
* @copyright 2003-2005 Lorenzo Alberton, Richard Heyes
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @link http://pear.php.net/package/Pager
*/
class Pager_Common
{
// {{{ class vars
 
/**
* @var integer number of items
* @access private
*/
var $_totalItems;
 
/**
* @var integer number of items per page
* @access private
*/
var $_perPage = 10;
 
/**
* @var integer number of page links for each window
* @access private
*/
var $_delta = 10;
 
/**
* @var integer current page number
* @access private
*/
var $_currentPage = 1;
 
/**
* @var integer total pages number
* @access private
*/
var $_totalPages = 1;
 
/**
* @var string CSS class for links
* @access private
*/
var $_linkClass = '';
 
/**
* @var string wrapper for CSS class name
* @access private
*/
var $_classString = '';
 
/**
* @var string path name
* @access private
*/
var $_path = CURRENT_PATHNAME;
 
/**
* @var string file name
* @access private
*/
var $_fileName = CURRENT_FILENAME;
/**
* @var boolean If false, don't override the fileName option. Use at your own risk.
* @access private
*/
var $_fixFileName = true;
 
/**
* @var boolean you have to use FALSE with mod_rewrite
* @access private
*/
var $_append = true;
 
/**
* @var string specifies which HTTP method to use
* @access private
*/
var $_httpMethod = 'GET';
/**
* @var string specifies which HTML form to use
* @access private
*/
var $_formID = '';
 
/**
* @var boolean whether or not to import submitted data
* @access private
*/
var $_importQuery = true;
 
/**
* @var string name of the querystring var for pageID
* @access private
*/
var $_urlVar = 'pageID';
 
/**
* @var array data to pass through the link
* @access private
*/
var $_linkData = array();
 
/**
* @var array additional URL vars
* @access private
*/
var $_extraVars = array();
/**
* @var array URL vars to ignore
* @access private
*/
var $_excludeVars = array();
 
/**
* @var boolean TRUE => expanded mode (for Pager_Sliding)
* @access private
*/
var $_expanded = true;
/**
* @var boolean TRUE => show accesskey attribute on <a> tags
* @access private
*/
var $_accesskey = false;
 
/**
* @var string extra attributes for the <a> tag
* @access private
*/
var $_attributes = '';
/**
* @var string onclick
* @access private
*/
var $_onclick = '';
 
/**
* @var string alt text for "first page" (use "%d" placeholder for page number)
* @access private
*/
var $_altFirst = 'first page';
 
/**
* @var string alt text for "previous page"
* @access private
*/
var $_altPrev = 'previous page';
 
/**
* @var string alt text for "next page"
* @access private
*/
var $_altNext = 'next page';
 
/**
* @var string alt text for "last page" (use "%d" placeholder for page number)
* @access private
*/
var $_altLast = 'last page';
 
/**
* @var string alt text for "page"
* @access private
*/
var $_altPage = 'page';
 
/**
* @var string image/text to use as "prev" link
* @access private
*/
var $_prevImg = '&lt;&lt; Back';
 
/**
* @var string image/text to use as "next" link
* @access private
*/
var $_nextImg = 'Next &gt;&gt;';
 
/**
* @var string link separator
* @access private
*/
var $_separator = '';
 
/**
* @var integer number of spaces before separator
* @access private
*/
var $_spacesBeforeSeparator = 0;
 
/**
* @var integer number of spaces after separator
* @access private
*/
var $_spacesAfterSeparator = 1;
 
/**
* @var string CSS class name for current page link
* @access private
*/
var $_curPageLinkClassName = '';
 
/**
* @var string Text before current page link
* @access private
*/
var $_curPageSpanPre = '';
 
/**
* @var string Text after current page link
* @access private
*/
var $_curPageSpanPost = '';
 
/**
* @var string Text before first page link
* @access private
*/
var $_firstPagePre = '[';
 
/**
* @var string Text to be used for first page link
* @access private
*/
var $_firstPageText = '';
 
/**
* @var string Text after first page link
* @access private
*/
var $_firstPagePost = ']';
 
/**
* @var string Text before last page link
* @access private
*/
var $_lastPagePre = '[';
 
/**
* @var string Text to be used for last page link
* @access private
*/
var $_lastPageText = '';
 
/**
* @var string Text after last page link
* @access private
*/
var $_lastPagePost = ']';
 
/**
* @var string Will contain the HTML code for the spaces
* @access private
*/
var $_spacesBefore = '';
 
/**
* @var string Will contain the HTML code for the spaces
* @access private
*/
var $_spacesAfter = '';
 
/**
* @var string $_firstLinkTitle
* @access private
*/
var $_firstLinkTitle = 'first page';
 
/**
* @var string $_nextLinkTitle
* @access private
*/
var $_nextLinkTitle = 'next page';
 
/**
* @var string $_prevLinkTitle
* @access private
*/
var $_prevLinkTitle = 'previous page';
 
/**
* @var string $_lastLinkTitle
* @access private
*/
var $_lastLinkTitle = 'last page';
 
/**
* @var string Text to be used for the 'show all' option in the select box
* @access private
*/
var $_showAllText = '';
 
/**
* @var array data to be paged
* @access private
*/
var $_itemData = null;
 
/**
* @var boolean If TRUE and there's only one page, links aren't shown
* @access private
*/
var $_clearIfVoid = true;
 
/**
* @var boolean Use session for storing the number of items per page
* @access private
*/
var $_useSessions = false;
 
/**
* @var boolean Close the session when finished reading/writing data
* @access private
*/
var $_closeSession = false;
 
/**
* @var string name of the session var for number of items per page
* @access private
*/
var $_sessionVar = 'setPerPage';
 
/**
* Pear error mode (when raiseError is called)
* (see PEAR doc)
*
* @var int $_pearErrorMode
* @access private
*/
var $_pearErrorMode = null;
 
// }}}
// {{{ public vars
 
/**
* @var string Complete set of links
* @access public
*/
var $links = '';
 
/**
* @var string Complete set of link tags
* @access public
*/
var $linkTags = '';
 
/**
* @var array Array with a key => value pair representing
* page# => bool value (true if key==currentPageNumber).
* can be used for extreme customization.
* @access public
*/
var $range = array();
/**
* @var array list of available options (safety check)
* @access private
*/
var $_allowed_options = array(
'totalItems',
'perPage',
'delta',
'linkClass',
'path',
'fileName',
'fixFileName',
'append',
'httpMethod',
'formID',
'importQuery',
'urlVar',
'altFirst',
'altPrev',
'altNext',
'altLast',
'altPage',
'prevImg',
'nextImg',
'expanded',
'accesskey',
'attributes',
'onclick',
'separator',
'spacesBeforeSeparator',
'spacesAfterSeparator',
'curPageLinkClassName',
'curPageSpanPre',
'curPageSpanPost',
'firstPagePre',
'firstPageText',
'firstPagePost',
'lastPagePre',
'lastPageText',
'lastPagePost',
'firstLinkTitle',
'nextLinkTitle',
'prevLinkTitle',
'lastLinkTitle',
'showAllText',
'itemData',
'clearIfVoid',
'useSessions',
'closeSession',
'sessionVar',
'pearErrorMode',
'extraVars',
'excludeVars',
'currentPage',
);
 
// }}}
// {{{ build()
 
/**
* Generate or refresh the links and paged data after a call to setOptions()
*
* @access public
*/
function build()
{
//reset
$this->_pageData = array();
$this->links = '';
 
$this->_generatePageData();
$this->_setFirstLastText();
 
if ($this->_totalPages > (2 * $this->_delta + 1)) {
$this->links .= $this->_printFirstPage();
}
 
$this->links .= $this->_getBackLink();
$this->links .= $this->_getPageLinks();
$this->links .= $this->_getNextLink();
 
$this->linkTags .= $this->_getFirstLinkTag();
$this->linkTags .= $this->_getPrevLinkTag();
$this->linkTags .= $this->_getNextLinkTag();
$this->linkTags .= $this->_getLastLinkTag();
 
if ($this->_totalPages > (2 * $this->_delta + 1)) {
$this->links .= $this->_printLastPage();
}
}
 
// }}}
// {{{ getPageData()
 
/**
* Returns an array of current pages data
*
* @param $pageID Desired page ID (optional)
* @return array Page data
* @access public
*/
function getPageData($pageID = null)
{
$pageID = empty($pageID) ? $this->_currentPage : $pageID;
 
if (!isset($this->_pageData)) {
$this->_generatePageData();
}
if (!empty($this->_pageData[$pageID])) {
return $this->_pageData[$pageID];
}
return array();
}
 
// }}}
// {{{ getPageIdByOffset()
 
/**
* Returns pageID for given offset
*
* @param $index Offset to get pageID for
* @return int PageID for given offset
*/
function getPageIdByOffset($index)
{
$msg = '<b>PEAR::Pager Error:</b>'
.' function "getPageIdByOffset()" not implemented.';
return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED);
}
 
// }}}
// {{{ getOffsetByPageId()
 
/**
* Returns offsets for given pageID. Eg, if you
* pass it pageID one and your perPage limit is 10
* it will return (1, 10). PageID of 2 would
* give you (11, 20).
*
* @param integer PageID to get offsets for
* @return array First and last offsets
* @access public
*/
function getOffsetByPageId($pageid = null)
{
$pageid = isset($pageid) ? $pageid : $this->_currentPage;
if (!isset($this->_pageData)) {
$this->_generatePageData();
}
 
if (isset($this->_pageData[$pageid]) || is_null($this->_itemData)) {
return array(
max(($this->_perPage * ($pageid - 1)) + 1, 1),
min($this->_totalItems, $this->_perPage * $pageid)
);
} else {
return array(0, 0);
}
}
 
// }}}
// {{{ getPageRangeByPageId()
 
/**
* @param integer PageID to get offsets for
* @return array First and last offsets
*/
function getPageRangeByPageId($pageID)
{
$msg = '<b>PEAR::Pager Error:</b>'
.' function "getPageRangeByPageId()" not implemented.';
return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED);
}
 
// }}}
// {{{ getLinks()
 
/**
* Returns back/next/first/last and page links,
* both as ordered and associative array.
*
* NB: in original PEAR::Pager this method accepted two parameters,
* $back_html and $next_html. Now the only parameter accepted is
* an integer ($pageID), since the html text for prev/next links can
* be set in the factory. If a second parameter is provided, then
* the method act as it previously did. This hack was done to mantain
* backward compatibility only.
*
* @param integer $pageID Optional pageID. If specified, links
* for that page are provided instead of current one. [ADDED IN NEW PAGER VERSION]
* @param string $next_html HTML to put inside the next link [deprecated: use the factory instead]
* @return array back/next/first/last and page links
*/
function getLinks($pageID=null, $next_html='')
{
$msg = '<b>PEAR::Pager Error:</b>'
.' function "getLinks()" not implemented.';
return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED);
}
 
// }}}
// {{{ getCurrentPageID()
 
/**
* Returns ID of current page
*
* @return integer ID of current page
*/
function getCurrentPageID()
{
return $this->_currentPage;
}
 
// }}}
// {{{ getNextPageID()
 
/**
* Returns next page ID. If current page is last page
* this function returns FALSE
*
* @return mixed Next page ID
*/
function getNextPageID()
{
return ($this->getCurrentPageID() == $this->numPages() ? false : $this->getCurrentPageID() + 1);
}
 
// }}}
// {{{ getPreviousPageID()
 
/**
* Returns previous page ID. If current page is first page
* this function returns FALSE
*
* @return mixed Previous pages' ID
*/
function getPreviousPageID()
{
return $this->isFirstPage() ? false : $this->getCurrentPageID() - 1;
}
 
// }}}
// {{{ numItems()
 
/**
* Returns number of items
*
* @return int Number of items
*/
function numItems()
{
return $this->_totalItems;
}
 
// }}}
// {{{ numPages()
 
/**
* Returns number of pages
*
* @return int Number of pages
*/
function numPages()
{
return (int)$this->_totalPages;
}
 
// }}}
// {{{ isFirstPage()
 
/**
* Returns whether current page is first page
*
* @return bool First page or not
*/
function isFirstPage()
{
return ($this->_currentPage < 2);
}
 
// }}}
// {{{ isLastPage()
 
/**
* Returns whether current page is last page
*
* @return bool Last page or not
*/
function isLastPage()
{
return ($this->_currentPage == $this->_totalPages);
}
 
// }}}
// {{{ isLastPageComplete()
 
/**
* Returns whether last page is complete
*
* @return bool Last age complete or not
*/
function isLastPageComplete()
{
return !($this->_totalItems % $this->_perPage);
}
 
// }}}
// {{{ _generatePageData()
 
/**
* Calculates all page data
* @access private
*/
function _generatePageData()
{
// Been supplied an array of data?
if (!is_null($this->_itemData)) {
$this->_totalItems = count($this->_itemData);
}
$this->_totalPages = ceil((float)$this->_totalItems / (float)$this->_perPage);
$i = 1;
if (!empty($this->_itemData)) {
foreach ($this->_itemData as $key => $value) {
$this->_pageData[$i][$key] = $value;
if (count($this->_pageData[$i]) >= $this->_perPage) {
$i++;
}
}
} else {
$this->_pageData = array();
}
 
//prevent URL modification
$this->_currentPage = min($this->_currentPage, $this->_totalPages);
}
 
// }}}
// {{{ _renderLink()
 
/**
* Renders a link using the appropriate method
*
* @param altText Alternative text for this link (title property)
* @param linkText Text contained by this link
* @return string The link in string form
* @access private
*/
function _renderLink($altText, $linkText)
{
if ($this->_httpMethod == 'GET') {
if ($this->_append) {
$href = '?' . $this->_http_build_query_wrapper($this->_linkData);
} else {
$href = str_replace('%d', $this->_linkData[$this->_urlVar], $this->_fileName);
}
$onclick = '';
if (array_key_exists($this->_urlVar, $this->_linkData)) {
$onclick = str_replace('%d', $this->_linkData[$this->_urlVar], $this->_onclick);
}
return sprintf('<a href="%s"%s%s%s%s title="%s">%s</a>',
htmlentities($this->_url . $href),
empty($this->_classString) ? '' : ' '.$this->_classString,
empty($this->_attributes) ? '' : ' '.$this->_attributes,
empty($this->_accesskey) ? '' : ' accesskey="'.$this->_linkData[$this->_urlVar].'"',
empty($onclick) ? '' : ' onclick="'.$onclick.'"',
$altText,
$linkText
);
} elseif ($this->_httpMethod == 'POST') {
return sprintf("<a href='javascript:void(0)' onclick='%s'%s%s%s title='%s'>%s</a>",
$this->_generateFormOnClick($this->_url, $this->_linkData),
empty($this->_classString) ? '' : ' '.$this->_classString,
empty($this->_attributes) ? '' : ' '.$this->_attributes,
empty($this->_accesskey) ? '' : ' accesskey=\''.$this->_linkData[$this->_urlVar].'\'',
$altText,
$linkText
);
}
return '';
}
 
// }}}
// {{{ _generateFormOnClick()
 
/**
* Mimics http_build_query() behavior in the way the data
* in $data will appear when it makes it back to the server.
* For example:
* $arr = array('array' => array(array('hello', 'world'),
* 'things' => array('stuff', 'junk'));
* http_build_query($arr)
* and _generateFormOnClick('foo.php', $arr)
* will yield
* $_REQUEST['array'][0][0] === 'hello'
* $_REQUEST['array'][0][1] === 'world'
* $_REQUEST['array']['things'][0] === 'stuff'
* $_REQUEST['array']['things'][1] === 'junk'
*
* However, instead of generating a query string, it generates
* Javascript to create and submit a form.
*
* @param string $formAction where the form should be submitted
* @param array $data the associative array of names and values
* @return string A string of javascript that generates a form and submits it
* @access private
*/
function _generateFormOnClick($formAction, $data)
{
// Check we have an array to work with
if (!is_array($data)) {
trigger_error(
'_generateForm() Parameter 1 expected to be Array or Object. Incorrect value given.',
E_USER_WARNING
);
return false;
}
 
if (!empty($this->_formID)) {
$str = 'var form = document.getElementById("'.$this->_formID.'"); var input = ""; ';
} else {
$str = 'var form = document.createElement("form"); var input = ""; ';
}
// We /shouldn't/ need to escape the URL ...
$str .= sprintf('form.action = "%s"; ', htmlentities($formAction));
$str .= sprintf('form.method = "%s"; ', $this->_httpMethod);
foreach ($data as $key => $val) {
$str .= $this->_generateFormOnClickHelper($val, $key);
}
 
if (empty($this->_formID)) {
$str .= 'document.getElementsByTagName("body")[0].appendChild(form);';
}
$str .= 'form.submit(); return false;';
return $str;
}
 
// }}}
// {{{ _generateFormOnClickHelper
 
/**
* This is used by _generateFormOnClick().
* Recursively processes the arrays, objects, and literal values.
*
* @param data Data that should be rendered
* @param prev The name so far
* @return string A string of Javascript that creates form inputs
* representing the data
* @access private
*/
function _generateFormOnClickHelper($data, $prev = '')
{
$str = '';
if (is_array($data) || is_object($data)) {
// foreach key/visible member
foreach ((array)$data as $key => $val) {
// append [$key] to prev
$tempKey = sprintf('%s[%s]', $prev, $key);
$str .= $this->_generateFormOnClickHelper($val, $tempKey);
}
} else { // must be a literal value
// escape newlines and carriage returns
$search = array("\n", "\r");
$replace = array('\n', '\n');
$escapedData = str_replace($search, $replace, $data);
// am I forgetting any dangerous whitespace?
// would a regex be faster?
// if it's already encoded, don't encode it again
if (!$this->_isEncoded($escapedData)) {
$escapedData = urlencode($escapedData);
}
$escapedData = htmlentities($escapedData, ENT_QUOTES, 'UTF-8');
 
$str .= 'input = document.createElement("input"); ';
$str .= 'input.type = "hidden"; ';
$str .= sprintf('input.name = "%s"; ', $prev);
$str .= sprintf('input.value = "%s"; ', $escapedData);
$str .= 'form.appendChild(input); ';
}
return $str;
}
 
// }}}
// {{{ _getLinksData()
 
/**
* Returns the correct link for the back/pages/next links
*
* @return array Data
* @access private
*/
function _getLinksData()
{
$qs = array();
if ($this->_importQuery) {
if ($this->_httpMethod == 'POST') {
$qs = $_POST;
} elseif ($this->_httpMethod == 'GET') {
$qs = $_GET;
}
}
foreach ($this->_excludeVars as $exclude) {
if (array_key_exists($exclude, $qs)) {
unset($qs[$exclude]);
}
}
if (count($this->_extraVars)){
$this->_recursive_urldecode($this->_extraVars);
$qs = array_merge($qs, $this->_extraVars);
}
if (count($qs) && get_magic_quotes_gpc()){
$this->_recursive_stripslashes($qs);
}
return $qs;
}
 
// }}}
// {{{ _recursive_stripslashes()
/**
* Helper method
* @param mixed $var
* @access private
*/
function _recursive_stripslashes(&$var)
{
if (is_array($var)) {
foreach (array_keys($var) as $k) {
$this->_recursive_stripslashes($var[$k]);
}
} else {
$var = stripslashes($var);
}
}
 
// }}}
// {{{ _recursive_urldecode()
 
/**
* Helper method
* @param mixed $var
* @access private
*/
function _recursive_urldecode(&$var)
{
if (is_array($var)) {
foreach (array_keys($var) as $k) {
$this->_recursive_urldecode($var[$k]);
}
} else {
$trans_tbl = array_flip(get_html_translation_table(HTML_ENTITIES));
$var = strtr($var, $trans_tbl);
}
}
 
// }}}
// {{{ _getBackLink()
 
/**
* Returns back link
*
* @param $url URL to use in the link [deprecated: use the factory instead]
* @param $link HTML to use as the link [deprecated: use the factory instead]
* @return string The link
* @access private
*/
function _getBackLink($url='', $link='')
{
//legacy settings... the preferred way to set an option
//now is passing it to the factory
if (!empty($url)) {
$this->_path = $url;
}
if (!empty($link)) {
$this->_prevImg = $link;
}
$back = '';
if ($this->_currentPage > 1) {
$this->_linkData[$this->_urlVar] = $this->getPreviousPageID();
$back = $this->_renderLink($this->_altPrev, $this->_prevImg)
. $this->_spacesBefore . $this->_spacesAfter;
}
return $back;
}
 
// }}}
// {{{ _getPageLinks()
 
/**
* Returns pages link
*
* @param $url URL to use in the link [deprecated: use the factory instead]
* @return string Links
* @access private
*/
function _getPageLinks($url='')
{
$msg = '<b>PEAR::Pager Error:</b>'
.' function "_getPageLinks()" not implemented.';
return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED);
}
 
// }}}
// {{{ _getNextLink()
 
/**
* Returns next link
*
* @param $url URL to use in the link [deprecated: use the factory instead]
* @param $link HTML to use as the link [deprecated: use the factory instead]
* @return string The link
* @access private
*/
function _getNextLink($url='', $link='')
{
//legacy settings... the preferred way to set an option
//now is passing it to the factory
if (!empty($url)) {
$this->_path = $url;
}
if (!empty($link)) {
$this->_nextImg = $link;
}
$next = '';
if ($this->_currentPage < $this->_totalPages) {
$this->_linkData[$this->_urlVar] = $this->getNextPageID();
$next = $this->_spacesAfter
. $this->_renderLink($this->_altNext, $this->_nextImg)
. $this->_spacesBefore . $this->_spacesAfter;
}
return $next;
}
 
// }}}
// {{{ _getFirstLinkTag()
 
/**
* @return string
* @access private
*/
function _getFirstLinkTag()
{
if ($this->isFirstPage() || ($this->_httpMethod != 'GET')) {
return '';
}
return sprintf('<link rel="first" href="%s" title="%s" />'."\n",
$this->_getLinkTagUrl(1),
$this->_firstLinkTitle
);
}
 
// }}}
// {{{ _getPrevLinkTag()
 
/**
* Returns previous link tag
*
* @return string the link tag
* @access private
*/
function _getPrevLinkTag()
{
if ($this->isFirstPage() || ($this->_httpMethod != 'GET')) {
return '';
}
return sprintf('<link rel="previous" href="%s" title="%s" />'."\n",
$this->_getLinkTagUrl($this->getPreviousPageID()),
$this->_prevLinkTitle
);
}
 
// }}}
// {{{ _getNextLinkTag()
 
/**
* Returns next link tag
*
* @return string the link tag
* @access private
*/
function _getNextLinkTag()
{
if ($this->isLastPage() || ($this->_httpMethod != 'GET')) {
return '';
}
return sprintf('<link rel="next" href="%s" title="%s" />'."\n",
$this->_getLinkTagUrl($this->getNextPageID()),
$this->_nextLinkTitle
);
}
 
// }}}
// {{{ _getLastLinkTag()
 
/**
* @return string the link tag
* @access private
*/
function _getLastLinkTag()
{
if ($this->isLastPage() || ($this->_httpMethod != 'GET')) {
return '';
}
return sprintf('<link rel="last" href="%s" title="%s" />'."\n",
$this->_getLinkTagUrl($this->_totalPages),
$this->_lastLinkTitle
);
}
 
// }}}
// {{{ _getLinkTagUrl()
 
/**
* Helper method
* @return string the link tag url
* @access private
*/
function _getLinkTagUrl($pageID)
{
$this->_linkData[$this->_urlVar] = $pageID;
if ($this->_append) {
$href = '?' . $this->_http_build_query_wrapper($this->_linkData);
} else {
$href = str_replace('%d', $this->_linkData[$this->_urlVar], $this->_fileName);
}
return htmlentities($this->_url . $href);
}
// }}}
// {{{ getPerPageSelectBox()
 
/**
* Returns a string with a XHTML SELECT menu,
* useful for letting the user choose how many items per page should be
* displayed. If parameter useSessions is TRUE, this value is stored in
* a session var. The string isn't echoed right now so you can use it
* with template engines.
*
* @param integer $start
* @param integer $end
* @param integer $step
* @param boolean $showAllData If true, perPage is set equal to totalItems.
* @param array (or string $optionText for BC reasons)
* - 'optionText': text to show in each option.
* Use '%d' where you want to see the number of pages selected.
* - 'attributes': (html attributes) Tag attributes or
* HTML attributes (id="foo" pairs), will be inserted in the
* <select> tag
* @return string xhtml select box
* @access public
*/
function getPerPageSelectBox($start=5, $end=30, $step=5, $showAllData=false, $extraParams=array())
{
require_once 'Pager/HtmlWidgets.php';
$widget =& new Pager_HtmlWidgets($this);
return $widget->getPerPageSelectBox($start, $end, $step, $showAllData, $extraParams);
}
 
// }}}
// {{{ getPageSelectBox()
 
/**
* Returns a string with a XHTML SELECT menu with the page numbers,
* useful as an alternative to the links
*
* @param array - 'optionText': text to show in each option.
* Use '%d' where you want to see the number of pages selected.
* - 'autoSubmit': if TRUE, add some js code to submit the
* form on the onChange event
* @param string $extraAttributes (html attributes) Tag attributes or
* HTML attributes (id="foo" pairs), will be inserted in the
* <select> tag
* @return string xhtml select box
* @access public
*/
function getPageSelectBox($params = array(), $extraAttributes = '')
{
require_once 'Pager/HtmlWidgets.php';
$widget =& new Pager_HtmlWidgets($this);
return $widget->getPageSelectBox($params, $extraAttributes);
}
 
// }}}
// {{{ _printFirstPage()
 
/**
* Print [1]
*
* @return string String with link to 1st page,
* or empty string if this is the 1st page.
* @access private
*/
function _printFirstPage()
{
if ($this->isFirstPage()) {
return '';
}
$this->_linkData[$this->_urlVar] = 1;
return $this->_renderLink(
str_replace('%d', 1, $this->_altFirst),
$this->_firstPagePre . $this->_firstPageText . $this->_firstPagePost
) . $this->_spacesBefore . $this->_spacesAfter;
}
 
// }}}
// {{{ _printLastPage()
 
/**
* Print [numPages()]
*
* @return string String with link to last page,
* or empty string if this is the 1st page.
* @access private
*/
function _printLastPage()
{
if ($this->isLastPage()) {
return '';
}
$this->_linkData[$this->_urlVar] = $this->_totalPages;
return $this->_renderLink(
str_replace('%d', $this->_totalPages, $this->_altLast),
$this->_lastPagePre . $this->_lastPageText . $this->_lastPagePost
);
}
 
// }}}
// {{{ _setFirstLastText()
 
/**
* sets the private _firstPageText, _lastPageText variables
* based on whether they were set in the options
*
* @access private
*/
function _setFirstLastText()
{
if ($this->_firstPageText == '') {
$this->_firstPageText = '1';
}
if ($this->_lastPageText == '') {
$this->_lastPageText = $this->_totalPages;
}
}
 
// }}}
// {{{ _http_build_query_wrapper()
/**
* This is a slightly modified version of the http_build_query() function;
* it heavily borrows code from PHP_Compat's http_build_query().
* The main change is the usage of htmlentities instead of urlencode,
* since it's too aggressive
*
* @author Stephan Schmidt <schst@php.net>
* @author Aidan Lister <aidan@php.net>
* @author Lorenzo Alberton <l dot alberton at quipo dot it>
* @param array $data
* @return string
* @access private
*/
function _http_build_query_wrapper($data)
{
$data = (array)$data;
if (empty($data)) {
return '';
}
$separator = ini_get('arg_separator.output');
if ($separator == '&amp;') {
$separator = '&'; //the string is escaped by htmlentities anyway...
}
$tmp = array ();
foreach ($data as $key => $val) {
if (is_scalar($val)) {
//array_push($tmp, $key.'='.$val);
$val = urlencode($val);
array_push($tmp, $key .'='. str_replace('%2F', '/', $val));
continue;
}
// If the value is an array, recursively parse it
if (is_array($val)) {
array_push($tmp, $this->__http_build_query($val, htmlentities($key)));
continue;
}
}
return implode($separator, $tmp);
}
 
// }}}
// {{{ __http_build_query()
 
/**
* Helper function
* @author Stephan Schmidt <schst@php.net>
* @author Aidan Lister <aidan@php.net>
* @access private
*/
function __http_build_query($array, $name)
{
$tmp = array ();
$separator = ini_get('arg_separator.output');
if ($separator == '&amp;') {
$separator = '&'; //the string is escaped by htmlentities anyway...
}
foreach ($array as $key => $value) {
if (is_array($value)) {
//array_push($tmp, $this->__http_build_query($value, sprintf('%s[%s]', $name, $key)));
array_push($tmp, $this->__http_build_query($value, $name.'%5B'.$key.'%5D'));
} elseif (is_scalar($value)) {
//array_push($tmp, sprintf('%s[%s]=%s', $name, htmlentities($key), htmlentities($value)));
array_push($tmp, $name.'%5B'.htmlentities($key).'%5D='.htmlentities($value));
} elseif (is_object($value)) {
//array_push($tmp, $this->__http_build_query(get_object_vars($value), sprintf('%s[%s]', $name, $key)));
array_push($tmp, $this->__http_build_query(get_object_vars($value), $name.'%5B'.$key.'%5D'));
}
}
return implode($separator, $tmp);
}
 
// }}}
// {{{ _isEncoded()
 
/**
* Helper function
* Check if a string is an encoded multibyte string
* @param string $string
* @return boolean
* @access private
*/
function _isEncoded($string)
{
$hexchar = '&#[\dA-Fx]{2,};';
return preg_match("/^(\s|($hexchar))*$/Uims", $string) ? true : false;
}
 
// }}}
// {{{ raiseError()
 
/**
* conditionally includes PEAR base class and raise an error
*
* @param string $msg Error message
* @param int $code Error code
* @access private
*/
function raiseError($msg, $code)
{
include_once 'PEAR.php';
if (empty($this->_pearErrorMode)) {
$this->_pearErrorMode = PEAR_ERROR_RETURN;
}
return PEAR::raiseError($msg, $code, $this->_pearErrorMode);
}
 
// }}}
// {{{ setOptions()
 
/**
* Set and sanitize options
*
* @param mixed $options An associative array of option names and
* their values.
* @return integer error code (PAGER_OK on success)
* @access public
*/
function setOptions($options)
{
foreach ($options as $key => $value) {
if (in_array($key, $this->_allowed_options) && (!is_null($value))) {
$this->{'_' . $key} = $value;
}
}
 
//autodetect http method
if (!isset($options['httpMethod'])
&& !isset($_GET[$this->_urlVar])
&& isset($_POST[$this->_urlVar])
) {
$this->_httpMethod = 'POST';
} else {
$this->_httpMethod = strtoupper($this->_httpMethod);
}
 
$this->_fileName = ltrim($this->_fileName, '/'); //strip leading slash
$this->_path = rtrim($this->_path, '/'); //strip trailing slash
 
if ($this->_append) {
if ($this->_fixFileName) {
$this->_fileName = CURRENT_FILENAME; //avoid possible user error;
}
$this->_url = $this->_path.'/'.$this->_fileName;
} else {
$this->_url = $this->_path;
if (strncasecmp($this->_fileName, 'javascript', 10) != 0) {
$this->_url .= '/';
}
if (strpos($this->_fileName, '%d') === false) {
trigger_error($this->errorMessage(ERROR_PAGER_INVALID_USAGE), E_USER_WARNING);
}
}
 
$this->_classString = '';
if (strlen($this->_linkClass)) {
$this->_classString = 'class="'.$this->_linkClass.'"';
}
 
if (strlen($this->_curPageLinkClassName)) {
$this->_curPageSpanPre = '<span class="'.$this->_curPageLinkClassName.'">';
$this->_curPageSpanPost = '</span>';
}
 
$this->_perPage = max($this->_perPage, 1); //avoid possible user errors
 
if ($this->_useSessions && !isset($_SESSION)) {
session_start();
}
if (!empty($_REQUEST[$this->_sessionVar])) {
$this->_perPage = max(1, (int)$_REQUEST[$this->_sessionVar]);
if ($this->_useSessions) {
$_SESSION[$this->_sessionVar] = $this->_perPage;
}
}
 
if (!empty($_SESSION[$this->_sessionVar])) {
$this->_perPage = $_SESSION[$this->_sessionVar];
}
 
if ($this->_closeSession) {
session_write_close();
}
 
$this->_spacesBefore = str_repeat('&nbsp;', $this->_spacesBeforeSeparator);
$this->_spacesAfter = str_repeat('&nbsp;', $this->_spacesAfterSeparator);
 
if (isset($_REQUEST[$this->_urlVar]) && empty($options['currentPage'])) {
$this->_currentPage = (int)$_REQUEST[$this->_urlVar];
}
$this->_currentPage = max($this->_currentPage, 1);
$this->_linkData = $this->_getLinksData();
 
return PAGER_OK;
}
 
// }}}
// {{{ getOption()
/**
* Return the current value of a given option
*
* @param string option name
* @return mixed option value
*/
function getOption($name)
{
if (!in_array($name, $this->_allowed_options)) {
$msg = '<b>PEAR::Pager Error:</b>'
.' invalid option: '.$name;
return $this->raiseError($msg, ERROR_PAGER_INVALID);
}
return $this->{'_' . $name};
}
 
// }}}
// {{{ getOptions()
 
/**
* Return an array with all the current pager options
*
* @return array list of all the pager options
*/
function getOptions()
{
$options = array();
foreach ($this->_allowed_options as $option) {
$options[$option] = $this->{'_' . $option};
}
return $options;
}
 
// }}}
// {{{ errorMessage()
 
/**
* Return a textual error message for a PAGER error code
*
* @param int $code error code
* @return string error message
* @access public
*/
function errorMessage($code)
{
static $errorMessages;
if (!isset($errorMessages)) {
$errorMessages = array(
ERROR_PAGER => 'unknown error',
ERROR_PAGER_INVALID => 'invalid',
ERROR_PAGER_INVALID_PLACEHOLDER => 'invalid format - use "%d" as placeholder.',
ERROR_PAGER_INVALID_USAGE => 'if $options[\'append\'] is set to false, '
.' $options[\'fileName\'] MUST contain the "%d" placeholder.',
ERROR_PAGER_NOT_IMPLEMENTED => 'not implemented'
);
}
 
return '<b>PEAR::Pager error:</b> '. (isset($errorMessages[$code]) ?
$errorMessages[$code] : $errorMessages[ERROR_PAGER]);
}
 
// }}}
}
?>
/trunk/bibliotheque/pear/Pager/Jumping.php
New file
0,0 → 1,254
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Contains the Pager_Jumping class
*
* PHP versions 4 and 5
*
* LICENSE: Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l dot alberton at quipo dot it>
* @author Richard Heyes <richard@phpguru.org>,
* @copyright 2003-2006 Lorenzo Alberton, Richard Heyes
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
* @version CVS: $Id: Jumping.php 10 2010-03-05 14:15:42Z jpm $
* @link http://pear.php.net/package/Pager
*/
 
/**
* require PEAR::Pager_Common base class
*/
require_once 'Pager/Common.php';
 
/**
* Pager_Jumping - Generic data paging class ("jumping window" style)
* Handles paging a set of data. For usage see the example.php provided.
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l dot alberton at quipo dot it>
* @author Richard Heyes <richard@phpguru.org>,
* @copyright 2003-2005 Lorenzo Alberton, Richard Heyes
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @link http://pear.php.net/package/Pager
*/
class Pager_Jumping extends Pager_Common
{
// {{{ Pager_Jumping()
 
/**
* Constructor
*
* @param array $options An associative array of option names
* and their values
* @access public
*/
function Pager_Jumping($options = array())
{
$err = $this->setOptions($options);
if ($err !== PAGER_OK) {
return $this->raiseError($this->errorMessage($err), $err);
}
$this->build();
}
 
// }}}
// {{{ getPageIdByOffset()
 
/**
* Returns pageID for given offset
*
* @param $index Offset to get pageID for
* @return int PageID for given offset
*/
function getPageIdByOffset($index)
{
if (!isset($this->_pageData)) {
$this->_generatePageData();
}
 
if (($index % $this->_perPage) > 0) {
$pageID = ceil((float)$index / (float)$this->_perPage);
} else {
$pageID = $index / $this->_perPage;
}
return $pageID;
}
 
// }}}
// {{{ getPageRangeByPageId()
 
/**
* Given a PageId, it returns the limits of the range of pages displayed.
* While getOffsetByPageId() returns the offset of the data within the
* current page, this method returns the offsets of the page numbers interval.
* E.g., if you have pageId=3 and delta=10, it will return (1, 10).
* PageID of 8 would give you (1, 10) as well, because 1 <= 8 <= 10.
* PageID of 11 would give you (11, 20).
* If the method is called without parameter, pageID is set to currentPage#.
*
* @param integer PageID to get offsets for
* @return array First and last offsets
* @access public
*/
function getPageRangeByPageId($pageid = null)
{
$pageid = isset($pageid) ? (int)$pageid : $this->_currentPage;
if (isset($this->_pageData[$pageid]) || is_null($this->_itemData)) {
// I'm sure I'm missing something here, but this formula works
// so I'm using it until I find something simpler.
$start = ((($pageid + (($this->_delta - ($pageid % $this->_delta))) % $this->_delta) / $this->_delta) - 1) * $this->_delta +1;
return array(
max($start, 1),
min($start+$this->_delta-1, $this->_totalPages)
);
} else {
return array(0, 0);
}
}
 
// }}}
// {{{ getLinks()
 
/**
* Returns back/next/first/last and page links,
* both as ordered and associative array.
*
* NB: in original PEAR::Pager this method accepted two parameters,
* $back_html and $next_html. Now the only parameter accepted is
* an integer ($pageID), since the html text for prev/next links can
* be set in the constructor. If a second parameter is provided, then
* the method act as it previously did. This hack's only purpose is to
* mantain backward compatibility.
*
* @param integer $pageID Optional pageID. If specified, links
* for that page are provided instead of current one.
* [ADDED IN NEW PAGER VERSION]
* @param string $next_html HTML to put inside the next link
* [deprecated: use the constructor instead]
* @return array Back/pages/next links
*/
function getLinks($pageID=null, $next_html='')
{
//BC hack
if (!empty($next_html)) {
$back_html = $pageID;
$pageID = null;
} else {
$back_html = '';
}
 
if (!is_null($pageID)) {
$this->links = '';
if ($this->_totalPages > $this->_delta) {
$this->links .= $this->_printFirstPage();
}
 
$_sav = $this->_currentPage;
$this->_currentPage = $pageID;
 
$this->links .= $this->_getBackLink('', $back_html);
$this->links .= $this->_getPageLinks();
$this->links .= $this->_getNextLink('', $next_html);
if ($this->_totalPages > $this->_delta) {
$this->links .= $this->_printLastPage();
}
}
 
$back = str_replace('&nbsp;', '', $this->_getBackLink());
$next = str_replace('&nbsp;', '', $this->_getNextLink());
$pages = $this->_getPageLinks();
$first = $this->_printFirstPage();
$last = $this->_printLastPage();
$all = $this->links;
$linkTags = $this->linkTags;
 
if (!is_null($pageID)) {
$this->_currentPage = $_sav;
}
 
return array(
$back,
$pages,
trim($next),
$first,
$last,
$all,
$linkTags,
'back' => $back,
'pages' => $pages,
'next' => $next,
'first' => $first,
'last' => $last,
'all' => $all,
'linktags' => $linkTags
);
}
 
// }}}
// {{{ _getPageLinks()
 
/**
* Returns pages link
*
* @param $url URL to use in the link
* [deprecated: use the constructor instead]
* @return string Links
* @access private
*/
function _getPageLinks($url = '')
{
//legacy setting... the preferred way to set an option now
//is adding it to the constuctor
if (!empty($url)) {
$this->_path = $url;
}
 
//If there's only one page, don't display links
if ($this->_clearIfVoid && ($this->_totalPages < 2)) {
return '';
}
 
$links = '';
$limits = $this->getPageRangeByPageId($this->_currentPage);
 
for ($i=$limits[0]; $i<=min($limits[1], $this->_totalPages); $i++) {
if ($i != $this->_currentPage) {
$this->range[$i] = false;
$this->_linkData[$this->_urlVar] = $i;
$links .= $this->_renderLink($this->_altPage.' '.$i, $i);
} else {
$this->range[$i] = true;
$links .= $this->_curPageSpanPre . $i . $this->_curPageSpanPost;
}
$links .= $this->_spacesBefore
. (($i != $this->_totalPages) ? $this->_separator.$this->_spacesAfter : '');
}
return $links;
}
 
// }}}
}
?>
/trunk/bibliotheque/pear/Pager/Sliding.php
New file
0,0 → 1,289
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Contains the Pager_Sliding class
*
* PHP versions 4 and 5
*
* LICENSE: Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l dot alberton at quipo dot it>
* @copyright 2003-2006 Lorenzo Alberton
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
* @version CVS: $Id: Sliding.php 62 2010-05-06 13:21:56Z jpm $
* @link http://pear.php.net/package/Pager
*/
 
/**
* require PEAR::Pager_Common base class
*/
require_once dirname(__FILE__).'/Common.php';
 
/**
* Pager_Sliding - Generic data paging class ("sliding window" style)
* Usage examples can be found in the PEAR manual
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l dot alberton at quipo dot it>
* @copyright 2003-2005 Lorenzo Alberton
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @link http://pear.php.net/package/Pager
*/
class Pager_Sliding extends Pager_Common
{
// {{{ Pager_Sliding()
 
/**
* Constructor
*
* @param array $options An associative array of option names
* and their values
* @access public
*/
function Pager_Sliding($options = array())
{
//set default Pager_Sliding options
$this->_delta = 2;
$this->_prevImg = '&laquo;';
$this->_nextImg = '&raquo;';
$this->_separator = '|';
$this->_spacesBeforeSeparator = 3;
$this->_spacesAfterSeparator = 3;
$this->_curPageSpanPre = '<b><u>';
$this->_curPageSpanPost = '</u></b>';
 
//set custom options
$err = $this->setOptions($options);
if ($err !== PAGER_OK) {
return $this->raiseError($this->errorMessage($err), $err);
}
$this->build();
}
 
// }}}
// {{{ getPageIdByOffset()
 
/**
* "Overload" PEAR::Pager method. VOID. Not needed here...
* @param integer $index Offset to get pageID for
* @deprecated
* @access public
*/
function getPageIdByOffset($index=null) { }
 
// }}}
// {{{ getPageRangeByPageId()
 
/**
* Given a PageId, it returns the limits of the range of pages displayed.
* While getOffsetByPageId() returns the offset of the data within the
* current page, this method returns the offsets of the page numbers interval.
* E.g., if you have pageId=5 and delta=2, it will return (3, 7).
* PageID of 9 would give you (4, 8).
* If the method is called without parameter, pageID is set to currentPage#.
*
* @param integer PageID to get offsets for
* @return array First and last offsets
* @access public
*/
function getPageRangeByPageId($pageid = null)
{
$pageid = isset($pageid) ? (int)$pageid : $this->_currentPage;
if (!isset($this->_pageData)) {
$this->_generatePageData();
}
if (isset($this->_pageData[$pageid]) || is_null($this->_itemData)) {
if ($this->_expanded) {
$min_surplus = ($pageid <= $this->_delta) ? ($this->_delta - $pageid + 1) : 0;
$max_surplus = ($pageid >= ($this->_totalPages - $this->_delta)) ?
($pageid - ($this->_totalPages - $this->_delta)) : 0;
} else {
$min_surplus = $max_surplus = 0;
}
return array(
max($pageid - $this->_delta - $max_surplus, 1),
min($pageid + $this->_delta + $min_surplus, $this->_totalPages)
);
}
return array(0, 0);
}
 
// }}}
// {{{ getLinks()
 
/**
* Returns back/next/first/last and page links,
* both as ordered and associative array.
*
* @param integer $pageID Optional pageID. If specified, links
* for that page are provided instead of current one.
* @return array back/pages/next/first/last/all links
* @access public
*/
function getLinks($pageID = null)
{
if ($pageID != null) {
$_sav = $this->_currentPage;
$this->_currentPage = $pageID;
 
$this->links = '';
if ($this->_totalPages > (2 * $this->_delta + 1)) {
$this->links .= $this->_printFirstPage();
}
$this->links .= $this->_getBackLink();
$this->links .= $this->_getPageLinks();
$this->links .= $this->_getNextLink();
if ($this->_totalPages > (2 * $this->_delta + 1)) {
$this->links .= $this->_printLastPage();
}
}
 
$back = str_replace('&nbsp;', '', $this->_getBackLink());
$next = str_replace('&nbsp;', '', $this->_getNextLink());
$pages = $this->_getPageLinks();
$first = $this->_printFirstPage();
$last = $this->_printLastPage();
$all = $this->links;
$linkTags = $this->linkTags;
 
if ($pageID != null) {
$this->_currentPage = $_sav;
}
 
return array(
$back,
$pages,
trim($next),
$first,
$last,
$all,
$linkTags,
'back' => $back,
'pages' => $pages,
'next' => $next,
'first' => $first,
'last' => $last,
'all' => $all,
'linktags' => $linkTags
);
}
 
// }}}
// {{{ _getPageLinks()
 
/**
* Returns pages link
*
* @return string Links
* @access private
*/
function _getPageLinks($url = '')
{
//legacy setting... the preferred way to set an option now
//is adding it to the constuctor
if (!empty($url)) {
$this->_path = $url;
}
//If there's only one page, don't display links
if ($this->_clearIfVoid && ($this->_totalPages < 2)) {
return '';
}
 
$links = '';
if ($this->_totalPages > (2 * $this->_delta + 1)) {
if ($this->_expanded) {
if (($this->_totalPages - $this->_delta) <= $this->_currentPage) {
$expansion_before = $this->_currentPage - ($this->_totalPages - $this->_delta);
} else {
$expansion_before = 0;
}
for ($i = $this->_currentPage - $this->_delta - $expansion_before; $expansion_before; $expansion_before--, $i++) {
$print_separator_flag = ($i != $this->_currentPage + $this->_delta); // && ($i != $this->_totalPages - 1)
$this->range[$i] = false;
$this->_linkData[$this->_urlVar] = $i;
$links .= $this->_renderLink($this->_altPage.' '.$i, $i)
. $this->_spacesBefore
. ($print_separator_flag ? $this->_separator.$this->_spacesAfter : '');
}
}
 
$expansion_after = 0;
for ($i = $this->_currentPage - $this->_delta; ($i <= $this->_currentPage + $this->_delta) && ($i <= $this->_totalPages); $i++) {
if ($i < 1) {
++$expansion_after;
continue;
}
 
// check when to print separator
$print_separator_flag = (($i != $this->_currentPage + $this->_delta) && ($i != $this->_totalPages));
 
if ($i == $this->_currentPage) {
$this->range[$i] = true;
$links .= $this->_curPageSpanPre . $i . $this->_curPageSpanPost;
} else {
$this->range[$i] = false;
$this->_linkData[$this->_urlVar] = $i;
$links .= $this->_renderLink($this->_altPage.' '.$i, $i);
}
$links .= $this->_spacesBefore
. ($print_separator_flag ? $this->_separator.$this->_spacesAfter : '');
}
 
if ($this->_expanded && $expansion_after) {
$links .= $this->_separator . $this->_spacesAfter;
for ($i = $this->_currentPage + $this->_delta +1; $expansion_after; $expansion_after--, $i++) {
$print_separator_flag = ($expansion_after != 1);
$this->range[$i] = false;
$this->_linkData[$this->_urlVar] = $i;
$links .= $this->_renderLink($this->_altPage.' '.$i, $i)
. $this->_spacesBefore
. ($print_separator_flag ? $this->_separator.$this->_spacesAfter : '');
}
}
 
} else {
//if $this->_totalPages <= (2*Delta+1) show them all
for ($i=1; $i<=$this->_totalPages; $i++) {
if ($i != $this->_currentPage) {
$this->range[$i] = false;
$this->_linkData[$this->_urlVar] = $i;
$links .= $this->_renderLink($this->_altPage.' '.$i, $i);
} else {
$this->range[$i] = true;
$links .= $this->_curPageSpanPre . $i . $this->_curPageSpanPost;
}
$links .= $this->_spacesBefore
. (($i != $this->_totalPages) ? $this->_separator.$this->_spacesAfter : '');
}
}
return $links;
}
 
// }}}
}
?>
/trunk/bibliotheque/pear/Pager.php
New file
0,0 → 1,193
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Contains the Pager class
*
* PHP versions 4 and 5
*
* LICENSE: Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l dot alberton at quipo dot it>
* @author Richard Heyes <richard@phpguru.org>
* @copyright 2003-2006 Lorenzo Alberton, Richard Heyes
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
* @version CVS: $Id: Pager.php 19 2010-03-24 18:22:25Z jpm $
* @link http://pear.php.net/package/Pager
*/
 
/**
* Pager - Wrapper class for [Sliding|Jumping]-window Pager
* Usage examples can be found in the PEAR manual
*
* @category HTML
* @package Pager
* @author Lorenzo Alberton <l dot alberton at quipo dot it>
* @author Richard Heyes <richard@phpguru.org>,
* @copyright 2003-2005 Lorenzo Alberton, Richard Heyes
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @link http://pear.php.net/package/Pager
*/
class Pager
{
// {{{ Pager()
 
/**
* Constructor
*
* -------------------------------------------------------------------------
* VALID options are (default values are set some lines before):
* - mode (string): "Jumping" or "Sliding" -window - It determines
* pager behaviour. See the manual for more details
* - totalItems (int): # of items to page.
* - perPage (int): # of items per page.
* - delta (int): # of page #s to show before and after the current
* one
* - linkClass (string): name of CSS class used for link styling.
* - append (bool): if true pageID is appended as GET value to the
* URL - if false it is embedded in the URL
* according to "fileName" specs
* - httpMethod (string): Specifies the HTTP method to use. Valid values
* are 'GET' or 'POST'
* according to "fileName" specs
* - importQuery (bool): if true (default behaviour), variables and
* values are imported from the submitted data
* (query string) and used in the generated links
* otherwise they're ignored completely
* - path (string): complete path to the page (without the page name)
* - fileName (string): name of the page, with a %d if append=true
* - urlVar (string): name of pageNumber URL var, for example "pageID"
* - altPrev (string): alt text to display for prev page, on prev link.
* - altNext (string): alt text to display for next page, on next link.
* - altPage (string): alt text to display before the page number.
* - prevImg (string): sth (it can be text such as "<< PREV" or an
* <img/> as well...) to display instead of "<<".
* - nextImg (string): same as prevImg, used for NEXT link, instead of
* the default value, which is ">>".
* - separator (string): what to use to separate numbers (can be an
* <img/>, a comma, an hyphen, or whatever.
* - spacesBeforeSeparator
* (int): number of spaces before the separator.
* - firstPagePre (string):
* string used before first page number (can be an
* <img/>, a "{", an empty string, or whatever.
* - firstPageText (string):
* string used in place of first page number
* - firstPagePost (string):
* string used after first page number (can be an
* <img/>, a "}", an empty string, or whatever.
* - lastPagePre (string):
* similar to firstPagePre.
* - lastPageText (string):
* similar to firstPageText.
* - lastPagePost (string):
* similar to firstPagePost.
* - spacesAfterSeparator
* (int): number of spaces after the separator.
* - firstLinkTitle (string):
* string used as title in <link rel="first"> tag
* - lastLinkTitle (string):
* string used as title in <link rel="last"> tag
* - prevLinkTitle (string):
* string used as title in <link rel="prev"> tag
* - nextLinkTitle (string):
* string used as title in <link rel="next"> tag
* - curPageLinkClassName
* (string): name of CSS class used for current page link.
* - clearIfVoid(bool): if there's only one page, don't display pager.
* - extraVars (array): additional URL vars to be added to the querystring
* - excludeVars (array): URL vars to be excluded in the querystring
* - itemData (array): array of items to page.
* - useSessions (bool): if true, number of items to display per page is
* stored in the $_SESSION[$_sessionVar] var.
* - closeSession (bool): if true, the session is closed just after R/W.
* - sessionVar (string): name of the session var for perPage value.
* A value != from default can be useful when
* using more than one Pager istance in the page.
* - pearErrorMode (constant):
* PEAR_ERROR mode for raiseError().
* Default is PEAR_ERROR_RETURN.
* -------------------------------------------------------------------------
* REQUIRED options are:
* - fileName IF append==false (default is true)
* - itemData OR totalItems (if itemData is set, totalItems is overwritten)
* -------------------------------------------------------------------------
*
* @param mixed $options An associative array of option names and
* their values.
* @access public
*/
function Pager($options = array())
{
//this check evaluates to true on 5.0.0RC-dev,
//so i'm using another one, for now...
//if (version_compare(phpversion(), '5.0.0') == -1) {
if (get_class($this) == 'pager') { //php4 lowers class names
// assign factoried method to this for PHP 4
eval('$this = Pager::factory($options);');
} else { //php5 is case sensitive
$msg = 'Pager constructor is deprecated.'
.' You must use the "Pager::factory($params)" method'
.' instead of "new Pager($params)"';
trigger_error($msg, E_USER_ERROR);
}
}
 
// }}}
// {{{ factory()
 
/**
* Return a pager based on $mode and $options
*
* @param array $options Optional parameters for the storage class
* @return object Object Storage object
* @static
* @access public
*/
static function &factory($options = array())
{
$mode = (isset($options['mode']) ? ucfirst($options['mode']) : 'Jumping');
$classname = 'Pager_' . $mode;
$classfile = 'Pager' . DIRECTORY_SEPARATOR . $mode . '.php';
 
// Attempt to include a custom version of the named class, but don't treat
// a failure as fatal. The caller may have already included their own
// version of the named class.
if (!class_exists($classname)) {
include_once $classfile;
}
 
// If the class exists, return a new instance of it.
if (class_exists($classname)) {
$pager = new $classname($options);
return $pager;
}
 
$null = null;
return $null;
}
 
// }}}
}
?>
/trunk/index.php
New file
0,0 → 1,94
<?php
// declare(encoding='UTF-8');
/** Inclusion du fichier principal de l'application*/
require_once 'referentiel.php';
?>
<!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 xml:lang="fr" lang="fr">
<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" />
 
<title><?php echo Referentiel::getMetaTitre(); ?></title>
<meta name="description" content="<?php echo Referentiel::getMetaDescription();?>" />
<meta name="keywords" content="<?php echo Referentiel::getMetaTags();?>" />
<meta name="revisit-after" content="15 days" />
<meta name="robots" content="index,follow" />
<meta name="author" content="Tela Botanica" />
 
<link rel="shortcut icon" type="image/x-icon" href="http://www.tela-botanica.org/favicon.ico" />
<link rel="icon" type="image/png" href="http://www.tela-botanica.org/sites/commun/generique/images/favicones/tela_botanica.png" />
 
<link rel="stylesheet" type="text/css" media="screen" href="http://www.tela-botanica.org/sites/commun/fr/styles/commun_simple.css" />
 
<style type="text/css" media="screen">
<!--
@import "http://www.tela-botanica.org/sites/commun/fr/styles/commun_complexe.css";
@import "http://www.tela-botanica.org/sites/parlons_bota/fr/styles/parlons_bota.css";
-->
</style>
 
<link rel="stylesheet" type="text/css" media="print" href="http://www.tela-botanica.org/sites/commun/fr/styles/impression.css" />
 
<link rel="stylesheet" type="text/css" media="screen" href="squelettes/css/referentiel/referentiel.css" />
<link rel="stylesheet" type="text/css" media="screen" href="squelettes/css/humanity/jquery-ui-1.8.custom.css" />
<link rel="stylesheet" type="text/css" media="screen" href="squelettes/css/referentiel/debogage.css" />
<script type="text/javascript" src="squelettes/js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="squelettes/js/jquery-ui-1.8.custom.min.js"></script>
</head>
<body xml:lang="fr" lang="fr">
<div id="reducteur">
 
<div id="logo_tela">
<a href="/" title="Retour à l'accueil du site">
<img src="http://www.tela-botanica.org/sites/reseau/generique/images/graphisme/logo_jaune.gif" alt="le logo de Tela Botanica"/>
</a>
</div>
<div id="bandeau">
<div id="bandeau_contenu">
<div id="titre_monde">
<h1>Referentiels</h1>
</div>
</div>
</div>
<div id="droite">
<div id="onglets">
<?php echo Referentiel::getContenuNavigation(); ?>
</div>
<div id="contenu">
<div id="entete">
<?php echo Referentiel::getContenuTete(); ?>
</div>
<div id="texte">
<?php echo Referentiel::getContenuCorps(); ?>
</div>
<div id="pied_texte">
<?php echo Referentiel::getContenuPied(); ?>
</div>
</div>
<div>
<?php echo Referentiel::getChrono(); ?>
<?php echo Referentiel::getExceptions(); ?>
</div>
<div id="pied">
<p> &copy;<a href="http://www.tela-botanica.org/" accesskey="1">Tela Botanica</a> / 2000-<?=date('Y')?> - Le réseau des Botanistes Francophones</p>
</div>
</div>
<div id="nav_gauche">
<ul>
<li><a href="<?=basename(__FILE__)?>?module=Test">Test</a></li>
<li><a href="<?=basename(__FILE__)?>?module=Versionnage">Versionnage</a></li>
<li><a href="<?=basename(__FILE__)?>?module=Consultation">Consultation</a></li>
</ul>
</div>
</div>
</body>
</html>
/trunk/squelettes/test.tpl.html
New file
0,0 → 1,58
<!-- REF - DEBUT TEST -->
<script type="text/javascript">
// Function pour cacher / afficher les options de recherche
$(document).ready(function(){
//Hide (Collapse) the toggle containers on load
$(".test .info").hide();
//Switch the "Open" and "Close" state per click
$(".test h2").toggle(function(){
$(this).addClass("active");
}, function () {
$(this).removeClass("active");
});
//Slide up and down on click
$(".test h2").click(function(){
$(this).next(".test .info").slideToggle("slow");
});
});
</script>
<h1>Tests</h1>
 
<?php foreach ($tests as $test) : ?>
<div class="test">
<h2 class="<?=$test['resultat'] ? 'ok' : 'ko';?>"><a href="#"><?=$test['titre']?></a> <span class="resultat"><?=$test['resultat'] ? 'ok' : 'ko';?></span></h2>
<div class="info">
<p class="description"><?=$test['description']?></p>
<?php if (isset($test['message'])) : ?>
<?php if (is_array($test['message'])) : ?>
<table>
<caption><?=count($test['message']['lignes'])?> lignes en erreur</caption>
<thead>
<tr>
<?php foreach ($test['message']['entete'] as $entete) : ?>
<th><?=$entete?></th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<?php foreach ($test['message']['lignes'] as $ligne) : ?>
<tr>
<?php foreach ($ligne as $info) : ?>
<td><?=$info?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else : ?>
<p class="message"><?=$test['message']?></p>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
<!-- REF - FIN TEST -->
/trunk/squelettes/css/referentiel/referentiel.css
New file
0,0 → 1,39
@CHARSET "UTF-8";
/*--------------------------------------------------------------------------------------------------------------*/
/* Général */
 
/*--------------------------------------------------------------------------------------------------------------*/
/* Tests */
.test {
width:800px;}
.test h2{
padding:5px 5px 5px 20px;
background:white url(images/ouvrir.png) no-repeat center left;
font-size:1em;
font-weight:bold;
text-transform:none;
width:775px;}
.test h2.active{ /*--When toggle is triggered, it will shift the image to the bottom to show its "opened" state--*/
background:white url(images/fermer.png) no-repeat center left;}
.test .message, .test .description{
margin:0 0 5px;
padding:5px;
overflow:hidden;
font-size:1em;
width:790px;
clear:both;}
.test .description{
background-color:#f0f0f0;
white-space:pre-wrap;}
.test .message p{
background-color:#FFFFDD;
border:1px solid #FFD700;}
.test .resultat{
text-transform:uppercase;
float:right;}
.test .ok{
background-color:#9ED30D !important;}
.test .ko{
background-color:#E9584C !important;}
.test .espace{
background-color:yellow !important;}
/trunk/squelettes/css/referentiel/debogage.css
New file
0,0 → 1,40
/*--------------------------------------------------------------------------------------------------------------*/
/* Débogage */
.debogage{
color:black;
border:3px solid #6495ed;}
.debogage_fichier, .debogage_ligne{
font-size:10px;
color:#A9A9A9;}
 
/*--------------------------------------------------------------------------------------------------------------*/
/* Tableau du chronométrage du programme */
table#chrono{
display:block;
border:3px solid #6495ed;
border-collapse:collapse;
text-align: center;
margin:0 auto;}
#chrono thead, tfoot{
background-color:#D0E3FA;
border:1px solid #6495ed;}
#chrono tbody{
background-color:#FFFFFF;
border:1px solid #6495ed;}
#chrono th{
font-family:monospace;
border:1px dotted #6495ed;
padding:5px;
background-color:#EFF6FF;
width:25%;}
#chrono td{
font-family:sans-serif;
font-size:80%;
border:1px solid #6495ed;
padding:5px;
text-align:center;}
#chrono caption{
font-family:sans-serif;
text-align: center;
width:90%;
margin:auto;}
/trunk/squelettes/css/referentiel/images/fermer.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/trunk/squelettes/css/referentiel/images/fermer.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/trunk/squelettes/css/referentiel/images/ouvrir.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/trunk/squelettes/css/referentiel/images/ouvrir.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/trunk/controleurs/Test.php
New file
0,0 → 1,705
<?php
// declare(encoding='UTF-8');
/**
* Classe Controleur du module Test.
*
* @package Referentiel
* @category Php5.2
* @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 Test extends AppliControleur {
private $projet = null;
private $tableStructureDao = null;
private $referentielDao = null;
private $manuel = null;
public function __construct() {
parent::__construct();
// Récupération de paramêtres
if (isset($_GET['projet'])) { // code du projet courrant
$this->projet = $_GET['projet'];
}
// Parser le fichier ini contenant certains règles liées à la version du manuel
$this->manuel = parse_ini_file(Config::get('dossier_configurations').DS.Config::get('manuel'));
// Chargement des DAO nécessaires
$this->tableStructureDao = $this->getModele('TableStructureDao');
$this->referentielDao = $this->getModele('ReferentielDao');
}
//+----------------------------------------------------------------------------------------------------------------+
// Méthodes
/**
* Fonction d'affichage par défaut, elle appelle la liste des administrateurs
*/
public function executerActionParDefaut() {
return $this->lancerTest();
}
public function lancerTest() {
$donnees = array();
// Récupération des données à tester
$colonnes = $this->tableStructureDao->getColonnes($this->projet);
$analyses = $this->tableStructureDao->getAnalyse($this->projet);
$noms = $this->referentielDao->getTout($this->projet);
$noms = $this->classerNoms($noms);
// Lancement des tests unitaires
$donnees['tests'][] = $this->testerNombreDeChamps($colonnes);
$donnees['tests'][] = $this->testerNomDesChamps($colonnes);
$donnees['tests'][] = $this->testerTypeDesChamps($colonnes);
$donnees['tests'][] = $this->testerTailleDesChamps($colonnes, $analyses);
$donnees['tests'][] = $this->testerNumNomClePrimaire($colonnes);
$donnees['tests'][] = $this->testerNumNomSuperieurAZero($noms);
$donnees['tests'][] = $this->testerNumNomRetenuSuperieurAZero($noms);
$donnees['tests'][] = $this->testerNumTaxSupEgalZeroUnique($noms);
$donnees['tests'][] = $this->testerTaxSupPourTaxon($noms);
$donnees['tests'][] = $this->testerExitenceTaxonSuperieur($noms);
$donnees['tests'][] = $this->testerClassificationRang($noms);
$donnees['tests'][] = $this->testerClassification($noms);
$donnees['tests'][] = $this->testerRang($noms);
$donnees['tests'][] = $this->testerNomCompletSupraGenerique($noms);
$donnees['tests'][] = $this->testerNomCompletGenre($noms);
$donnees['tests'][] = $this->testerNomCompletInfraGenre($noms);
$donnees['tests'][] = $this->testerNomCompletEspece($noms);
$donnees['tests'][] = $this->testerNomCompletInfraSpecifique($noms);
$donnees['tests'][] = $this->testerNomSupraGeneriqueMotUnique($noms);
$donnees['tests'][] = $this->testerNomSupraGeneriqueEspaces($noms);
//Debug::printr($this->manuel);
$this->setSortie(self::RENDU_CORPS, $this->getVue('test', $donnees));
}
private function classerNoms($noms) {
$noms_classes = array();
foreach ($noms as $nom) {
$noms_classes[$nom['num_nom']] = $nom;
}
return $noms_classes;
}
private function testerNombreDeChamps($colonnes) {
$info = array('titre' => 'Structure -> nombre de champs : %s',
'description' => 'Le nombre de champs présent dans la table doit être supérieur ou égal à 35.',
'resultat' => false);
$nbre_colonnes = count($colonnes);
$info['titre'] = sprintf($info['titre'], $nbre_colonnes);
if ($nbre_colonnes >= 35) {
$info['resultat'] = true;
}
return $info;
}
private function testerNomDesChamps($colonnes) {
$info = array('titre' => 'Structure -> noms des champs',
'description' => 'Les champs de la table contenant le référentiel doivent être conforme à ceux définit par le manuel technique.',
'resultat' => false);
$champs_attendus = explode(',', $this->manuel['champs']);
$champs_presents = array();
foreach ($colonnes as $colonne) {
$champs_presents[$colonne['Field']] = $colonne;
}
$ok = true;
$champs_manquant = array();
foreach ($champs_attendus as $champ_attendu) {
if (!isset($champs_presents[$champ_attendu])) {
$champs_manquant[] = $champ_attendu;
$ok = false;
}
}
$info['resultat'] = $ok;
if (!$ok) {
$info['message'] = 'Champs manquant : '.implode(', ', $champs_manquant).'.';
}
return $info;
}
private function testerTypeDesChamps($colonnes) {
$info = array('titre' => 'Structure -> types des champs',
'description' => 'Les types des champs de la table contenant le référentiel doivent être conforme à ceux définit par le manuel technique.',
'resultat' => false);
$champs_attendus = explode(',', $this->manuel['champs_type']);
$champs_presents = array();
foreach ($colonnes as $colonne) {
$champs_presents[$colonne['Field']] = $colonne['Type'];
}
// Recercherche des erreurs
$champs_erreur = array();
foreach ($champs_attendus as $champ_attendu) {
list($champ_attendu_nom, $champ_attendu_type) = explode('=', trim($champ_attendu));
 
if (isset($champs_presents[$champ_attendu_nom])) {
$champs_present_type = $champs_presents[$champ_attendu_nom];
if (($champ_attendu_type == 'VARCHAR' && strstr($champs_present_type, 'varchar') === false)
|| ($champ_attendu_type == 'TEXT' && strstr($champs_present_type, 'text') === false)
|| ($champ_attendu_type == 'INT' && strstr($champs_present_type, 'int') === false)
|| ($champ_attendu_type == 'BOOL' && preg_match('/(?:bool|boolean|tinyint\(1\))/i', $champs_present_type) === false)) {
$champs_erreur[] = $champ_attendu." vaut ".$champs_present_type;
}
}
}
// Analyse des résultats
if (count($champs_erreur) > 0) {
$info['message'] = "Champs n'ayant pas un bon type : ".implode(', ', $champs_erreur).'.';
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerTailleDesChamps($colonnes, $analyses) {
$info = array('titre' => 'Structure -> champs tronqués',
'description' => "Vérifie que les données de type texte insérées dans la table n'ont pas été tronquées lors de leur insertion.",
'resultat' => false);
$tailles_champs_maxi = array();
foreach ($colonnes as $colonne) {
if (preg_match('/^varchar\(([0-9]+)\)$/', $colonne['Type'], $match)) {
$tailles_champs_maxi[$colonne['Field']] = $match[1];
}
}
$tailles_trouvees = array();
foreach ($analyses as $analyse) {
if (preg_match('/\.([^.]+)$/', $analyse['Field_name'], $match)) {
$tailles_trouvees[$match[1]] = $analyse['Max_length'];
}
}
$champs_erreur = array();
$champs_attendus = explode(',', $this->manuel['champs']);
foreach ($champs_attendus as $champ_attendu) {
if (isset($tailles_champs_maxi[$champ_attendu]) && isset($tailles_trouvees[$champ_attendu])) {
if ($tailles_champs_maxi[$champ_attendu] == $tailles_trouvees[$champ_attendu]) {
$champs_erreur[] = $champ_attendu;
}
}
}
// Analyse des résultats
if (count($champs_erreur) > 0) {
$info['message'] = "Champs possédant des enregistrements avec une taille maximum : ".implode(', ', $champs_erreur).'.';
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerNumNomClePrimaire($colonnes) {
$info = array('titre' => 'Structure -> num_nom est clé primaire',
'description' => "Vérifie que le champ num_nom est bien la clé primaire de la table.",
'resultat' => false);
foreach ($colonnes as $colonne) {
if ($colonne['Field'] == 'num_nom' && $colonne['Key'] == 'PRI') {
$info['resultat'] = true;
}
}
return $info;
}
private function testerNumNomSuperieurAZero($noms) {
$info = array('titre' => 'num_nom -> supérieur à 0',
'description' => "Le champ num_nom doit contenir des nombres entiers supérieurs à 0.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['num_nom'] <= 0) {
$noms_erreur[] = $nom['num_nom'];
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message'] = count($noms_erreur)." enregistrements contiennent dans le champ num_nom une valeur inférieure ou égale à 0.";
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerNumNomRetenuSuperieurAZero($noms) {
$info = array('titre' => 'num_nom_retenu -> supérieur à 0',
'description' => "Le champ num_nom_retenu doit contenir des nombres entiers supérieurs à 0.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['num_nom_retenu'] <= 0) {
$noms_erreur[] = $nom['num_nom'];
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message'] = count($noms_erreur)." enregistrements dont le champ num_nom_retenu est inférieur ou égal à 0 : ".implode(', ', $noms_erreur).'.';
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerNumTaxSupEgalZeroUnique($noms) {
$info = array('titre' => 'num_tax_sup -> égal à 0 unique',
'description' => "Un seul enregistrement doit posséder la valeur 0 dans le champ num_tax_sup. Il correspond au premier taxon de la classification.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if (preg_match('/^0$/', $nom['num_tax_sup'])) {
$noms_erreur[] = $nom['num_nom'];
}
}
// Analyse des résultats
if (count($noms_erreur) > 1) {
$info['message'] = count($noms_erreur)." enregistrements ont une valeur de 0 dans le champ num_tax_sup : ".implode(', ', $noms_erreur).'.';
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerTaxSupPourTaxon($noms) {
$info = array('titre' => 'Classification -> uniquement pour les taxons',
'description' => "Seul les enregistrements représentant un taxon doivent posséder une valeur dans le champ num_tax_sup.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['num_nom_retenu'] == $nom['num_nom'] && preg_match('/^[0-9]+$/', $nom['num_tax_sup'])) {
$noms_erreur[] = $nom['num_nom'];
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message'] = count($noms_erreur)." enregistrements qui n'est pas un taxon et qui possède une valeur dans num_tax_sup : ".implode(', ', $noms_erreur).'.';
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerExitenceTaxonSuperieur($noms) {
$info = array('titre' => 'Classification -> existence du taxon supérieur',
'description' => "Pour chaque enregistrement représentant un taxon doit posséder un taxon supérieur sauf la racine de la classification.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['num_nom_retenu'] == $nom['num_nom']) {
if ($nom['num_tax_sup'] != 0 && !isset($noms[$nom['num_tax_sup']])) {
$noms_erreur[] = $nom['num_nom'];
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message'] = count($noms_erreur)." enregistrements dont le taxon supérieur n'existe pas : ".implode(', ', $noms_erreur).'.';
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerClassificationRang($noms) {
$info = array('titre' => 'Classification -> taxon supérieur avec rang inférieur',
'description' => "Pour chaque enregistrement représentant un taxon, chaque taxon supérieur doit avoir un rang inférieur au taxon courant.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['num_nom_retenu'] == $nom['num_nom']) {
if (isset($noms[$nom['num_tax_sup']])) {
$nom_sup = $noms[$nom['num_tax_sup']];
if ($nom_sup['rang'] > $nom['rang']) {
$noms_erreur[] = $nom['num_nom'];
}
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message'] = count($noms_erreur)." enregistrements avec un problème : ".implode(', ', $noms_erreur).'.';
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerClassification($noms) {
$info = array('titre' => 'Classification -> racine liée à chaque noeud',
'description' => "Pour chaque enregistrement, la classification doit pouvoir être remonté jusqu'à un même nom unique possédant une valeur num_tax_sup de 0.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['num_nom_retenu'] == $nom['num_nom']) {
$classif_ok = $this->remonterClassif($noms, $nom);
if ($classif_ok === false) {
$noms_erreur[] = $nom['num_nom'];
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message'] = count($noms_erreur)." taxons dont la classification n'est pas bonne : ".implode(', ', $noms_erreur).'.';
} else {
$info['resultat'] = true;
}
return $info;
}
private function remonterClassif(&$noms, $nom) {
if (!isset($noms[$nom['num_tax_sup']]) && $nom['num_tax_sup'] == '0') {
return true;
} else if (!isset($noms[$nom['num_tax_sup']]) && $nom['num_tax_sup'] != '0') {
return false;
} else {
return $this->remonterClassif($noms, $noms[$nom['num_tax_sup']]);
}
}
private function testerRang($noms) {
$info = array('titre' => 'rang',
'description' => "Le rang doit correspondre à un valeur numérique définit dans le manuel.",
'resultat' => false);
$rangs = array_flip(explode(',', $this->manuel['rangs']));
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if (!isset($rangs[$nom['rang']])) {
$noms_erreur[] = $nom['num_nom'];
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message'] = count($noms_erreur)." noms dont le rang n'est pas bon : ".implode(', ', $noms_erreur).'.';
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerNomCompletSupraGenerique($noms) {
$info = array('titre' => 'nom_complet -> noms supra-génériques',
'description' => "Si le rang est < à {$this->manuel['rang_genre']} le nom_complet doit correspondre à la valeur du champ nom_supra_generique. ".
"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['rang'] < $this->manuel['rang_genre']) {
$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
$nom_complet_ideal = $this->formaterStyleNomGenre($nom['nom_supra_generique']);
$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
if ($nom['nom_complet'] != $nom_complet_ideal) {
$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerNomCompletGenre($noms) {
$info = array('titre' => 'nom_complet -> noms de genres',
'description' => "Si le rang est = à {$this->manuel['rang_genre']} le nom_complet doit correspondre à la valeur du champ genre. ".
"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['rang'] == $this->manuel['rang_genre']) {
$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
if ($nom['nom_complet'] != $nom_complet_ideal) {
$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerNomCompletInfraGenre($noms) {
$info = array('titre' => 'nom_complet -> noms infra-génériques',
'description' => "Si le rang est > à {$this->manuel['rang_genre']} et < à {$this->manuel['rang_sp']} le nom_complet doit correspondre à une des formules suivantes : \n".
" genre + ' ' + type_epithete + ' ' + epithete_infra_generique \n".
" genre + ' ' + epithete_infra_generique + ' ' + type_epithete=agg. \n".
"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['rang'] > $this->manuel['rang_genre'] && $nom['rang'] < $this->manuel['rang_sp']) {
$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
$nom_complet_ideal = '';
if ($nom['type_epithete'] == 'agg.') {
$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
$nom_complet_ideal .= ' '.$this->formaterStyleNomGenre($nom['epithete_infra_generique']);
$nom_complet_ideal .= ' '.$nom['type_epithete'];
} else {
$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
$nom_complet_ideal .= ' '.$nom['type_epithete'];
$nom_complet_ideal .= ' '.$this->formaterStyleNomGenre($nom['epithete_infra_generique']);
}
$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
if ($nom['nom_complet'] != $nom_complet_ideal) {
$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerNomCompletEspece($noms) {
$info = array('titre' => "nom_complet -> noms d'espèce",
'description' => "Si le rang est = à {$this->manuel['rang_sp']} le nom_complet doit correspondre à la formule : \n".
" genre + ' ' + epithete_sp \n".
"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['rang'] == $this->manuel['rang_sp']) {
$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
$nom_complet_ideal .= ' '.strtolower($nom['epithete_sp']);
$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
if ($nom['nom_complet'] != $nom_complet_ideal) {
$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerNomCompletInfraSpecifique($noms) {
$info = array('titre' => 'nom_complet -> noms infra-spécifiques',
'description' => "Si le rang est > à {$this->manuel['rang_sp']} le nom_complet doit correspondre à la formule : \n".
" genre + ' ' + epithete_sp + ' ' + type_epithete + ' ' + epithete_infra_generique\n".
"Les valeurs des champs cultivar_groupe, cultivar et nom_commercial peuvent s'y ajouter.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['rang'] > $this->manuel['rang_sp']) {
$suffixe_plte_cultivee = $this->construireSuffixeNomPltCultivee($nom);
$nom_complet_ideal = $this->formaterStyleNomGenre($nom['genre']);
$nom_complet_ideal .= ' '.strtolower($nom['epithete_sp']);
$nom_complet_ideal .= ' '.strtolower($nom['type_epithete']);
$nom_complet_ideal .= ' '.strtolower($nom['epithete_infra_sp']);
$nom_complet_ideal .= ($suffixe_plte_cultivee != '' ? ' '.$suffixe_plte_cultivee : '');
if ($nom['nom_complet'] != $nom_complet_ideal) {
$nom_complet_traite = $this->repererEspace($nom['nom_complet']);
$noms_erreur[] = array($nom['num_nom'], $nom_complet_traite, $nom_complet_ideal);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'nom_complet', 'nom_complet corrigé');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerNomSupraGeneriqueMotUnique($noms) {
$info = array('titre' => 'nom_supra_generique -> plusieurs mots',
'description' => "Le champ nom_supra_generique doit contenir un seul mot.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['nom_supra_generique'] != '') {
$mots = explode(' ', trim($nom['nom_supra_generique']));
if (count($mots) > 1) {
$nom_supra_generique_traite = $this->repererEspace($nom['nom_supra_generique']);
$noms_erreur[] = array($nom['num_nom'], $nom_supra_generique_traite);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'nom_supra_generique erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerNomSupraGeneriqueEspaces($noms) {
$info = array('titre' => 'nom_supra_generique -> espaces en trop',
'description' => "Le champ nom_supra_generique ne doit pas contenir d'espace avant ou aprés le nom.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['nom_supra_generique'] != '') {
if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s+$)/', $nom['nom_supra_generique'])) {
$nom_supra_generique_traite = $this->repererEspace($nom['nom_supra_generique']);
$noms_erreur[] = array($nom['num_nom'], $nom_supra_generique_traite);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'nom_supra_generique erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function formaterStyleNomGenre($genre) {
$genre_fmt = '';
if (preg_match('/^\s*([x+])\s+(.+)$/i', $genre, $match)) {
$genre_fmt = strtolower($match[1]).' '.ucfirst(strtolower($match[2]));
} else {
$genre_fmt = ucfirst(strtolower($genre));
}
return $genre_fmt;
}
private function repererEspace($nom_complet) {
$nom_complet = str_replace(' ', '<span class="espace">&nbsp;</span>', $nom_complet);
return $nom_complet;
}
private function construireSuffixeNomPltCultivee($nom) {
$suffixe = array();
$suffixe[] = $this->construireNomCultivarGroupe($nom);
$suffixe[] = $this->construireNomCommercial($nom);
$suffixe[] = $this->construireNomCultivar($nom);
$suffixe = array_filter($suffixe);
return implode(' ', $suffixe);
}
private function construireNomCultivarGroupe($nom) {
$nom_groupe_cultivar = '';
if ($nom['cultivar_groupe'] != '') {
if (preg_match('/ gx$/', $nom['cultivar_groupe'])) {
$nom_groupe_cultivar = '('.$nom['cultivar_groupe'].')';
} else {
$nom_groupe_cultivar = '('.$nom['cultivar_groupe'].' Gp)';
}
}
return $nom_groupe_cultivar;
}
private function construireNomCommercial($nom) {
$nom_commercial = '';
if ($nom['nom_commercial'] != '') {
$nom_commercial = strtoupper($nom['nom_commercial']);
}
return $nom_commercial;
}
private function construireNomCultivar($nom) {
$nom_cultivar = '';
if ($nom['cultivar'] != '') {
$nom_cultivar = "'".$nom['cultivar']."'";
}
return $nom_cultivar;
}
}
?>
/trunk/controleurs/AppliControleur.php
New file
0,0 → 1,99
<?php
// declare(encoding='UTF-8');
/**
* Classe Controleur générale partagée par les différents modules de l'application.
*
* @package Referentiel
* @category Php5.2
* @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$
*/
abstract class AppliControleur extends Controleur {
const RENDU_TETE = 'tete';
const RENDU_CORPS = 'corps';
const RENDU_PIED = 'pied';
private $sortie = array();
private $parametres = array();
// FIXME : voir s'il est plus intéressant d'utiliser une méthode dans les classes filles
protected $url = null;
public function __construct() {
$registre = Registre::getInstance();
$this->parametres = $registre->get('parametres');
$this->url = $this->parametres['url'];
parent::__construct();
}
/**
* Attribue à la bonne position de sortie un contenu.
*/
protected function setSortie($position, $contenu, $fusionner = false) {
if ($this->verifierExistencePosition($position)) {
if ($fusionner) {
$this->sortie[$position] .= $contenu;
} else {
$this->sortie[$position] = $contenu;
}
}
}
/**
* Vérifie l'existence de la position indiquée pour son utilisation dans le tableau de sortie.
* @param string la position à tester.
* @return bool true si la position est valide, sinon false.
*/
private function verifierExistencePosition($position) {
$existe = true;
if ($position != self::RENDU_TETE &&
$position != self::RENDU_CORPS &&
$position != self::RENDU_PIED) {
trigger_error("La position '$position' n'est pas une valeur prédéfinie.", E_USER_WARNING);
$existe = false;
}
return $existe;
}
/**
* Retourne le tableau de sortie à utiliser dans le controleur principal de l'application.
*/
public function getSortie() {
return $this->sortie;
}
 
/**
* Execute l'action d'un module donnée et fusionne le résultat avec le tableau de sortie.
*/
protected function executerAction($ClasseModule, $action) {
$module = new $ClasseModule();
$module->$action();
$this->fusionnerSortie($module->getSortie());
}
/**
* Fusionne un tableau de sortie par défaut avec le tableau passé en paramêtre.
* @param array le tableau à fusionner
*/
private function fusionnerSortie($sortie) {
$this->sortie = array_merge($this->sortie, $sortie);
}
protected function postraiterDonnees(&$tableau) {
if (count($tableau) > 0) {
foreach ($tableau as $cle => &$valeur) {
if ($valeur == '') {
$valeur = '&nbsp;';
} else if (is_string($valeur)) {
$valeur = preg_replace('/&(?!amp;)/i', '&amp;', $valeur, -1);
} else if (is_array($valeur)) {
$this->postraiterDonnees($valeur);
}
}
}
}
}
/trunk/controleurs/Referentiel.php
New file
0,0 → 1,185
<?php
// declare(encoding='UTF-8');
/**
* Referentiel est le controlleur principal de l'application.
* Il repartit les demandes utilisateurs dans les différents modules, execute les actions et redistribue le code
* html dans les différentes fonctions d'affichage.
* C'est une Singleton.
*
* @package Referentiel
* @category Php5
* @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 Referentiel extends Controleur {
/**
* Instance de la classe pointant sur elle même (pour le pattern singleton)
*/
private static $instance = null;
/**
* Paramètres pour les collections
*/
private static $parametres = array();
/**
* Constructeur vide
*/
public function __construct() {
$meta = array('titre' => '', 'description' => '', 'tags' => '');
$sortie = array('metadonnees' => $meta, 'corps' => '', 'tete' => '', 'pied' => '', 'navigation' => '');
$url = new Url(Config::get('url_base'));
self::$parametres = array( 'module' => 'Test',
'action' => 'executerActionParDefaut',
'sortie' => $sortie,
'url' => $url);
parent::__construct();
}
/**
* Initialisation du controleur principal en fonction des paramêtres de l'url.
*/
public static function initialiser() {
self::verifierCreationInstance();
self::gererSession();
if (isset($_GET['module'])) {
self::$parametres['module'] = $_GET['module'];
}
self::$parametres['url']->setVariableRequete('module', self::$parametres['module']);
if (isset($_GET['action'])) {
self::$parametres['action'] = $_GET['action'];
}
self::$parametres['url']->setVariableRequete('action', self::$parametres['action']);
$registre = Registre::getInstance();
$registre->set('parametres', &self::$parametres);
$ClasseModule = self::$parametres['module'];
$action = self::$parametres['action'];
$module = new $ClasseModule();
$module->$action();
self::fusionnerSortie($module->getSortie());
}
private static function gererSession() {
if (Config::get('session_demarrage')) {
// Attribution d'un nom à la session
session_name(Config::get('session_nom'));
// Démarrage de la session
session_start();
}
}
/**
* Fusionne un tableau de sortie par défaut avec le tableau renvoyé par l'action du module.
* @param array le tableau à fusionner
*/
private static function fusionnerSortie($sortie) {
self::$parametres['sortie'] = array_merge(self::$parametres['sortie'], $sortie);
}
/**
* Vérifie si l'instance de classe à été crée, si non la crée.
*/
private static function verifierCreationInstance() {
if (empty(self::$instance)) {
self::$instance = new Referentiel();
}
}
/**
* Retourne le titre du contenu de l'application.
*/
public static function getMetaTitre() {
return self::$parametres['sortie']['metadonnees']['titre'];
}
/**
* Retourne la description du contenu de l'application.
*/
public static function getMetaDescription() {
return self::$parametres['sortie']['metadonnees']['description'];
}
/**
* Retourne les mots-clés (tags) du contenu de l'application.
*/
public static function getMetaTags() {
return self::$parametres['sortie']['metadonnees']['tags'];
}
/**
* Retourne le contenu du corps de l'application.
*/
public static function getContenuCorps() {
$sortie = self::$parametres['sortie']['corps'];
if (Config::get('sortie_encodage') != Config::get('appli_encodage')) {
$sortie = mb_convert_encoding($sortie, Config::get('sortie_encodage'), Config::get('appli_encodage'));
}
return $sortie;
}
/**
* Retourne le contenu de la tête de l'application.
*/
public static function getContenuTete() {
$sortie = self::$parametres['sortie']['tete'];
if (Config::get('sortie_encodage') != Config::get('appli_encodage')) {
$sortie = mb_convert_encoding($sortie, Config::get('sortie_encodage'), Config::get('appli_encodage'));
}
return $sortie;
}
/**
* Retourne le contenu du pied de l'application.
*/
public static function getContenuPied() {
$sortie = self::$parametres['sortie']['pied'];
if (Config::get('sortie_encodage') != Config::get('appli_encodage')) {
$sortie = mb_convert_encoding($sortie, Config::get('sortie_encodage'), Config::get('appli_encodage'));
}
return $sortie;
}
/**
* Retourne les éléments de navigation de l'application.
*/
public static function getContenuNavigation() {
$sortie = self::$parametres['sortie']['navigation'];
if (Config::get('sortie_encodage') != Config::get('appli_encodage')) {
$sortie = mb_convert_encoding($sortie, Config::get('sortie_encodage'), Config::get('appli_encodage'));
}
return $sortie;
}
/**
* Retourne les chronos pris dans l'appli
*/
public static function getChrono() {
$sortie = '';
if (Config::get('chronometrage')) {
$chrono = Chronometre::afficherChrono();
$sortie = mb_convert_encoding($chrono, Config::get('sortie_encodage'), Config::get('appli_encodage'));
}
return $sortie;
}
/**
* Retourne les messages d'exceptions et d'erreurs.
*/
public static function getExceptions() {
$sortie = GestionnaireException::getExceptions();
if (Config::get('sortie_encodage') != Config::get('appli_encodage')) {
$sortie = mb_convert_encoding($sortie, Config::get('sortie_encodage'), Config::get('appli_encodage'));
}
return $sortie;
}
}
?>
/trunk/LICENCES.txt
New file
0,0 → 1,3
L'application Referentiel (Ref) est sous double licence (sauf mention contraire dans les fichiers) :
- GPL v3 (http://www.opensource.org/licenses/gpl-3.0.html)
- CECILL (http://www.cecill.info/)
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/trunk/AUTEURS.txt
New file
0,0 → 1,0
Jean-Pascal MILCENT <jpm@tela-botanica.org>.
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/trunk/composants/Composant.php
New file
0,0 → 1,13
<?php
 
class Composant {
 
public static function fabrique($classe, $options = array()) {
$classe_nom = implode('', array_map('ucfirst', explode('_', $classe)));
require_once dirname(__FILE__).DS.$classe.DS.$classe_nom.'.php';
$Composant = new $classe_nom($options);
return $Composant;
}
}
?>
/trunk/composants/fragmenteur/squelettes/defaut.tpl.html
New file
0,0 → 1,45
<!-- FRAGMENTEUR : début -->
<div id="fragmenteur" style="clear:left;">
<h2>Navigation dans les résultats :</h2>
<?php if (isset($alphabet)) : ?>
<p style="margin:0;" class="aide">Cliquer sur une lettre pour faire apparaitre la liste des taxons correspondante :</p>
<p>
<strong>
<?php foreach ($alphabet as $lettre) : ?>
<?php if ($lettre['lettre'] == $lettre_selected) : ?>
<span class="frag_alpha_lien_selection"><?=$lettre['lettre'];?></span>&nbsp;
<?php else : ?>
<a class="frag_alpha_lien" href="<?=$lettre['url']?>"><?=$lettre['lettre'];?></a>&nbsp;
<?php endif; ?>
<?php endforeach; ?>
</strong>
</p>
<?php endif; ?>
<form id="fragmenteur_quantite" action="<?=$url;?>" method="get">
<p>Affichage des données <?=$frag_donnee_debut;?> à <?=$frag_donnee_fin;?> sur <?=$frag_donnee_total;?> résultats.
<?php if ($pager_links['pages']) : ?>
Pages de résultats :&nbsp;
<span class="frag_premier"><?=$pager_links['first'];?>&nbsp;</span>
<span class="frag_precedent"><?=$pager_links['back'];?>&nbsp;</span>
<span class="frag_pages"><?=$pager_links['pages'];?>&nbsp;</span>
<span class="frag_suivant"><?=$pager_links['next'];?>&nbsp;</span>
<span class="frag_dernier"><?=$pager_links['last'];?>&nbsp;</span>
.
<?php endif; ?>
Nombre de résultats par page :
<select id="frag_nbre" name="frag_nbre" onchange="javascript:this.form.submit();">
<option value="*" <?= ($par_page_selected == '*') ? 'selected="selected"': '';?>>tous</option>
<?php foreach ($par_page as $nbre) : ?>
<option value="<?=$nbre;?>" <?=$nbre == $par_page_selected? 'selected="selected"': '';?>><?=$nbre;?></option>
<?php endforeach; ?>
</select>
<?php foreach ($form_get_url_chp_hidden as $cle => $val) : ?>
<input type="hidden" name="<?=$cle;?>" value="<?=$val;?>" />
<?php endforeach; ?>
</p>
</form>
</div>
<!-- FRAGMENTEUR : fin -->
/trunk/composants/fragmenteur/Fragmenteur.php
New file
0,0 → 1,171
<?php
 
class Fragmenteur {
const PAGER_MODE = 'Sliding';
const PAGE_DELTA = 2;
const PAGE_SEPARATEUR = '-';
const URL_VAR = 'page';
const SQUELETTE = 'defaut';
const DONNEES_PAR_PAGE_CHOIX = '10,20,50,100';
const DONNEES_PAR_PAGE_DEFAUT = 10;
const ALPHABET_AFFICHAGE_DEFAUT = false;
const ALPHABET_LETTRE_DEFAUT = 'A';
private $pager_mode;
private $pager;
private $url;
private $lettre;
private $page_delta;
private $page_separateur;
private $donnees_total;
private $donnees_par_page;
private $donnees_par_page_choix;
private $url_var;
private $squelette;
private $chemin_squelette;
private $recherche_alphabetique;
private $squelette_donnees = array();
public function __construct($options) {
// Gestion de l'url
if (isset($options['url'])) {
if ($options['url'] instanceof Url) {
$this->url = $options['url'];
} else {
$msg = "Fragmenteur nécessite nécessite un objet Url du Framework de Tela Botanica pour fonctionner.";
trigger_error($msg, E_USER_ERROR);
}
} else {
$msg = "Fragmenteur nécessite de renseigner dans le tableau d'options l'url pour la clé 'url'".
trigger_error($msg, E_USER_ERROR);
}
// Gestion de la liste alphabétique
$this->alphabet_affichage = (isset($options['alphabet_affichage']) ? $options['alphabet_affichage'] : self::ALPHABET_AFFICHAGE_DEFAUT);
if ($this->alphabet_affichage == true) {
$lettre = (isset($options['lettre']) ? $options['lettre'] : self::ALPHABET_LETTRE_DEFAUT);
$this->setLettre($lettre);
if (isset($_GET['lettre'])) {
$this->setLettre(urldecode($_GET['lettre']));
}
}
// Gestion des infos pour le pager
$this->squelette = (isset($options['squelette']) ? $options['squelette'] : self::SQUELETTE).'.tpl.html';
$this->chemin_squelette = dirname(__FILE__).DS.'squelettes'.DS.$this->squelette;
$this->pager_mode = (isset($options['pager_mode']) ? $options['pager_mode'] : self::PAGER_MODE);
$this->page_delta = (isset($options['page_delta']) ? $options['page_delta'] : self::PAGE_DELTA);
$this->page_separateur = (isset($options['page_separateur']) ? $options['page_separateur'] : self::PAGE_SEPARATEUR);
$this->url_var = (isset($options['url_var']) ? $options['url_var'] : self::URL_VAR);
$this->donnees_par_page = (isset($options['donnees_par_page']) ? $options['donnees_par_page'] : self::DONNEES_PAR_PAGE_DEFAUT);
$this->donnees_par_page_choix = (isset($options['donnees_par_page_choix']) ? $options['donnees_par_page_choix'] : self::DONNEES_PAR_PAGE_CHOIX);
$this->donnees_total = (isset($options['donnees_total']) ? $options['donnees_total'] : 0);
// Gestion du nombre de données à afficher par page.
if (isset($_GET['frag_nbre'])) {
if ($_GET['frag_nbre'] == '*') {
$_GET['page'] = 1;
}
$_SESSION['fragmenteur']['donnees_par_page'] = $_GET['frag_nbre'];
} else {
$_SESSION['fragmenteur']['donnees_par_page'] = $this->donnees_par_page;
}
$this->donnees_par_page = $_SESSION['fragmenteur']['donnees_par_page'];
if ($this->donnees_par_page == '*') {
$this->donnees_par_page = $this->donnees_total;
}
// Gestion du Fragmenteur (basé sur le Pager de Pear)
$pager_options = array( 'mode' => $this->pager_mode,
'perPage' => $this->donnees_par_page,
'delta' => $this->page_delta,
'totalItems' => $this->donnees_total,
'urlVar' => $this->url_var,
'separator' => $this->page_separateur);
$this->pager = Pager::factory($pager_options);
}
public function getDonneesParPage() {
return $this->donnees_par_page;
}
public function getDeplacementParPageId() {
return $this->pager->getOffsetByPageId();
}
public function getLettre() {
return $this->lettre;
}
public function setLettre($l) {
$this->lettre = $l;
}
public function getDonneesTotal() {
return $this->donnees_total;
}
public function setDonneesTotal($dt) {
$this->donnees_total = $dt;
}
 
private function getSqueletteDonnees() {
return $this->squelette_donnees;
}
private function setSqueletteDonnees($cle, $valeur) {
$this->squelette_donnees[$cle] = $valeur;
}
public function executer() {
// Gestion de la liste alphabétique
if ($this->alphabet_affichage == true) {
$alphabet = array();
$this->url->setVariableRequete('lettre', '*');
$alphabet['*'] = array( 'url' => $this->url->getURL(),
'lettre' => 'tous');
$this->url->unsetVariableRequete('lettre');
for ($i = 65; $i <= 90; $i++){
$this->url->setVariableRequete('lettre', chr($i));
$alphabet[chr($i)] = array('url' => $this->url->getURL(),
'lettre' => chr($i));
$this->url->unsetVariableRequete('lettre');
}
$this->setSqueletteDonnees('alphabet', $alphabet);
// Gestion de la lettre
$this->setSqueletteDonnees('lettre_selected', $this->getLettre());
// Gestion de l'url
$this->url->setVariableRequete('lettre', $this->getLettre());
}
// Gestion des urls
$this->url->setVariableRequete('page', $this->pager->getCurrentPageID());
$this->setSqueletteDonnees('url', $this->url->getURL());
// Gestion du fragmenteur
$this->setSqueletteDonnees('frag_donnee_total', $this->donnees_total);
$page_id_x_saut = ($this->pager->getCurrentPageID() * $this->donnees_par_page);
$this->setSqueletteDonnees('frag_donnee_debut', (($page_id_x_saut - $this->donnees_par_page) > 0 ? ($page_id_x_saut - $this->donnees_par_page) : 0));
$this->setSqueletteDonnees('frag_donnee_fin', ($page_id_x_saut >= $this->donnees_total ? $this->donnees_total : $page_id_x_saut));
$this->setSqueletteDonnees('par_page', explode(',', $this->donnees_par_page_choix));
$this->setSqueletteDonnees('par_page_selected', $_SESSION['fragmenteur']['donnees_par_page']);
$this->setSqueletteDonnees('pager_links', $this->pager->getLinks());
// Gestion des paramêtres pour le formulaire du Fragmenteur
$tab_parties = $this->url->getVariablesRequete();
$form_get_url_chp_hidden = array();
foreach ($tab_parties as $cle => $valeur) {
$form_get_url_chp_hidden[$cle] = $valeur;
}
$this->setSqueletteDonnees('form_get_url_chp_hidden', $form_get_url_chp_hidden);
// Création du rendu à partir du squelette et de ses données
$sortie = SquelettePhp::analyser($this->chemin_squelette, $this->getSqueletteDonnees());
return $sortie;
}
}
?>