Subversion Repositories Applications.referentiel

Compare Revisions

No changes between revisions

Ignore whitespace Rev 17 → Rev 18

/trunk/interfaces/controleurs/Test.php
New file
0,0 → 1,2254
<?php
// declare(encoding='UTF-8');
/**
* Classe Controleur du module Test.
*
* TODO : refactoriser l'ensemble des tests!
*
* @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();
$donnees['tests'] = 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->classerNomsParNumNom($noms);
$noms_homonymie = $this->classerNomsParNomComplet($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->testerNomSupraGeneriqueEspaces($noms);
$donnees['tests'][] = $this->testerNomSupraGeneriqueSyntaxe($noms);
$donnees['tests'][] = $this->testerNomSupraGeneriqueRang($noms);
$donnees['tests'][] = $this->testerGenreEspaces($noms);
$donnees['tests'][] = $this->testerGenreSyntaxe($noms);
$donnees['tests'][] = $this->testerGenreRang($noms);
$donnees['tests'][] = $this->testerEpitheteInfraGeneriqueEspaces($noms);
$donnees['tests'][] = $this->testerEpitheteInfraGeneriqueSyntaxe($noms);
$donnees['tests'][] = $this->testerEpitheteInfraGeneriqueRang($noms);
$donnees['tests'][] = $this->testerEpitheteSpEspaces($noms);
$donnees['tests'][] = $this->testerEpitheteSpSyntaxe($noms);
$donnees['tests'][] = $this->testerEpitheteSpRang($noms);
$donnees['tests'][] = $this->testerTypeEpitheteEspaces($noms);
$donnees['tests'][] = $this->testerTypeEpitheteSyntaxe($noms);
$donnees['tests'][] = $this->testerTypeEpitheteHybridite($noms);
$donnees['tests'][] = $this->testerEpitheteInfraSpEspaces($noms);
$donnees['tests'][] = $this->testerEpitheteInfraSpSyntaxe($noms);
$donnees['tests'][] = $this->testerEpitheteInfraSpRang($noms);
$donnees['tests'][] = $this->testerGroupeCultivarSyntaxe($noms);
$donnees['tests'][] = $this->testerGroupeCultivarRang($noms);
$donnees['tests'][] = $this->testerCultivarSyntaxe($noms);
$donnees['tests'][] = $this->testerCultivarRang($noms);
$donnees['tests'][] = $this->testerNomCommercialSyntaxe($noms);
$donnees['tests'][] = $this->testerNomCommercialPresenceCultivar($noms);
$donnees['tests'][] = $this->testerAuteurSyntaxe($noms);
$donnees['tests'][] = $this->testerAnneeSyntaxe($noms);
$donnees['tests'][] = $this->testerBiblioOrigineSyntaxe($noms);
$donnees['tests'][] = $this->testerHomonymieSyntaxe($noms);
$donnees['tests'][] = $this->testerHomonymieExistence($noms, $noms_homonymie);
$donnees['tests'][] = $this->testerBasionymeSyntaxe($noms);
$donnees['tests'][] = $this->testerBasionymeExistence($noms);
$donnees['tests'][] = $this->testerSynonymeProparteSyntaxe($noms);
$donnees['tests'][] = $this->testerSynonymeProparteExistence($noms);
$donnees['tests'][] = $this->testerSynonymeDouteuxSyntaxe($noms);
$donnees['tests'][] = $this->testerSynonymeMalAppliqueSyntaxe($noms);
$donnees['tests'][] = $this->testerSynonymeOrthographiqueSyntaxe($noms);
$donnees['tests'][] = $this->testerSynonymeOrthographiqueExistence($noms);
$donnees['tests'][] = $this->testerHybrideParent01Syntaxe($noms);
$donnees['tests'][] = $this->testerHybrideParent01Existence($noms);
$donnees['tests'][] = $this->testerHybrideParent02Syntaxe($noms);
$donnees['tests'][] = $this->testerHybrideParent02Existence($noms);
$donnees['tests'][] = $this->testerPresenceSyntaxe($noms);
$donnees['tests'][] = $this->testerStatutOrigineSyntaxe($noms);
$donnees['tests'][] = $this->testerStatutIntroductionSyntaxe($noms);
$donnees['tests'][] = $this->testerStatutCultureSyntaxe($noms);
*/
//Debug::printr($this->manuel);
$this->setSortie(self::RENDU_CORPS, $this->getVue('test', $donnees));
}
//+--------------------------------------------------------------------------------------------------------------+//
// TESTS
private function testerStatutCultureSyntaxe($noms) {
$info = array('titre' => 'statut_culture -> syntaxe',
'description' => "Le champ statut_culture peut contenir :\n".
" - le symbole tiret «-» une autre information non référencée...\n".
" - une première lettre en majuscule indiquant le code standard attribué à ce taxon.\n".
" - Cette première lettre peut être suivie d'un tiret puis d'une deuxième lettre en majuscule indiquant ".
"un code de présence spécifique au référentiel.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['statut_culture'] != '') {
if (!$this->verifierStatutCulture($nom['statut_culture'])) {
$noms_erreur[] = array($nom['num_nom'], $nom['statut_culture']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'statut_culture erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerStatutIntroductionSyntaxe($noms) {
$info = array('titre' => 'statut_introduction -> syntaxe',
'description' => "Le champ statut_introduction peut contenir :\n".
" - le symbole tiret «-» une autre information non référencée...\n".
" - une première lettre en majuscule indiquant le code standard attribué à ce taxon.\n".
" - Cette première lettre peut être suivie d'un tiret puis d'une deuxième lettre en majuscule indiquant ".
"un code de présence spécifique au référentiel.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['statut_introduction'] != '') {
if (!$this->verifierStatutIntroduction($nom['statut_introduction'])) {
$noms_erreur[] = array($nom['num_nom'], $nom['statut_introduction']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'statut_introduction erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerStatutOrigineSyntaxe($noms) {
$info = array('titre' => 'statut_origine -> syntaxe',
'description' => "Le champ statut_origine peut contenir :\n".
" - le symbole tiret «-» une autre information non référencée...\n".
" - une première lettre en majuscule indiquant le code standard attribué à ce taxon.\n".
" - Cette première lettre peut être suivie d'un tiret puis d'une deuxième lettre en majuscule indiquant ".
"un code de présence spécifique au référentiel.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['statut_origine'] != '') {
if (!$this->verifierStatutOrigine($nom['statut_origine'])) {
$noms_erreur[] = array($nom['num_nom'], $nom['statut_origine']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'statut_origine erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerPresenceSyntaxe($noms) {
$info = array('titre' => 'presence -> syntaxe',
'description' => "Le champ presence contient soit :\n".
" - le symbole tiret «-» une autre information non référencée...\n".
" - une première lettre en majuscule indiquant le code standard attribué à ce taxon.\n".
" - Cette première lettre peut être suivie d'un tiret puis d'une deuxième lettre en majuscule indiquant ".
"un code de présence spécifique au référentiel.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['presence'] != '') {
if (!$this->verifierPresence($nom['presence'])) {
$noms_erreur[] = array($nom['num_nom'], $nom['presence']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'presence erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerHybrideParent02Existence($noms) {
$info = array('titre' => 'hybride_parent_02 -> existence',
'description' => "Si le champ hybride_parent_02 contient un nombre alors il doit correspondre à une valeur du champ ".
"num_nom.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['hybride_parent_02'] != '') {
if (!isset($noms[$nom['hybride_parent_02']]) && $nom['hybride_parent_02'] != '0') {
$noms_erreur[] = array($nom['num_nom'], $nom['hybride_parent_02']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'hybride_parent_02 introuvable');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerHybrideParent02Syntaxe($noms) {
$info = array('titre' => 'hybride_parent_02 -> syntaxe',
'description' => "Le champ hybride_parent_02 contient soit :\n".
" - une valeur vide.\n".
" - un nombre",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['hybride_parent_02'] != '') {
if (!$this->verifierNombre($nom['hybride_parent_02'])) {
$noms_erreur[] = array($nom['num_nom'], $nom['hybride_parent_02']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'hybride_parent_02 erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerHybrideParent01Existence($noms) {
$info = array('titre' => 'hybride_parent_01 -> existence',
'description' => "Si le champ hybride_parent_01 contient un nombre alors il doit correspondre à une valeur du champ ".
"num_nom.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['hybride_parent_01'] != '' && $nom['hybride_parent_01'] != '0') {
if (!isset($noms[$nom['hybride_parent_01']])) {
$noms_erreur[] = array($nom['num_nom'], $nom['hybride_parent_01']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'hybride_parent_01 introuvable');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerHybrideParent01Syntaxe($noms) {
$info = array('titre' => 'hybride_parent_01 -> syntaxe',
'description' => "Le champ hybride_parent_01 contient soit :\n".
" - une valeur vide.\n".
" - un nombre",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['hybride_parent_01'] != '') {
if (!$this->verifierNombre($nom['hybride_parent_01'])) {
$noms_erreur[] = array($nom['num_nom'], $nom['hybride_parent_01']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'hybride_parent_01 erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerSynonymeOrthographiqueExistence($noms) {
$info = array('titre' => 'synonyme_orthographique -> existence',
'description' => "Si le champ synonyme_orthographique contient un nombre alors il doit correspondre à une valeur du champ ".
"num_nom.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['synonyme_orthographique'] != '') {
if (!isset($noms[$nom['synonyme_orthographique']])) {
$noms_erreur[] = array($nom['num_nom'], $nom['synonyme_orthographique']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'synonyme_orthographique introuvable');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerSynonymeOrthographiqueSyntaxe($noms) {
$info = array('titre' => 'synonyme_orthographique -> syntaxe',
'description' => "Le champ synonyme_orthographique contient soit :\n".
" - une valeur vide.\n".
" - un nombre",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['synonyme_orthographique'] != '') {
if (!$this->verifierNombre($nom['synonyme_orthographique'])) {
$noms_erreur[] = array($nom['num_nom'], $nom['synonyme_orthographique']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'synonyme_orthographique erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerSynonymeMalAppliqueSyntaxe($noms) {
$info = array('titre' => 'synonyme_mal_applique -> syntaxe',
'description' => "Le champ synonyme_mal_applique contient soit :\n".
" - une valeur vide.\n".
" - le chiffre 1",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['synonyme_mal_applique'] != '') {
if (!$this->verifierBooleen($nom['synonyme_mal_applique'])) {
$noms_erreur[] = array($nom['num_nom'], $nom['synonyme_mal_applique']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'synonyme_mal_applique erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerSynonymeDouteuxSyntaxe($noms) {
$info = array('titre' => 'synonyme_douteux -> syntaxe',
'description' => "Le champ synonyme_douteux contient soit :\n".
" - une valeur vide.\n".
" - le chiffre 1",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['synonyme_douteux'] != '') {
if (!$this->verifierBooleen($nom['synonyme_douteux'])) {
$noms_erreur[] = array($nom['num_nom'], $nom['synonyme_douteux']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'synonyme_douteux erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerSynonymeProparteExistence($noms) {
$info = array('titre' => 'synonyme_proparte -> existence',
'description' => "Si le champ synonyme_proparte contient un ou plusieurs nombres alors chacun d'entre eux ".
"doit correspondre à une valeur du champ num_nom.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['synonyme_proparte'] != '') {
$num_nom_a_verifier = explode(',', $nom['synonyme_proparte']);
$num_nom_en_erreur = array();
foreach ($num_nom_a_verifier as $num_nom) {
if (!isset($noms[$num_nom])) {
$num_nom_en_erreur[] = $num_nom;
}
}
if (count($nbre_en_erreur) > 0) {
$noms_erreur[] = array($nom['num_nom'], implode(',', $num_nom_en_erreur));
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'synonyme_proparte introuvable');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerSynonymeProparteSyntaxe($noms) {
$info = array('titre' => 'synonyme_proparte -> syntaxe',
'description' => "Le champ synonyme_proparte contient soit :\n".
" - une valeur vide.\n".
" - un nombre.\n".
" - une suite de nombre séparés par des virgules.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['synonyme_proparte'] != '') {
if (!$this->verifierNombreSuite($nom['synonyme_proparte'])) {
$noms_erreur[] = array($nom['num_nom'], $nom['synonyme_proparte']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'synonyme_proparte erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerBasionymeExistence($noms) {
$info = array('titre' => 'basionyme -> existence',
'description' => "Si le champ basionyme contient un nombre alors il doit correspondre à une valeur du champ ".
"num_nom.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['basionyme'] != '') {
if (!isset($noms[$nom['basionyme']])) {
$noms_erreur[] = array($nom['num_nom'], $nom['basionyme']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'basionyme introuvable');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerBasionymeSyntaxe($noms) {
$info = array('titre' => 'basionyme -> syntaxe',
'description' => "Le champ basionyme contient :\n".
" - un nombre ou une valeur vide.\n",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['basionyme'] != '') {
if (!$this->verifierNombre($nom['basionyme'])) {
$noms_erreur[] = array($nom['num_nom'], $nom['basionyme']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'basionyme erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerHomonymieExistence($noms, $noms_homonymie) {
$info = array('titre' => 'homonyme -> existence',
'description' => "Si le champ homonyme contient «1» alors plusieurs noms doivent posséder la même valeur ".
"dans le champ nom_complet.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['homonyme'] != '0' && $nom['homonyme'] != '') {
if ($noms_homonymie[$nom['nom_complet']] <= 1) {
$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'homonyme introuvable');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerHomonymieSyntaxe($noms) {
$info = array('titre' => 'homonyme -> syntaxe',
'description' => "Le champ homonyme contient :\n".
" - le chiffre 1 ou une valeur vide.\n",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['homonyme'] != '') {
if (!$this->verifierBooleen($nom['homonyme'])) {
$noms_erreur[] = array($nom['num_nom'], $nom['homonyme']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'homonyme erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerBiblioOrigineSyntaxe($noms) {
$info = array('titre' => 'biblio_origine -> syntaxe',
'description' => "Le champ biblio_origine se compose de plusieurs parties séparées par des caractères ".
"précis qui sont dans l'ordre de gauche à droite :\n".
" - Éventuellement le mot « in » suivi d'un intitulé auteur (utilisé pour indiquer l'intitulé auteur de ".
"l'ouvrage global dans lequel la publication est parue).\n".
" - point-virgule « ; » (si l'info précédent a été renseignée)\n".
" - Abréviation ou nom de l'ouvrage ou de la revue selon le standard en vigueur dans le code du nom. ".
"Cette information ne doit pas contenir de caractère virgule « , ».\n".
" - virgule « , »\n".
" - Les informations permettant d'identifier plus précisément le document contenant le nom... ".
"Par exemple, l'éditeur, le tome, le numéro d'édition, le volume... séparées par des virgules ou d'autres ".
"caractères sauf deux points « : ».\n".
" - deux points « : »\n".
" - la page contenant la publication du nom ou un ensemble de page (première et dernière page de ".
"l'ensemble séparées par un tiret « - »). Quelques fois des numéros ou d'autres informations indiquant ".
"dans le document la position du nom. Le tiret « - » doit toujours servir à séparer un ensemble.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['biblio_origine'] != '') {
if (!$this->verifierBiblioOrigine($nom['biblio_origine'])) {
$biblio_traite = $this->repererEspace($nom['biblio_origine']);
$noms_erreur[] = array($nom['num_nom'], $biblio_traite);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'biblio_origine erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerAnneeSyntaxe($noms) {
$info = array('titre' => 'annee -> syntaxe',
'description' => "Le champ annee doit :\n".
" - contenir un nombre de 4 chiffre\n".
" - être supérieur ou égal à 1753 ",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['annee'] != '') {
if (!$this->verifierAnnee($nom['annee'])) {
$noms_erreur[] = array($nom['num_nom'], $nom['annee']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'annee erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerAuteurSyntaxe($noms) {
$info = array('titre' => 'auteur -> syntaxe',
'description' => "Le champ auteur doit :\n".
" - contenir l'intitulé complet des noms de l'auteur ou des auteurs ayant publiés à l'origine la combinaison latine courante.\n".
" - ou débuter par le mot « sensu » et contient l'intitulé complet des noms de l'auteur ou des auteurs ayant publiés un nom dont la description ne correspond pas à celle de l'auteur ou des auteurs d'origine.\n".
" - se composer de caractères alphabétiques (A-Z, a-z), incluant les signes diacritiques, le symbole point (.), les paires de parenthèses ( () ), les apostrophes, l'esperluette (&) et l'espace ( ).\n".
" - contenir, si nécessaire, des abréviations de noms d'auteurs respectant les standards.\n".
" - contenir une translittération des noms d'alphabet cyrillique, arabe, chinois... en alphabet latin.\n".
" - inclure entre parenthèses l'intitulé des noms de l'auteur ou des auteurs ayant publié le basionyme.\n".
" - toujours utiliser l'esperluette (&) à la place du mot « et » pour séparer les noms d'auteurs.\n".
" - conformément à la recommandation 46C.2 du CINB, si une un citation comprend plus de deux auteurs, ".
"elle devrait être limitée au nom du premier, suivi de « & al.».\n",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['auteur'] != '') {
if (!$this->verifierAuteur($nom['auteur'])) {
$intitule_traite = $this->repererEspace($nom['auteur']);
$noms_erreur[] = array($nom['num_nom'], $intitule_traite);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'auteur erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerNomCommercialSyntaxe($noms) {
$info = array('titre' => 'nom_commercial -> syntaxe',
'description' => "Le champ nom_commercial doit contenir un nom commercial conforme aux règles du ".
"Code Internationnal de Nomenclature des Plantes Cultivées (CINPC) ".
"qui se compose de caractères majuscules (A-Z) incluant des signes diacritiques et des espaces.\n",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['nom_commercial'] != '') {
if (!$this->verifierNomCommercial($nom['nom_commercial'])) {
$epithete_traite = $this->repererEspace($nom['nom_commercial']);
$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'cultivar erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerNomCommercialPresenceCultivar($noms) {
$info = array('titre' => 'nom_commercial -> groupe_cultivar OU cultivar non vide',
'description' => "Si le champ nom_commercial contier un nom commercial alors le champ cultivar OU ".
"cultivar_groupe ne doit pas être vide.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['nom_commercial'] != '' && ($nom['cultivar'] == '' && $nom['cultivar_groupe'] == '')) {
$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet']);
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'nom_commercial sans cultivar ou cultivar_groupe');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerCultivarSyntaxe($noms) {
$info = array('titre' => 'cultivar -> syntaxe',
'description' => "Le champ cultivar_groupe doit contenir :\n".
" - un nom de cultivar conforme aux règles du Code Internationnal de Nomenclature des Plantes ".
"Cultivées (CINPC) qui se compose de caractères alphanumériques (A-Z,a-z et 0-9) incluant ".
"signes diacritiques et marques de ponctuations.\n".
" - un nom en alphabet latin ce qui implique une translittération des noms d'alphabet cyrillique, ".
"arabe, chinois...\n".
" - une lettre majuscule obligatoire pour le premier caractère du premier mot et pour les autres mots ".
"importants mais pas pour les mots mineurs.\n".
"Ne doit pas contenir :\n".
" - cv., convar. ou de guillemets simples (').\n",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['cultivar'] != '') {
if (!$this->verifierEpitheteCultivar($nom['cultivar'])) {
$epithete_traite = $this->repererEspace($nom['cultivar']);
$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'cultivar erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerCultivarRang($noms) {
$info = array('titre' => "cultivar -> rang >= {$this->manuel['rang_genre']}",
'description' => "Si le champ cultivar n'est pas vide alors le rang du nom doit être supérieur ou égal à {$this->manuel['rang_genre']}.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['cultivar'] != '') {
if ($nom['rang'] < $this->manuel['rang_genre']) {
$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerGroupeCultivarSyntaxe($noms) {
$info = array('titre' => 'cultivar_groupe -> syntaxe',
'description' => "Le champ cultivar_groupe doit contenir un nom de groupe de cultivar conforme aux règles ".
"du code des plantes cultivées qui se compose de caractères alphanumériques (A-Z,a-z et 0-9) incluant ".
"signes diacritiques et marques de ponctuations.\n".
"Il ne doit pas contenir le mot Groupe, l'abbréviation «gp» ou des parenthèses.\n".
"Il peut contir à la fin l'abréviation «gx» pour distinguer les groupes des grex.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['cultivar_groupe'] != '') {
if (!$this->verifierEpitheteGroupeCultivar($nom['cultivar_groupe'])) {
$epithete_traite = $this->repererEspace($nom['cultivar_groupe']);
$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'cultivar_groupe erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerGroupeCultivarRang($noms) {
$info = array('titre' => "cultivar_groupe -> rang >= {$this->manuel['rang_genre']}",
'description' => "Si le champ cultivar_groupe n'est pas vide alors le rang du nom doit être supérieur ou égal à {$this->manuel['rang_genre']}.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['cultivar_groupe'] != '') {
if ($nom['rang'] < $this->manuel['rang_genre']) {
$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerEpitheteInfraSpEspaces($noms) {
$info = array('titre' => 'epithete_infra_sp -> espaces en trop',
'description' => "Le champ epithete_infra_sp ne doit pas contenir d'espace avant ou aprés le nom.\n".
"Si des espaces sont compris dans la valeur du champ, il ne doit pas y avoir plusieurs espaces consécutifs.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['epithete_infra_sp'] != '') {
if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['epithete_infra_sp'])) {
$epithete_traite = $this->repererEspace($nom['epithete_infra_sp']);
$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'epithete_infra_sp erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerEpitheteInfraSpSyntaxe($noms) {
$info = array('titre' => 'epithete_infra_sp -> syntaxe',
'description' => "Le champ epithete_infra_sp peut contenir :\n".
" - un mot unique composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
" Il commence par une lettre minuscule (avec ou sans tréma).\n".
" Il peut être précédé par le signe + ou la lettre x suivi d'un espace.\n".
" - une formule d'hybridité composée d'une série de noms d'espèce ou d'infra espèce (au moins 2) séparés entre eux \n".
" par la lettre x entourée de caractères espaces.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['epithete_infra_sp'] != '') {
$mots = explode(' ', $nom['epithete_infra_sp']);
foreach ($mots as $mot) {
if (!(preg_match('/^[+x]$/', $mot) || $this->verifierTypeEpithete($mot)|| $this->verifierEpitheteSp($mot))) {
$epithete_traite = $this->repererEspace($nom['epithete_infra_sp']);
$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
}
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'epithete_infra_sp erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerEpitheteInfraSpRang($noms) {
$info = array('titre' => "epithete_infra_sp -> rang > {$this->manuel['rang_sp']}",
'description' => "Si le champ epithete_infra_sp n'est pas vide alors le rang du nom doit être supérieur à {$this->manuel['rang_sp']}.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['epithete_infra_sp'] != '') {
if ($nom['rang'] < $this->manuel['rang_sp']) {
$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerTypeEpitheteEspaces($noms) {
$info = array('titre' => 'type_epithete -> espaces en trop',
'description' => "Le champ type_epithete ne doit pas contenir d'espace.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['type_epithete'] != '') {
if (preg_match('/\s+/', $nom['type_epithete'])) {
$valeur_traitee = $this->repererEspace($nom['epithete_sp']);
$noms_erreur[] = array($nom['num_nom'], $valeur_traitee);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'type_epithete erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerTypeEpitheteSyntaxe($noms) {
$info = array('titre' => 'type_epithete -> syntaxe',
'description' => "Le champ type_epithete doit contenir un mot unique composé de lettres minuscules sans ".
" accents et de tirets (-). Il commence par une lettre minuscule sans accent.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['type_epithete'] != '') {
if (!$this->verifierTypeEpithete($nom['type_epithete'])) {
$noms_erreur[] = array($nom['num_nom'], $nom['type_epithete']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'type_epithete erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerTypeEpitheteHybridite($noms) {
$info = array('titre' => 'type_epithete -> hybridité',
'description' => "Le champ type_epithete ne doit pas contenir de préfixe indiquant l'hybridité comme : \n".
" - «n-» \n".
" - «notho-» \n",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['type_epithete'] != '') {
if (preg_match('/^(?:n-|notho-)/', $nom['type_epithete'])) {
$noms_erreur[] = array($nom['num_nom'], $nom['type_epithete']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'type_epithete erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
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 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 testerNomSupraGeneriqueSyntaxe($noms) {
$info = array('titre' => 'nom_supra_generique -> syntaxe',
'description' => "Le champ nom_supra_generique contient un mot composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
"La première lettre (avec ou sans tréma) du mot doit être en majuscule.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['nom_supra_generique'] != '') {
if (!preg_match('/^[A-ZÄËḦÏÖÜẄẌŸ][-a-zäëḧïöẗüẅẍÿ]+$/', $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 testerNomSupraGeneriqueRang($noms) {
$info = array('titre' => "nom_supra_generique -> rang < {$this->manuel['rang_genre']}",
'description' => "Si le champ nom_supra_generique n'est pas vide alors le rang du nom doit être inférieur à {$this->manuel['rang_genre']}.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['nom_supra_generique'] != '') {
if ($nom['rang'] >= $this->manuel['rang_genre']) {
$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerGenreEspaces($noms) {
$info = array('titre' => 'genre -> espaces en trop',
'description' => "Le champ genre ne doit pas contenir d'espace avant ou aprés le nom.\n".
"Si des espaces sont compris dans la valeur du champ, il ne doit pas y avoir plusieurs espaces consécutifs.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['genre'] != '') {
if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['genre'])) {
$nom_traite = $this->repererEspace($nom['genre']);
$noms_erreur[] = array($nom['num_nom'], $nom_traite);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'genre erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerGenreSyntaxe($noms) {
$info = array('titre' => 'genre -> syntaxe',
'description' => "Le champ genre peut contenir :\n".
" - un mot unique composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
" Il commence par une lettre majuscule (avec ou sans tréma).".
" Il peut être précédé par le signe + ou la lettre x suivi d'un espace.\n".
" - une formule d'hybridité composée d'une série de noms de genre (au moins 2) séparés entre eux \n".
" par la lettre x entourée de caractères espaces.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['genre'] != '') {
$mots = explode(' ', $nom['genre']);
foreach ($mots as $mot) {
if (!(preg_match('/^[+x]$/', $mot) || $this->verifierEpitheteGenre($mot))) {
$nom_traite = $this->repererEspace($nom['genre']);
$noms_erreur[] = array($nom['num_nom'], $nom_traite);
}
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'genre erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerGenreRang($noms) {
$info = array('titre' => "genre -> rang >= {$this->manuel['rang_genre']}",
'description' => "Si le champ genre n'est pas vide alors le rang du nom doit être supérieur ou égal à {$this->manuel['rang_genre']}.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['genre'] != '') {
if ($nom['rang'] < $this->manuel['rang_genre']) {
$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerEpitheteInfraGeneriqueSyntaxe($noms) {
$info = array('titre' => 'epithete_infra_generique -> syntaxe',
'description' => "Le champ epithete_infra_generique est composé de lettres minuscules avec ou sans tréma (¨) et de tirets (-). \n".
"La première lettre (avec ou sans tréma) doit être en majuscule.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['epithete_infra_generique'] != '') {
if (!preg_match('/^[A-ZÄËḦÏÖÜẄẌŸ][-a-zäëḧïöẗüẅẍÿ]+/', $nom['epithete_infra_generique'])) {
$epithete_traite = $this->repererEspace($nom['epithete_infra_generique']);
$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'epithete_infra_generique erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerEpitheteInfraGeneriqueRang($noms) {
$info = array('titre' => "epithete_infra_generique -> {$this->manuel['rang_genre']} < rang < {$this->manuel['rang_sp']}",
'description' => "Si le champ epithete_infra_generique n'est pas vide alors le rang du nom doit être compris \n".
"entre {$this->manuel['rang_genre']} et {$this->manuel['rang_sp']}.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['epithete_infra_generique'] != '') {
if ($nom['rang'] <= $this->manuel['rang_genre'] || $nom['rang'] >= $this->manuel['rang_sp']) {
$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerEpitheteInfraGeneriqueEspaces($noms) {
$info = array('titre' => 'epithete_infra_generique -> espaces en trop',
'description' => "Le champ epithete_infra_generique ne doit pas contenir d'espace avant ou aprés sa valeur.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['epithete_infra_generique'] != '') {
if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['epithete_infra_generique'])) {
$epithete_traite = $this->repererEspace($nom['epithete_infra_generique']);
$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'epithete_infra_generique erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerEpitheteSpEspaces($noms) {
$info = array('titre' => 'epithete_sp -> espaces en trop',
'description' => "Le champ epithete_sp ne doit pas contenir d'espace avant ou aprés le nom.\n".
"Si des espaces sont compris dans la valeur du champ, il ne doit pas y avoir plusieurs espaces consécutifs.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['epithete_sp'] != '') {
if (preg_match('/(?:^\s+(?!:\s+)|(?!:\s+)\s{2,}(?!:\s+)|(?!:\s+)\s+$)/', $nom['epithete_sp'])) {
$epithete_traite = $this->repererEspace($nom['epithete_sp']);
$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'epithete_sp erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerEpitheteSpSyntaxe($noms) {
$info = array('titre' => 'epithete_sp -> syntaxe',
'description' => "Le champ epithete_sp peut contenir :\n".
" - un mot unique composé de lettres minuscules [a-z] incluant les caractères [ëï-]. \n".
" Il commence par une lettre minuscule [a-zëï].\n".
" Il peut être précédé par le signe + ou la lettre x suivi d'un espace.\n".
" - un mot contenant sp. suivi d'un ou plusieurs caractères numériques (1-9) ou d'un seul caractère majuscule (A-Z) \n".
" - une formule d'hybridité composée d'une série de noms d'espèce (au moins 2) séparés entre eux \n".
" par la lettre x entourée de caractères espaces.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['epithete_sp'] != '') {
$mots = explode(' ', $nom['epithete_sp']);
foreach ($mots as $mot) {
if (!(preg_match('/^[+x]$/', $mot) || $this->verifierEpitheteSp($mot))) {
$epithete_traite = $this->repererEspace($nom['epithete_sp']);
$noms_erreur[] = array($nom['num_nom'], $epithete_traite);
}
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'epithete_sp erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
private function testerEpitheteSpRang($noms) {
$info = array('titre' => "epithete_sp -> rang >= {$this->manuel['rang_sp']}",
'description' => "Si le champ epithete_sp n'est pas vide alors le rang du nom doit être supérieur ou égal à {$this->manuel['rang_sp']}.",
'resultat' => false);
// Réalisation du test
$noms_erreur = array();
foreach ($noms as $nom) {
if ($nom['epithete_sp'] != '') {
if ($nom['rang'] < $this->manuel['rang_sp']) {
$noms_erreur[] = array($nom['num_nom'], $nom['nom_complet'], $nom['rang']);
}
}
}
// Analyse des résultats
if (count($noms_erreur) > 0) {
$info['message']['entete'] = array('num_nom', 'nom_complet', 'rang erroné');
$info['message']['lignes'] = $noms_erreur;
} else {
$info['resultat'] = true;
}
return $info;
}
//+--------------------------------------------------------------------------------------------------------------+//
// MÉTHODES COMMUNES aux TESTS
private function verifierPresence($valeur) {
$codes = $this->manuel['codes_presence'];
$ok = $this->verifierStatuts($valeur, $codes);
return $ok;
}
private function verifierStatutOrigine($valeur) {
$codes = $this->manuel['codes_statuts_origine'];
$ok = $this->verifierStatuts($valeur, $codes);
return $ok;
}
private function verifierStatutIntroduction($valeur) {
$codes = $this->manuel['codes_statuts_introduction'];
$ok = $this->verifierStatuts($valeur, $codes);
return $ok;
}
private function verifierStatutCulture($valeur) {
$codes = $this->manuel['codes_statuts_culture'];
$ok = $this->verifierStatuts($valeur, $codes);
return $ok;
}
private function verifierStatuts($valeur, $codes) {
$ok = true;
if (!preg_match("/^(?:|-|[$codes](?:-[A-Z])?)$/", $valeur)) {
$ok = false;
}
return $ok;
}
private function verifierBooleen($valeur) {
$ok = true;
if (!preg_match('/^1$/', $valeur)) {
$ok = false;
}
return $ok;
}
private function verifierNombre($valeur) {
$ok = true;
if (!preg_match('/^[0-9]+$/', $valeur)) {
$ok = false;
}
return $ok;
}
private function verifierNombreSuite($valeur) {
$ok = true;
if (!preg_match('/^(?:[0-9]+,)*[0-9]+$/', $valeur)) {
$ok = false;
}
return $ok;
}
private function verifierTypeEpithete($type) {
$ok = false;
$rejetes = $this->manuel['type_epithete_rejetes'];
if (preg_replace("/^(?:$rejetes)$/", '', $type) == '') {
$ok = false;
} else if (preg_match('/^[a-z][-a-z]*[.]?$/', $type)) {
$ok = true;
}
return $ok;
}
private function verifierBiblioOrigine($intitule) {
$ok = true;
if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $intitule)) {
$ok = false;// Contient des espaces en trop
} else if (!preg_match('/^(?:in [^;]+[;]|)[^,]+?(?:[,][^:]+|)(?:[:].+|)$/', $intitule)) {
$ok = false;
} else if (preg_match('/(?:(?:^|[,:])\s*(?:[:,]|$))/', $intitule)) {
$ok = false;// Contient une mauvaise suite de caractères
}
return $ok;
}
private function verifierAnnee($annee) {
$ok = true;
if (!preg_match('/^[0-9]{4}$/', $annee)) {
$ok = false;
} else if ($annee < 1753) {
$ok = false;
}
return $ok;
}
private function verifierAuteur($intitule) {
$ok = true;
$acceptes = $this->manuel['auteur_acceptes'];
if (!preg_match("/^(?:$acceptes)$/", $intitule)) {
if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $intitule)) {
$ok = false;// Contient des espaces en trop
} else {
$mots_rejetes = $this->manuel['auteur_mots_rejetes'];
$mots = explode(' ', $intitule);
foreach ($mots as $position => $mot) {
if (preg_match("/^(?:$mots_rejetes)$/i", $mot)) {
$ok = false;// Mot rejeté
} else if (preg_match("/^(?:(?:\p{L}|[.'\(\)-])+|[&])$/u", $mot)) {
continue;// Mot de l'intitulé auteur
} else {
$ok = false;
}
}
}
}
return $ok;
}
private function verifierNomCommercial($epithete) {
$ok = false;
if (preg_match("/^[[:upper:][:punct:][:digit:][:space:]]+$/", $epithete)) {
$ok = true;
}
return $ok;
}
private function verifierEpitheteCultivar($epithete) {
$ok = true;
$acceptes = $this->manuel['cultivar_acceptes'];
if (!preg_match("/^(?:$acceptes)$/", $epithete)) {
if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $epithete)) {
$ok = false;// Contient des espaces en trop
} else {
$mots_rejetes = $this->manuel['cultivar_mots_rejetes'];
$mots_mineurs = $this->manuel['mots_mineurs'];
$mots = explode(' ', $epithete);
foreach ($mots as $position => $mot) {
if (preg_match("/^(?:$mots_rejetes)$/i", $mot)) {
$ok = false;// Mot rejeté
} else if ($position > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot)) {
continue;// Mot mineur en minuscule qui n'est pas en 1ère position
} else {
$mots_tiret = explode('-', $mot);
foreach ($mots_tiret as $position_tiret => $mot_tiret) {
if ($position_tiret > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot_tiret)) {
continue;// Mot-tiret mineur en minuscule qui n'est pas en 1ère position
} else if (preg_match('/^[[:upper:]][[:lower:]]+$/', $mot_tiret)) {
continue;//Mot (ou 'mot-tiret') avec lettre initiale majuscule
} else if ($position_tiret == count($mots_tiret) && preg_match('/^[:upper:][:lower:]+[:punct:]?$/', $mot_tiret)) {
continue;//Dernier mot (ou 'mot-tiret') avec lettre initiale majuscule, suivi d'un éventuel signe de ponctuation
} else {
$ok = false;
}
}
}
}
}
}
return $ok;
}
private function verifierEpitheteGroupeCultivar($epithete) {
$ok = true;
$acceptes = $this->manuel['cultivar_gp_acceptes'];
if (!preg_match("/^(?:$acceptes)$/", $epithete)) {
if (preg_match('/(?:^\s+|\s{2,}|\s+$)/', $epithete)) {
$ok = false;// Contient des espaces en trop
} else {
$mots_acceptes = $this->manuel['cultivar_gp_mots_acceptes'];
$mots_rejetes = $this->manuel['cultivar_gp_mots_rejetes'];
$mots_mineurs = $this->manuel['mots_mineurs'];
$mots = explode(' ', $epithete);
foreach ($mots as $position => $mot) {
if (preg_match("/^(?:$mots_acceptes)$/i", $mot)) {
continue;// Mot accepté
} else if (preg_match("/^(?:$mots_rejetes)$/i", $mot)) {
$ok = false;// Mot rejeté
} else if ($position > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot)) {
continue;// Mot mineur en minuscule qui n'est pas en 1ère position
} else {
$mots_tiret = explode('-', $mot);
foreach ($mots_tiret as $position_tiret => $mot_tiret) {
if ($position_tiret > 0 && preg_match("/^(?:$mots_mineurs)$/", $mot_tiret)) {
continue;// Mot-tiret mineur en minuscule qui n'est pas en 1ère position dans le mot
} else if (preg_match('/^[[:upper:]][[:lower:]]+$/', $mot_tiret)) {
continue;// Mot (ou 'mot-tiret') avec lettre initiale majuscule
} else if ($position_tiret == count($mots_tiret) && preg_match('/^[:upper:][:lower:]+[:punct:]?$/', $mot_tiret)) {
continue;// Dernier mot (ou 'mot-tiret') avec lettre initiale majuscule, suivi d'un éventuel signe de ponctuation
} else {
$ok = false;
}
}
}
}
}
}
return $ok;
}
private function verifierEpitheteSp($epithete) {
$ok = false;
if (preg_match('/^[a-zëï][-a-zëï]+$/', $epithete)) {
$ok = true;
} else if (preg_match('/^sp\.(?:[A-Z]|[1-9][0-9]*)$/', $epithete)) {
$ok = true;
}
return $ok;
}
private function verifierEpitheteGenre($epithete) {
$ok = false;
if (preg_match('/^[A-ZËÏ](?:[-a-zëï]+|[a-zëï]+-[A-ZËÏ][a-zëï]+)$/', $epithete)) {
$ok = true;
}
return $ok;
}
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;
}
private function classerNomsParNumNom($noms) {
$noms_classes = array();
foreach ($noms as $nom) {
$noms_classes[$nom['num_nom']] = $nom;
}
return $noms_classes;
}
private function classerNomsParNomComplet($noms) {
$noms_classes = array();
foreach ($noms as $nom) {
if (!isset($noms_classes[$nom['nom_complet']])) {
$noms_classes[$nom['nom_complet']] = 1;
} else {
$noms_classes[$nom['nom_complet']]++;
}
}
return $noms_classes;
}
}
?>
/trunk/interfaces/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/interfaces/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/interfaces/framework.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/framework/autoload.inc.php';
?>
/trunk/interfaces/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/interfaces/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/interfaces/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;
}
}
?>
/trunk/interfaces/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/interfaces/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/interfaces/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/interfaces/configurations/config.default.ini
New file
0,0 → 1,48
; +------------------------------------------------------------------------------------------------------+
; Général
; Séparateur de dossier
ds = DIRECTORY_SEPARATOR
 
; +------------------------------------------------------------------------------------------------------+
; Info sur l'application
info.nom = Gestion des référentiels
; 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/"
; Nom du fichier contenant les infos sur la version courante du manuel technique
manuel = "referentiel_v2.1.ini"
 
; +------------------------------------------------------------------------------------------------------+
; 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/interfaces/configurations/referentiel_v2.1.ini
New file
0,0 → 1,76
; Version du référentiel servant de base aux informations ci-dessous
version = 2.1
; Noms des champs
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"
; Noms et types des champs
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"
; Valeurs numériques des rangs
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"
; Valeur numérique indiquant le rang du genre
rang_genre="220"
; Valeur numérique indiquant le rang de l'espèce
rang_sp="290"
 
; TOUTES LES LISTES séparées par | sontinsérées dans la regexp suivante : /^(?:$liste)$/ VOUS DEVEZ SI NÉCESSAIRE
; ANTISLASHER LES CARACTÈRES : . \ + * ? [ ^ ] $ ( ) { } = ! < > : -
; Liste de types d'épithète à rejeter. Séparation : ,. Insenssible à la casse.
type_epithete_rejetes="cv[.]?|convar[.]?"
; Liste de mots de noms de cultivar qui doivent être rejetés. Séparation : |. Inssensible à la casse.
cultivar_mots_rejetes="cv[.]?|convar[.]?"
; Liste de noms de cultivar acceptés faisant exception à la règle de la majuscule pour la 1ère lettre de chaque mot. Séparation : |. Senssible à la casse.
cultivar_acceptes="s-Hertogenbosch|IJsselham"
; Liste de mots de noms de groupe de cultivar qui doivent être rejetés. Séparation : |. Inssensible à la casse.
cultivar_gp_mots_rejetes="gp|grex|group|gruppe|groupe|grupo|gruppen"
; Liste de mots de noms de groupe de cultivar à accepter. Séparation : |. Senssible à la casse.
cultivar_gp_mots_acceptes="gx"
; Liste de noms de groupe de cultivar à accepter. Séparation : |. Senssible à la casse.
cultivar_gp_acceptes=""
;Liste des mots mineurs (conjonctions et prépositions). Séparation : |. Sensible à la casse.
mots_mineurs = "mais|ou|et|donc|or|ni|car|and|but|or|nor|de|à|pour|en|dans|avec|sur|par|sans|of|to|in|for|with|on"
; Liste des intitulés auteur faisant exception aux règles mais acceptés. Séparation : |
auteur_acceptes=""
; Liste des mots composant un intitulés auteur qui sont rejetés. Séparation : |
auteur_mots_rejetes="et|and|[(]?(?:p\.){2}[)]?"
 
; Liste des codes de présence
codes_presence = "PSDECA"
; Liste des statuts d'origine
codes_statuts_origine = "NSDECAX"
; Liste des statuts d'introduction
codes_statuts_introduction = "ISDECAX"
; Liste des statuts de culture
codes_statuts_culture = "CISDECX"
/trunk/interfaces/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/interfaces/configurations
New file
Property changes:
Added: svn:ignore
+config.ini
/trunk/interfaces/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/interfaces/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/interfaces/.htaccess
New file
0,0 → 1,2
#AddHandler x-httpd-php5 .php
#AddDefaultCharset UTF-8
/trunk/interfaces/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/interfaces/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/interfaces/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/interfaces/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/interfaces/bibliotheque/pear/Pager/Pager_savebc.php
New file
0,0 → 1,3
<?php
require_once 'Pager.php';
?>
/trunk/interfaces/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/interfaces/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/interfaces/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/interfaces/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/interfaces/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/interfaces/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/interfaces/squelettes/css/referentiel/images/ouvrir.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/trunk/interfaces/squelettes/css/referentiel/images/ouvrir.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/trunk/interfaces/squelettes/css/referentiel/images/fermer.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/trunk/interfaces/squelettes/css/referentiel/images/fermer.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/trunk/interfaces/squelettes/js/jquery-1.4.2.min.js
New file
0,0 → 1,154
/*!
* jQuery JavaScript Library v1.4.2
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Sat Feb 13 22:33:48 2010 -0500
*/
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
/trunk/interfaces/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>
<p>Cliquer sur les titres des tests pour affichers les détails.</p>
<?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 -->