/branches/v1.0-adhemar/framework/Controleur.php |
---|
New file |
0,0 → 1,142 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Classe Controleur, coeur d'une application, c'est normalement la seule classe d'une application |
* qui devrait être appelée de l'extérieur. |
* Elle est abstraite donc doit obligatoirement être étendue. |
* |
* @category php5 |
* @package Framework |
* @author Aurélien PERONNET <aurelien@tela-botanica.org> |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright 2009 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$$ |
* @link /doc/framework/ |
* |
*/ |
abstract class Controleur { |
/** |
* Registre global, normalement accessible partout |
*/ |
private $registre; |
/** |
* Constructeur par défaut |
*/ |
public function __construct() { |
if (Config::existe('fw_html_errors')) { |
ini_set('html_errors', Config::get('fw_html_errors')); |
} |
$this->registre = Registre::getInstance(); |
$this->registre->set('base_chemin_modele', Config::get('chemin_modeles')); |
$this->registre->set('base_chemin_squelette', Config::get('chemin_squelettes')); |
$this->registre->set('base_chemin_controleur', Config::get('chemin_controleurs')); |
$this->registre->set('base_url_application', new Url(Config::get('url_base'))); |
$this->verifierEtReencoderTableauRequete(); |
} |
/** |
* Charge un modele donné et le rend disponible sous la forme $this->nom_modele |
* |
* @param string $nom_modele le nom du modèle à charger |
* |
* @return boolean false si le chargement a échoué, sinon true. |
*/ |
final protected function chargerModele($nom_modele) { |
$sortie = true; |
$modele = $this->getModele($nom_modele); |
if ($modele !== false) { |
$this->$nom_modele = new $nom_modele; |
} else { |
$sortie = false; |
} |
return $sortie; |
} |
/** |
* Retourne un modele donné |
* |
* @param string $nom_modele le nom du modèle à charger |
* |
* @return mixed false si le chargement a échoué, sinon l'objet du modèle demandé. |
*/ |
final protected function getModele($nom_modele) { |
$sortie = false; |
$chemin_modele = $this->registre->get('base_chemin_modele').$nom_modele.'.php'; |
if (file_exists($chemin_modele)) { |
include_once $chemin_modele; |
if (class_exists($nom_modele)) { |
$sortie = new $nom_modele; |
} |
} |
return $sortie; |
} |
/** |
* Fonction prenant en paramètre le nom d'un squelette et un tableau associatif de données, |
* en extrait les variables, charge le squelette et retourne le résultat des deux combinés. |
* |
* @param String $nom_squelette le nom du squelette |
* @param Array $donnees un tableau associatif contenant les variables a injecter dans la vue |
* |
* @return boolean false si la vue n'existe pas, sinon la chaine résultat. |
*/ |
final protected function getVue($nom_squelette, $donnees = array()) { |
$donnees = $this->preTraiterDonnees($donnees); |
$chemin_squelette = ($this->registre->get('base_chemin_squelette')).$nom_squelette.'.tpl.html'; |
$sortie = SquelettePhp::analyser($chemin_squelette, $donnees); |
return $sortie; |
} |
/** |
* Fonction prenant en paramètre un tableau de données et effectuant un traitement dessus. |
* Cette fonction est à surcharger dans les classes filles pour automatiser un traitement |
* avant chaque chargement de vue. |
* |
* @param Array $donnees Le tableau de données à traiter |
* |
* @return Array $donnees Le tableau de données traité |
*/ |
protected function preTraiterDonnees($donnees) { |
return $donnees; |
} |
/** |
* Procédure vérifiant l'encodage des tableaux $_GET et $_POST et les transcodant dans l'encodage de l'application |
*/ |
protected function verifierEtReencoderTableauRequete() { |
if (Config::get('sortie_encodage') != Config::get('appli_encodage')) { |
$_POST = $this->encoderTableau($_POST, Config::get('appli_encodage'), Config::get('sortie_encodage')); |
$_GET = $this->encoderTableau($_GET, Config::get('appli_encodage'), Config::get('sortie_encodage')); |
} |
} |
/** |
* Fonction récursive transcodant toutes les valeurs d'un tableau de leur encodage d'entrée vers un encodage de sortie donné |
* @param $tableau Array Un tableau de données à encoder |
* @param $encodage_sortie String l'encodage vers lequel on doit transcoder |
* @param $encodage_entree String l'encodage original des chaines du tableau (optionnel) |
* @return Array Le tableau encodé dans l'encodage de sortie |
* |
*/ |
final protected function encoderTableau($tableau, $encodage_sortie, $encodage_entree = null) { |
if (is_array($tableau)) { |
foreach ($tableau as $cle => $valeur) { |
if (is_array($valeur)) { |
$tableau[$cle] = $this->encoderTableau($tableau[$cle], $encodage_sortie, $encodage_entree); |
} else { |
$tableau[$cle] = mb_convert_encoding($valeur, $encodage_sortie, $encodage_entree); |
} |
} |
} |
return $tableau; |
} |
} |
?> |
Property changes: |
Added: svn:keywords |
+Id Author Date Revision HeadURL |
\ No newline at end of property |
/branches/v1.0-adhemar/framework/autoload.inc.php |
---|
New file |
0,0 → 1,67 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Fichier contenant la fonction de chargement automatique de classes, il doit toujours rester à la racine |
* du framework car il initialise le chemin de l'application en se basant sur son propre emplacement. |
* |
* PHP Version 5.1.2 |
* |
* @category Fichier_De_Fonctions |
* @package Framework |
// Auteur principal : |
* @author Aurelien PERONNET <aurelien@tela-botanica.org> |
// Autres auteurs : |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $$Id$$ |
* @copyright 1999-2009 Tela Botanica (accueil@tela-botanica.org) |
*/ |
// Redéfinition de la constante DIRECTORY_SEPARATOR |
if (!defined('DS')) { |
define('DS', DIRECTORY_SEPARATOR); |
} |
// Redéfinition de la constante PATH_SEPARATOR |
if (!defined('PS')) { |
define('PS', PATH_SEPARATOR); |
} |
// Autoload pour le Framework |
function autoloadFw($nom_classe_fw) { |
$fichier_a_inclure = dirname(__FILE__).DS.$nom_classe_fw.'.php'; |
if (file_exists($fichier_a_inclure)) { |
include_once $fichier_a_inclure; |
return null; |
} |
} |
spl_autoload_register('autoloadFw'); |
// Instanciation du gestionnaire d'exception |
GestionnaireException::getInstance(); |
// Instanciation du gestionnaire de logs |
Log::getInstance(); |
// Encodage de l'application (défini ici car on peut avoir des sorties d'erreurs dès le début) |
mb_internal_encoding(Config::get('appli_encodage')); |
// Autoload par défaut pour l'application |
function autoloadAppliDefaut($nom_classe) { |
$dossiers_classes = array( Config::get('chemin_controleurs'), |
Config::get('chemin_modeles'), |
Config::get('chemin_bibliotheque')); |
foreach ($dossiers_classes as $chemin) { |
$fichier_a_tester = $chemin.$nom_classe.'.php'; |
if (file_exists($fichier_a_tester)) { |
include_once $fichier_a_tester; |
return null; |
} |
} |
} |
spl_autoload_register('autoloadAppliDefaut'); |
// Autoload défini par l'application |
if (function_exists('__autoload')) { |
spl_autoload_register('__autoload'); |
} |
?> |
Property changes: |
Added: svn:keywords |
+Id Author Date Revision HeadURL |
\ No newline at end of property |
/branches/v1.0-adhemar/framework/Log.php |
---|
New file |
0,0 → 1,192 |
<?php |
//declare(encoding='UTF-8'); |
/** |
* Classe permettant de logger des messages dans les fichier situés dans le dossier de log |
* |
* PHP Version 5 |
* |
* @category PHP |
* @package Framework |
* @author aurelien <aurelien@tela-botanica.org> |
* @copyright 2009 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/framework/ |
*/ |
class Log { |
/** |
* Boolean indiquant si l'on doit utiliser les logs ou pas |
*/ |
private static $logger = false; |
/** |
* Tableau associatif stockant les descripteurs de fichiers |
*/ |
private static $fichiersLog = array(); |
/** |
* Chemin de base du dossier log de l'application |
*/ |
private static $cheminLogs = ''; |
/** |
* Booleen indiquant si l'on peut correctement écrire dans les fichiers de logs |
*/ |
private static $droitLogger = true; |
/** |
* Zone horaire (pour éviter des avertissements dans les dates) |
*/ |
private static $timeZone = ''; |
/** |
* Taille maximum d'un fichier de log avant que celui ne soit archivé (en octets) |
*/ |
private static $tailleMax = 10000; |
/** |
* séparateur de chemin |
*/ |
private static $sd = DIRECTORY_SEPARATOR; |
/** |
* Extension des fichiers de log |
*/ |
private static $ext = '.log'; |
/** |
* La classe registre se contient elle-même, (pour le pattern singleton) |
*/ |
private static $log; |
/** |
* Constructeur par défaut, privé, car on accède à la classe par le getInstance |
*/ |
private function __construct() { |
self::$sd = Config::get('ds'); |
self::$cheminLogs = Config::get('chemin_logs'); |
self::$timeZone = Config::get('fw_timezone'); |
self::$tailleMax = Config::get('fw_taille_max_logs'); |
self::$logger = Config::get('fw_log_debogage'); |
// gestion de la timezone pour éviter des erreurs |
if (function_exists('date_default_timezone_set') && function_exists('date_default_timezone_get')) { |
date_default_timezone_set(self::$timeZone); |
} |
if (self::$logger && (!is_dir(self::$cheminLogs) || !is_writable(self::$cheminLogs))) { |
self::desactiverEcriture(); |
} |
} |
/** |
* Fonction qui renvoie l'instance de classe en assurant son unicité, c'est l'unique méthode qui doit être |
* utilisée pour récupérer l'objet Registre |
* @return Log le gestionnaire de log en cours |
*/ |
public static function getInstance() { |
if (self::$log instanceof Log) { |
return self::$log; |
} |
self::$log = new Log(); |
return self::$log; |
} |
/** |
* Ajoute une entrée au log spécifié par le paramètre $nomFichier |
* @param string $nomFichier le nom du fichier dans lequel écrire |
*/ |
public static function ajouterEntree($nomFichier,$entree,$mode='a+') { |
if(self::$droitLogger) { |
$date = "\n"."\n".date('d m Y H:i')."\n" ; |
// si le fichier est déjà dans le tableau et qu'on peut y écrire |
if(self::verifierOuvrirFichier($nomFichier,$mode)) { |
// on y écrit le message de log |
fwrite(self::$fichiersLog[$nomFichier],$date.$entree); |
// on vérifie si le fichier ne dépasse pas la taille maximale |
self::verifierTailleFichierOuArchiver($nomFichier); |
} else { |
// sinon on interdit l'écriture |
self::desactiverEcriture($nomFichier); |
} |
} |
} |
/** |
* Vide un fichier log indiqué |
* @param string $nomFichier le nom du fichier à vider |
*/ |
public static function viderLog($nomFichier) { |
self::ajouterEntree($nomFichier, '', 'w'); |
} |
/** |
* Vérifie la présence d'un fichier dans le tableau, ses droits d'écriture, |
* l'ouvre si nécessaire |
* @param string $nomFichier le nom du fichier dont on doit vérifier la présence |
* @return boolean true si le fichier est ouvert ou maintenant accessible, false sinon |
*/ |
public static function verifierOuvrirFichier($nomFichier,$mode) { |
// le fichier est il déjà ouvert ? |
if (in_array($nomFichier, self::$fichiersLog)) { |
// si oui peut on y écrire ? |
if (is_writable(self::$cheminLogs.$nomFichier.self::$ext)) { |
// si oui on renvoie le descripteur |
return true; |
} |
return false; |
} else { |
// sinon on l'ouvre |
$fp = @fopen(self::$cheminLogs.$nomFichier.self::$ext,$mode); |
// si l'ouverture a réussi et si le fichier a les droits d'écriture |
if ($fp && is_writable(self::$cheminLogs.$nomFichier.self::$ext)) { |
// si oui on renvoie le descripteur qu'on ajoute au tableau |
self::$fichiersLog[$nomFichier] = $fp; |
return true; |
} |
return false; |
} |
} |
/** |
* Vérifie la taille d'un fichier donné et si celle ci est trop importante |
* archive le fichier de log |
* @param string $nomFichier nom du fichier à vérifier |
*/ |
private static function verifierTailleFichierOuArchiver($nomFichier) { |
if(filesize(self::$cheminLogs.$nomFichier.self::$ext) > self::$tailleMax) { |
rename(self::$cheminLogs.$nomFichier.self::$ext,self::$cheminLogs.$nomFichier.date('d_m_Y_H:i').self::$ext); |
self::ajouterEntree($nomFichier,''); |
} |
} |
/** |
* Désactive l'écriture du log et envoie un message au gestionnaire d'erreurs |
* @param string $nomFichier le nom du fichier qui a causé l'erreur |
*/ |
private static function desactiverEcriture($nomFichier = '') { |
self::$droitLogger = false; |
if ($nomFichier != '') { |
$fichierDossier = 'fichier '.$nomFichier ; |
} else { |
$fichierDossier = 'dossier des logs'; |
} |
$message = 'Écriture impossible dans le '.$fichierDossier.', Assurez-vous des droits du dossier et des fichiers'; |
$e = new ErrorException($message, 0, E_USER_WARNING, __FILE__, __LINE__); |
GestionnaireException::gererException($e); |
} |
/** |
* destructeur de classe, ferme les descripteurs ouverts |
*/ |
public function __destruct() { |
foreach(self::$fichiersLog as $nomFichier => $fp) { |
fclose($fp); |
} |
} |
} |
?> |
Property changes: |
Added: svn:keywords |
+Id Author Date Revision HeadURL |
\ No newline at end of property |
/branches/v1.0-adhemar/framework/Url.php |
---|
New file |
0,0 → 1,772 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* classe Url, gérant le découpage des paramètres, leurs modification etc... |
* Traduction et conversion d'une classe (NET_Url2) issue de Pear |
* |
* @category Php5 |
* @package Framework |
// Auteur principal |
* @author Christian Schmidt <schmidt@php.net> |
// Autre auteurs |
* @author Aurélien PERONNET <aurelien@tela-botanica.org> |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright 2009 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$ |
* @link /doc/framework/ |
* |
*/ |
class Url |
{ |
/** |
* Parsing strict dans resoudre() (voir RFC 3986, section 5.2.2). Par défaut |
* à true. |
*/ |
const OPTION_STRICTE = 'strict'; |
/** |
* Répresenter les tableaux dans les requêtes en utilisant la notation php []. Par défaut à true. |
*/ |
const OPTION_UTILISER_CROCHETS = 'use_brackets'; |
/** |
* URL-encoder les clés des variables dans les requêtes. Par défaut à true. |
*/ |
const OPTION_ENCODER_CLES = 'encode_keys'; |
/** |
* Séparateurs de variables lors du parsing de la requête. Chaque caractère |
* est considéré comme un séparateur. Par défaut, spécifié par le paramêtre |
* arg_separator.input dans php.ini (par défaut "&"). |
*/ |
const OPTION_SEPARATEUR_ENTREE = 'input_separator'; |
/** |
* Séparateur de variables lors de la génération de la requête. Par défaut, spécifié |
* par le paramètre arg_separator.output dans php.ini (par défaut "&"). |
*/ |
const OPTION_SEPARATEUR_SORTIE = 'output_separator'; |
/** |
* Options par défaut correspondant au comportement de php |
* vis à vis de $_GET |
*/ |
private $options = array( |
self::OPTION_STRICTE => true, |
self::OPTION_UTILISER_CROCHETS => true, |
self::OPTION_ENCODER_CLES => true, |
self::OPTION_SEPARATEUR_ENTREE => 'x&', |
self::OPTION_SEPARATEUR_SORTIE => 'x&'); |
/** |
* @var string|bool |
*/ |
private $schema = false; |
/** |
* @var string|bool |
*/ |
private $infoUtilisateur = false; |
/** |
* @var string|bool |
*/ |
private $hote = false; |
/** |
* @var int|bool |
*/ |
private $port = false; |
/** |
* @var string |
*/ |
private $chemin = ''; |
/** |
* @var string|bool |
*/ |
private $requete = false; |
/** |
* @var string|bool |
*/ |
private $fragment = false; |
/** |
* @param string $url une URL relative ou absolue |
* @param array $options |
*/ |
public function __construct($url, $options = null) { |
$this->setOption(self::OPTION_SEPARATEUR_ENTREE, |
Config::get('fw_url_arg_separateur_entree')); |
$this->setOption(self::OPTION_SEPARATEUR_SORTIE, |
Config::get('fw_url_arg_separateur_sortie')); |
if (is_array($options)) { |
foreach ($options as $nomOption => $valeur) { |
$this->setOption($nomOption); |
} |
} |
if (preg_match('@^([a-z][a-z0-9.+-]*):@i', $url, $reg)) { |
$this->schema = $reg[1]; |
$url = substr($url, strlen($reg[0])); |
} |
if (preg_match('@^//([^/#?]+)@', $url, $reg)) { |
$this->setAutorite($reg[1]); |
$url = substr($url, strlen($reg[0])); |
} |
$i = strcspn($url, '?#'); |
$this->chemin = substr($url, 0, $i); |
$url = substr($url, $i); |
if (preg_match('@^\?([^#]*)@', $url, $reg)) { |
$this->requete = $reg[1]; |
$url = substr($url, strlen($reg[0])); |
} |
if ($url) { |
$this->fragment = substr($url, 1); |
} |
} |
/** |
* Retourne le schéma, c.a.d. "http" ou "urn", ou false si aucun schéma n'est |
* spécifié, i.e. l'url est une url relative |
* |
* @return string|bool |
*/ |
public function getSchema() { |
return $this->schema; |
} |
/** |
* @param string|bool $schema |
* |
* @return void |
* @see getSchema() |
*/ |
public function setSchema($schema) { |
$this->schema = $schema; |
} |
/** |
* renvoie la partie user de la partie infoUtilisateur (partie précédant le premier |
* ":"), ou false si aucune partie infoUtilisateur n'est définie. |
* |
* @return string|bool |
*/ |
public function getUtilisateur() { |
return $this->infoUtilisateur !== false ? preg_replace('@:.*$@', '', $this->infoUtilisateur) : false; |
} |
/** |
* renvoie la partie mot de passe de la partie infoUtilisateur (partie après le premier |
* ":"), , ou false si aucune partie infoUtilisateur n'est définie (i.e. l'URL ne contient |
* pas de "@" en face du nom d'hôte) ou si la partie infoUtilisateur ne contient pas de ":". |
* |
* @return string|bool |
*/ |
public function getMotDePasse() { |
return $this->infoUtilisateur !== false ? substr(strstr($this->infoUtilisateur, ':'), 1) : false; |
} |
/** |
* Renvoie la partie userinfio, ou false si celle-ci n'existe pas, i.e. si la partie |
* autorité ne contient pas de "@" |
* |
* @return string|bool |
*/ |
public function getInfoUtilisateur() { |
return $this->infoUtilisateur; |
} |
/** |
* Setteur pour la partie infoUtilisateur. Si deux argument sont passé, ils sont combinés |
* dans la partie infoUtilisateur de cette manière username ":" password. |
* |
* @param string|bool $infoUtilisateur infoUtilisateur ou username |
* @param string|bool $motDePasse |
* |
* @return void |
*/ |
public function setInfoUtilisateur($infoUtilisateur, $motDePasse = false) { |
$this->infoUtilisateur = $infoUtilisateur; |
if ($motDePasse !== false) { |
$this->infoUtilisateur .= ':' . $motDePasse; |
} |
} |
/** |
* Renvoie la partie hôte, ou false s'il n'y a pas de partie autorité, c.a.d. |
* l'URL est relative. |
* |
* @return string|bool |
*/ |
public function getHote() { |
return $this->hote; |
} |
/** |
* @param string|bool $hote |
* |
* @return void |
*/ |
public function setHote($hote) { |
$this->hote = $hote; |
} |
/** |
* Renvoie le numéro de port, ou false si aucun numéro de port n'est spécifié, |
* i.e. le port par défaut doit utilisé. |
* |
* @return int|bool |
*/ |
public function getPort() { |
return $this->port; |
} |
/** |
* @param int|bool $port |
* |
* @return void |
*/ |
public function setPort($port) { |
$this->port = intval($port); |
} |
/** |
* Renvoie la partie autorité, i.e. [ infoUtilisateur "@" ] hote [ ":" port ], ou |
* false si celle-ci est absente. |
* |
* @return string|bool |
*/ |
public function getAutorite() { |
if (!$this->hote) { |
return false; |
} |
$autorite = ''; |
if ($this->infoUtilisateur !== false) { |
$autorite .= $this->infoUtilisateur . '@'; |
} |
$autorite .= $this->hote; |
if ($this->port !== false) { |
$autorite .= ':' . $this->port; |
} |
return $autorite; |
} |
/** |
* @param string|false $autorite |
* |
* @return void |
*/ |
public function setAutorite($autorite) { |
$this->user = false; |
$this->pass = false; |
$this->hote = false; |
$this->port = false; |
if (preg_match('@^(([^\@]+)\@)?([^:]+)(:(\d*))?$@', $autorite, $reg)) { |
if ($reg[1]) { |
$this->infoUtilisateur = $reg[2]; |
} |
$this->hote = $reg[3]; |
if (isset($reg[5])) { |
$this->port = intval($reg[5]); |
} |
} |
} |
/** |
* Renvoie la partie chemin (chemin) (éventuellement vide). |
* |
* @return string |
*/ |
public function getChemin() { |
return $this->chemin; |
} |
/** |
* @param string $chemin |
* |
* @return void |
*/ |
public function setChemin($chemin) { |
$this->chemin = $chemin; |
} |
/** |
* renvoie la chaine de requête (requete string) (sans le premier "?"), ou false si "?" |
* n'est pas présent dans l'url. |
* |
* @return string|bool |
* @see self::getVariablesRequete() |
*/ |
public function getRequete() { |
return $this->requete; |
} |
/** |
* @param string|bool $requete |
* |
* @return void |
* @see self::setVariablesRequete() |
*/ |
public function setRequete($requete) { |
$this->requete = $requete; |
} |
/** |
* Renvoie le nom du fragment, ou false si "#" n'est pas present dans l'URL. |
* |
* @return string|bool |
*/ |
public function getFragment() { |
return $this->fragment; |
} |
/** |
* @param string|bool $fragment |
* |
* @return void |
*/ |
public function setFragment($fragment) { |
$this->fragment = $fragment; |
} |
/** |
* Renvoie la requete string sous forme d'un tableau de variables telles qu'elles apparaitraient |
* dans le $_GET d'un script PHP |
* |
* @return array |
*/ |
public function getVariablesRequete() { |
$pattern = '/' . |
preg_quote($this->getOption(self::OPTION_SEPARATEUR_ENTREE), '/') . |
'/'; |
$parties = preg_split($pattern, $this->requete, -1, PREG_SPLIT_NO_EMPTY); |
$retour = array(); |
foreach ($parties as $partie) { |
if (strpos($partie, '=') !== false) { |
list($cle, $valeur) = explode('=', $partie, 2); |
} else { |
$cle = $partie; |
$valeur = null; |
} |
if ($this->getOption(self::OPTION_ENCODER_CLES)) { |
$cle = rawurldecode($cle); |
} |
$valeur = rawurldecode($valeur); |
if ($this->getOption(self::OPTION_UTILISER_CROCHETS) && |
preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $cle, $matches)) { |
$cle = $matches[1]; |
$idx = $matches[2]; |
// On s'assure que c'est bien un tableau |
if (empty($retour[$cle]) || !is_array($retour[$cle])) { |
$retour[$cle] = array(); |
} |
// Ajout des données |
if ($idx === '') { |
$retour[$cle][] = $valeur; |
} else { |
$retour[$cle][$idx] = $valeur; |
} |
} elseif (!$this->getOption(self::OPTION_UTILISER_CROCHETS) |
&& !empty($retour[$cle]) |
) { |
$retour[$cle] = (array) $retour[$cle]; |
$retour[$cle][] = $valeur; |
} else { |
$retour[$cle] = $valeur; |
} |
} |
return $retour; |
} |
/** |
* @param array $tableau (nom => valeur) tableau |
* |
* @return void |
*/ |
public function setVariablesRequete(array $tableau) { |
if (!$tableau) { |
$this->requete = false; |
} else { |
foreach ($tableau as $nom => $valeur) { |
if ($this->getOption(self::OPTION_ENCODER_CLES)) { |
$nom = rawurlencode($nom); |
} |
if (is_array($valeur)) { |
foreach ($valeur as $k => $v) { |
$parties[] = $this->getOption(self::OPTION_UTILISER_CROCHETS) |
? sprintf('%s[%s]=%s', $nom, $k, $v) |
: ($nom . '=' . $v); |
} |
} elseif (!is_null($valeur)) { |
$parties[] = $nom . '=' . $valeur; |
} else { |
$parties[] = $nom; |
} |
} |
$this->requete = implode($this->getOption(self::OPTION_SEPARATEUR_SORTIE), |
$parties); |
} |
} |
/** |
* @param string $nom |
* @param mixed $valeur |
* |
* @return array |
*/ |
public function setVariableRequete($nom, $valeur) { |
$tableau = $this->getVariablesRequete(); |
$tableau[$nom] = $valeur; |
$this->setVariablesRequete($tableau); |
} |
/** |
* @param string $nom |
* |
* @return void |
*/ |
public function unsetVariableRequete($nom) { |
$tableau = $this->getVariablesRequete(); |
unset($tableau[$nom]); |
$this->setVariablesRequete($tableau); |
} |
/** |
* @param array $noms tableau des noms de variable à supprimer de l'url. |
* |
* @return void |
*/ |
public function unsetVariablesRequete($noms) { |
$tableau = $this->getVariablesRequete(); |
foreach ($noms as $nom) { |
unset($tableau[$nom]); |
} |
$this->setVariablesRequete($tableau); |
} |
/** |
* Renvoie un représentation sous forme de chaine de l'URL |
* |
* @return string |
*/ |
public function getURL() { |
// Voir RFC 3986, section 5.3 |
$url = ""; |
if ($this->schema !== false) { |
$url .= $this->schema . ':'; |
} |
$autorite = $this->getAutorite(); |
if ($autorite !== false) { |
$url .= '//' . $autorite; |
} |
$url .= $this->chemin; |
if ($this->requete !== false) { |
$url .= '?' . $this->requete; |
} |
if ($this->fragment !== false) { |
$url .= '#' . $this->fragment; |
} |
return $url; |
} |
/** |
* Renvoie une représentation de cette URL sous forme de chaine normalisée. Utile pour la |
* comparaison d'URLs |
* |
* @return string |
*/ |
public function getURLNormalisee() { |
$url = clone $this; |
$url->normaliser(); |
return $url->getUrl(); |
} |
/** |
* Renvoie une instance normalisée de Url |
* |
* @return Url |
*/ |
public function normaliser() { |
// See RFC 3886, section 6 |
// les cchémas sont insesibles à la casse |
if ($this->schema) { |
$this->schema = strtolower($this->schema); |
} |
// les noms d'hotes sont insensibles à la casse |
if ($this->hote) { |
$this->hote = strtolower($this->hote); |
} |
// Supprimer le numéro de port par défaut pour les schemas connus (RFC 3986, section 6.2.3) |
if ($this->port && |
$this->schema && |
$this->port == getservbyname($this->schema, 'tcp')) { |
$this->port = false; |
} |
// normalisation dans le cas d'un encodage avec %XX pourcentage (RFC 3986, section 6.2.2.1) |
foreach (array('infoUtilisateur', 'hote', 'chemin') as $partie) { |
if ($this->$partie) { |
$this->$partie = preg_replace('/%[0-9a-f]{2}/ie', 'strtoupper("\0")', $this->$partie); |
} |
} |
// normalisation des segments du chemin (RFC 3986, section 6.2.2.3) |
$this->chemin = self::supprimerSegmentsAPoints($this->chemin); |
// normalisation basée sur le schéma (RFC 3986, section 6.2.3) |
if ($this->hote && !$this->chemin) { |
$this->chemin = '/'; |
} |
} |
/** |
* Renvoie vrai ou faux suivant que l'instance en cours représente une URL relative ou absolue. |
* |
* @return bool |
*/ |
public function etreAbsolue() { |
return (bool) $this->schema; |
} |
/** |
* Renvoie une instance de Url représentant une URL absolue relative à |
* cette URL. |
* |
* @param Url|string $reference URL relative |
* |
* @return Url |
*/ |
public function resoudre($reference) { |
if (is_string($reference)) { |
$reference = new self($reference); |
} |
if (!$this->etreAbsolue()) { |
throw new Exception('L\'URL de base doit être absolue !'); |
} |
// Un parseur non strict peut choisir d'ignorer un schema dans la référence |
// si celui ci est identique au schéma de base de l'URI. |
if (!$this->getOption(self::OPTION_STRICTE) && $reference->schema == $this->schema) { |
$reference->schema = false; |
} |
$cible = new self(''); |
if ($reference->schema !== false) { |
$cible->schema = $reference->schema; |
$cible->setAutorite($reference->getAutorite()); |
$cible->chemin = self::supprimerSegmentsAPoints($reference->chemin); |
$cible->requete = $reference->requete; |
} else { |
$autorite = $reference->getAutorite(); |
if ($autorite !== false) { |
$cible->setAutorite($autorite); |
$cible->chemin = self::supprimerSegmentsAPoints($reference->chemin); |
$cible->requete = $reference->requete; |
} else { |
if ($reference->chemin == '') { |
$cible->chemin = $this->chemin; |
if ($reference->requete !== false) { |
$cible->requete = $reference->requete; |
} else { |
$cible->requete = $this->requete; |
} |
} else { |
if (substr($reference->chemin, 0, 1) == '/') { |
$cible->chemin = self::supprimerSegmentsAPoints($reference->chemin); |
} else { |
// Concaténation chemins (RFC 3986, section 5.2.3) |
if ($this->hote !== false && $this->chemin == '') { |
$cible->chemin = '/' . $this->chemin; |
} else { |
$i = strrpos($this->chemin, '/'); |
if ($i !== false) { |
$cible->chemin = substr($this->chemin, 0, $i + 1); |
} |
$cible->chemin .= $reference->chemin; |
} |
$cible->chemin = self::supprimerSegmentsAPoints($cible->chemin); |
} |
$cible->requete = $reference->requete; |
} |
$cible->setAutorite($this->getAutorite()); |
} |
$cible->schema = $this->schema; |
} |
$cible->fragment = $reference->fragment; |
return $cible; |
} |
/** |
* La suppression des segments à points est décrite dans la RFC 3986, section 5.2.4, e.g. |
* "/foo/../bar/baz" => "/bar/baz" |
* |
* @param string $chemin un chemin |
* |
* @return string un chemin |
*/ |
private static function supprimerSegmentsAPoints($chemin) { |
$sortie = ''; |
// Assurons de ne pas nous retrouver piégés dans une boucle infinie due à un bug de |
// cette méthode |
$j = 0; |
while ($chemin && $j++ < 100) { |
// Étape A |
if (substr($chemin, 0, 2) == './') { |
$chemin = substr($chemin, 2); |
} elseif (substr($chemin, 0, 3) == '../') { |
$chemin = substr($chemin, 3); |
// Étape B |
} elseif (substr($chemin, 0, 3) == '/./' || $chemin == '/.') { |
$chemin = '/' . substr($chemin, 3); |
// Étape C |
} elseif (substr($chemin, 0, 4) == '/../' || $chemin == '/..') { |
$chemin = '/' . substr($chemin, 4); |
$i = strrpos($sortie, '/'); |
$sortie = $i === false ? '' : substr($sortie, 0, $i); |
// Étape D |
} elseif ($chemin == '.' || $chemin == '..') { |
$chemin = ''; |
// Étape E |
} else { |
$i = strpos($chemin, '/'); |
if ($i === 0) { |
$i = strpos($chemin, '/', 1); |
} |
if ($i === false) { |
$i = strlen($chemin); |
} |
$sortie .= substr($chemin, 0, $i); |
$chemin = substr($chemin, $i); |
} |
} |
return $sortie; |
} |
/** |
* Renvoie une instance de Url representant l'URL canonique du script PHP |
* en cours d'éxécution |
* |
* @return string |
*/ |
public static function getCanonique() { |
if (!isset($_SERVER['REQUEST_METHOD'])) { |
// ALERT - pas d'URL en cours |
throw new Exception('Le script n\'a pas été appellé à travers un serveur web'); |
} |
// on part d'une URL relative |
$url = new self($_SERVER['PHP_SELF']); |
$url->schema = isset($_SERVER['HTTPS']) ? 'https' : 'http'; |
$url->hote = $_SERVER['SERVER_NAME']; |
$port = intval($_SERVER['SERVER_PORT']); |
if ($url->schema == 'http' && $port != 80 || |
$url->schema == 'https' && $port != 443) { |
$url->port = $port; |
} |
return $url; |
} |
/** |
* Renvoie l'URL utilisée pour récupérer la requête en cours |
* |
* @return string |
*/ |
public static function getURLDemande() { |
return self::getDemande()->getUrl(); |
} |
/** |
* Renvoie une instance de Url representant l'URL utilisée pour |
* récupérer la requête en cours |
* |
* @return Url |
*/ |
public static function getDemande() { |
if (!isset($_SERVER['REQUEST_METHOD'])) { |
// ALERTE - pas d'URL en cours |
throw new Exception('Le script n\'a pas été appellé à travers un serveur web'); |
} |
// On part d'une URL relative |
$url = new self($_SERVER['REQUEST_URI']); |
$url->schema = isset($_SERVER['HTTPS']) ? 'https' : 'http'; |
// On met à jour les valeurs de l'hote et si possible du port |
$url->setAutorite($_SERVER['HTTP_hote']); |
return $url; |
} |
/** |
* Met à jour la valeur de l'option spécifiée. |
* |
* @param string $nomOption une des constantes commençant par self::OPTION_ |
* @param mixed $valeur valeur de l'option |
* |
* @return void |
* @see self::OPTION_STRICTE |
* @see self::OPTION_UTILISER_CROCHETS |
* @see self::OPTION_ENCODER_CLES |
*/ |
function setOption($nomOption, $valeur) { |
if (!array_key_exists($nomOption, $this->options)) { |
return false; |
} |
$this->options[$nomOption] = $valeur; |
} |
/** |
* Renvoie la valeur de l'option specifiée. |
* |
* @param string $nomOption Nom de l'option demandée |
* |
* @return mixed |
*/ |
function getOption($nomOption) { |
return isset($this->options[$nomOption]) |
? $this->options[$nomOption] : false; |
} |
public function __toString() { |
return $this->getURL(); |
} |
} |
Property changes: |
Added: svn:keywords |
+Id Author Date Revision HeadURL |
\ No newline at end of property |
/branches/v1.0-adhemar/framework/Application.php |
---|
New file |
0,0 → 1,82 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Classe fournissant des informations au Framework sur l'application. |
* |
* PHP version 5 |
* |
* @category Debogage |
* @package Framework |
// Auteur principal : |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
// Autres auteurs : |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $$Id$$ |
* @copyright 1999-2009 Tela Botanica (accueil@tela-botanica.org) |
*/ |
class Application { |
/** |
* tableau d'informations sur l'application |
*/ |
private static $info = null; |
/** |
* chemin de base de l'application |
*/ |
private static $chemin = null; |
/** |
* Modificateur pour le chemin de base |
* @param string $chemin_fichier_principal chemin de base |
*/ |
public static function setChemin($chemin_fichier_principal) { |
if (self::$chemin === null) { |
if (!file_exists($chemin_fichier_principal)) { |
trigger_error("Le fichier indiqué n'existe pas. Utilisez __FILE__ dans la méthode set().", E_USER_ERROR); |
} else { |
self::$chemin = dirname($chemin_fichier_principal).DS; |
} |
} else { |
trigger_error("Le chemin de l'application a déjà été enregistré auprès du Framework", E_USER_WARNING); |
} |
} |
/** |
* accesseur pour le chemin |
* @return string le chemin |
*/ |
public static function getChemin() { |
return self::$chemin; |
} |
/** Le tableau des informations sur l'application possède les clés suivantes : |
* - nom : nom de l'application |
* - abr : abréviation de l'application |
* - encodage : encodage de l'application (ISO-8859-15, UTF-8...) |
* |
* @param array $info tableau fournissant des informations sur l'application |
* @return void |
*/ |
public static function setInfo($info) { |
if (self::$info === null) { |
self::$info = $info; |
} else { |
trigger_error("Le informations de l'application ont déjà été enregistrées auprès du Framework", E_USER_WARNING); |
} |
} |
/** |
* accesseur pour le tableau d'infos |
* @param string $cle la clé à laquelle on veut accéder |
*/ |
public static function getInfo($cle = null) { |
if ($cle !== null) { |
if (isset(self::$info[$cle])) { |
return self::$info[$cle]; |
} |
} else { |
return self::$info; |
} |
} |
} |
Property changes: |
Added: svn:keywords |
+Id Author Date Revision HeadURL |
\ No newline at end of property |
/branches/v1.0-adhemar/framework/SquelettePhp.php |
---|
New file |
0,0 → 1,74 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Classe SquelettePhp, traitant les squelette Php utilisant la syntaxe courte php ou pas. |
* Ces méthodes sont statiques. |
* |
* @category php5 |
* @package Framework |
* @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$$ |
* @link /doc/framework/ |
*/ |
class SquelettePhp { |
/** |
* Fonction prenant en paramètre un chemin de fichier squelette et un tableau associatif de données, |
* en extrait les variables, charge le squelette et retourne le résultat des deux combinés. |
* |
* @param String $fichier le chemin du fichier du squelette |
* @param Array $donnees un tableau associatif contenant les variables a injecter dans le squelette. |
* |
* @return boolean false si la vue n'existe pas, sinon la chaine résultat. |
*/ |
public static function analyser($fichier, Array $donnees = array()) { |
$sortie = false; |
if (file_exists($fichier)) { |
// Extraction des variables du tableau de données |
extract($donnees); |
// Démarage de la bufferisation de sortie |
ob_start(); |
// Si les tags courts sont activés |
if ((bool) @ini_get('short_open_tag') === true) { |
// Simple inclusion du squelette |
include $fichier; |
} else { |
// Sinon, remplacement des tags courts par la syntaxe classique avec echo |
$html_et_code_php = self::traiterTagsCourts($fichier); |
// Pour évaluer du php mélangé dans du html il est nécessaire de fermer la balise php ouverte par eval |
$html_et_code_php = '?>'.$html_et_code_php; |
// Interprétation du html et du php dans le buffer |
echo eval($html_et_code_php); |
} |
// Récupèration du contenu du buffer |
$sortie = ob_get_contents(); |
// Suppression du buffer |
@ob_end_clean(); |
} else { |
$msg = "Le fichier du squelette '$fichier' n'existe pas."; |
trigger_error($msg, E_USER_WARNING); |
} |
// Retourne le contenu |
return $sortie; |
} |
/** |
* Fonction chargeant le contenu du squelette et remplaçant les tags court php (<?= ...) par un tag long avec echo. |
* |
* @param String $chemin_squelette le chemin du fichier du squelette |
* |
* @return string le contenu du fichier du squelette php avec les tags courts remplacés. |
*/ |
private static function traiterTagsCourts($chemin_squelette) { |
$contenu = file_get_contents($chemin_squelette); |
// Remplacement de tags courts par un tag long avec echo |
$contenu = str_replace('<?=', '<?php echo ', $contenu); |
// Ajout systématique d'un point virgule avant la fermeture php |
$contenu = preg_replace("/;*\s*\?>/", "; ?>", $contenu); |
return $contenu; |
} |
} |
?> |
Property changes: |
Added: svn:keywords |
+Id Author Date Revision HeadURL |
\ No newline at end of property |
/branches/v1.0-adhemar/framework/Registre.php |
---|
New file |
0,0 → 1,94 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Classe registre, qui permet un accès à différentes variables à travers les autres classes. |
* C'est un singleton |
* |
* PHP Version 5 |
* |
* @category Class |
* @package Framework |
* @author Jean-Pascal Milcent <jmp@tela-botanica.org> |
* @copyright 2009 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$$ |
* @link /doc/framework/ |
* |
*/ |
class Registre { |
/** |
* Tableau associatif stockant les variables |
*/ |
private $stockage = array(); |
/** |
* La classe registre se contient elle-même, (pour le pattern singleton) |
*/ |
private static $registre; |
/** |
* Constructeur par défaut, privé, car on accède à la classe par le getInstance |
*/ |
private function __construct() { |
} |
/** |
* Fonction qui renvoie l'instance de classe en assurant son unicité, c'est l'unique méthode qui doit être |
* utilisée pour récupérer l'objet Registre |
*/ |
public static function getInstance() { |
if (self::$registre instanceof Registre) { |
return self::$registre; |
} |
self::$registre = new Registre; |
return self::$registre; |
} |
/** |
* Ajoute un objet au tableau selon un intitulé donné |
* @param string l'intitulé sous lequel l'objet sera conservé |
* @param mixed l'objet à conserver |
*/ |
public function set($intitule, $objet) { |
if (is_array($objet) && isset($this->stockage[$intitule])) { |
$this->stockage[$intitule] = array_merge((array) $this->stockage[$intitule], (array) $objet); |
$message = "Le tableau $intitule présent dans le registre a été fusionné avec un nouveau tableau de même intitulé !"; |
trigger_error($message, E_USER_WARNING); |
} else { |
$this->stockage[$intitule] = $objet; |
} |
} |
/** |
* Renvoie l'objet associé à l'intitulé donné en paramètre |
* @return mixed l'objet associé à l'intitulé ou null s'il n'est pas présent |
*/ |
public function get($intitule) { |
if (isset($this->stockage[$intitule])) { |
return $this->stockage[$intitule]; |
} |
return null; |
} |
/** |
* Détruit l'objet associé à l'intitulé, n'a pas d'effet si il n'y a pas d'objet associé |
*/ |
public function detruire($intitule) { |
if (isset($this->stockage[$intitule])) { |
unset($this->stockage[$intitule]); |
} |
} |
/** |
* Teste si un objet est présent sous un intitulé donné |
* @return boolean true si un objet associé à cet intitulé est présent, false sinon |
*/ |
public function existe($intitule) { |
if(isset($this->stockage[$intitule])){ |
return true; |
} |
return false; |
} |
} |
?> |
Property changes: |
Added: svn:keywords |
+Id Author Date Revision HeadURL |
\ No newline at end of property |
/branches/v1.0-adhemar/framework/config.defaut.ini |
---|
New file |
0,0 → 1,119 |
; Renommer ce fichier en config.ini |
; +------------------------------------------------------------------------------------------------------+ |
; Général |
; Séparateur de dossier |
ds = DIRECTORY_SEPARATOR |
; Séparateur de chemin |
ps = PATH_SEPARATOR |
; Fin de ligne de fichier |
eol = PHP_EOL |
; +------------------------------------------------------------------------------------------------------+ |
; Urls |
; Le séparateur utilisé pour séparer les arguments des urls lorsque le framework parse une url. |
; Pour remettre les valeurs par défaut, utitliser : "php:ini_get('arg_separator.input')" |
fw_url_arg_separateur_entree = "&" |
; Le séparateur utilisé par le framework lorsqu'il génère des URL pour séparer les arguments. |
; Pour remettre les valeurs par défaut, utitliser : "php:ini_get('arg_separator.output')" |
fw_url_arg_separateur_sortie = "&" |
; +------------------------------------------------------------------------------------------------------+ |
; Débogage |
; Indique si oui ou non on veut afficher le débogage. |
fw_debogage = true |
; Indique si oui ou non on veut afficher le contexte de débogage. |
fw_debogage_contexte = false |
; Niveau d'erreur à employer pour le code PHP. Voir le manuel de PHP pour les différents niveaux disponibles. |
fw_debogage_niveau = 2048 |
; Indique si oui ou non on veut activer la journalisation des erreurs. |
fw_log_debogage = false |
; Indique le fuseau horaire pour le datage des logs. |
fw_timezone = Europe/Paris |
; Indique la taille max d'un fichier log (en octets) |
fw_taille_max_logs = 1000000 |
; +------------------------------------------------------------------------------------------------------+ |
; Benchmark |
; Indique si oui ou nom on veut afficher le tableau de chronométrage de l'application. |
fw_benchmark_chrono = true |
; +------------------------------------------------------------------------------------------------------+ |
; Chemins et fichiers |
; Nom des fichiers de config recherché. Défini par défaut dans la classe Config |
; fw_fichier_config = "config%s.ini" |
; Chemin vers le dossier du framework. Défini par défaut dans la classe Config |
; fw_chemin = "php:dirname(__FILE__).DS" |
; Nom du dossier de la bibliotheque de codes de l'application. |
dossier_bibliotheque = bibliotheque |
; Nom du dossier des composants graphiques de l'application. |
dossier_composants = composants |
; Nom du dossier des controleurs de l'application. |
dossier_configurations = configurations |
; Nom du dossier des controleurs de l'application. |
dossier_controleurs = controleurs |
; Nom du dossier des traductions de l'application. |
dossier_i18n = i18n |
; Nom du dossier des modèles de l'application. |
dossier_modeles = modeles |
; Nom du dossier des squelettes de l'application. |
dossier_squelettes = squelettes |
; Nom du dossier des logs de l'application. |
dossier_logs = logs |
; Chemin vers le dossier de l'appli. |
chemin_appli = "php:Application::getChemin()" |
; Chemin vers le dossier de la bibliotheque de codes de l'application. |
chemin_bibliotheque = "{ref:chemin_appli}{ref:dossier_bibliotheque}{ref:ds}" |
; Chemin vers le dossier des composants graphiques de l'application. |
chemin_composants = "{ref:chemin_appli}{ref:dossier_composants}{ref:ds}" |
; Chemin vers le dossier des controleurs de l'application. |
chemin_configurations = "{ref:chemin_appli}{ref:dossier_configurations}{ref:ds}" |
; Chemin vers le dossier des controleurs de l'application. |
chemin_controleurs = "{ref:chemin_appli}{ref:dossier_controleurs}{ref:ds}" |
; Chemin vers le dossier des traductions de l'application. |
chemin_i18n = "{ref:chemin_appli}{ref:dossier_i18n}{ref:ds}" |
; Chemin vers le dossier des modèles de l'application. |
chemin_modeles = "{ref:chemin_appli}{ref:dossier_modeles}{ref:ds}" |
; Chemin vers le dossier des squelettes de l'application. |
chemin_squelettes = "{ref:chemin_appli}{ref:dossier_squelettes}{ref:ds}" |
; Chemin vers le dossier des logs de l'application. |
chemin_logs = "{ref:chemin_appli}{ref:dossier_logs}{ref:ds}" |
; +------------------------------------------------------------------------------------------------------+ |
; Paramètrage de la base de données. |
; abstraction de la base de données. |
bdd_abstraction = pdo |
; Protocole de la base de données. |
bdd_protocole = mysql |
; Nom du serveur de bases de données. |
bdd_serveur = localhost |
; Nom de l'utilisateur de la base de données. |
bdd_utilisateur = "" |
; Mot de passe de l'utilisateur de la base de données. |
bdd_mot_de_passe = "" |
; Nom de la base de données principale. |
bdd_nom = "" |
; Encodage de la base de données principale. Normalement le même que l'application mais au format base de |
données : voir ici : http://dev.mysql.com/doc/refman/5.0/en/charset-charsets.html |
et là: http://www.postgresql.org/docs/8.1/static/multibyte.html pour les correspondances |
bdd_encodage = "utf8" |
; +------------------------------------------------------------------------------------------------------+ |
; Encodage de l'application, des fichiers php, squelettes... de l'application |
appli_encodage = "UTF-8" |
; Encodage des donnés renvoyées au navigateur |
; (faire attention à la correspondane avec les .htaccess et les balises meta du html des squelettes) |
sortie_encodage = "UTF-8" |
; +------------------------------------------------------------------------------------------------------+ |
; URLs |
; URL de base de l'application, si elle est laissée vide, l'application fonctionnera en Stand-alone |
; Peut utiliser une objet Net_URL comme ceci : "php:$mon_objet_net_url->getUrl()" |
url_base = "" |
; +------------------------------------------------------------------------------------------------------+ |
; Identifications |
; Indiquer ici si l'utilisateur est identifié ou pas. |
; Peut utiliser un objet Auth comme ceci : "php:$mon_objet_auth->getAuth()" |
identification = true |
Property changes: |
Added: svn:keywords |
+Id Author Date Revision HeadURL |
\ No newline at end of property |
/branches/v1.0-adhemar/framework/.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 |
Property changes: |
Added: svn:keywords |
+Id Author Date Revision HeadURL |
\ No newline at end of property |
/branches/v1.0-adhemar/framework/Chronometre.php |
---|
New file |
0,0 → 1,152 |
<?php |
// declare(encoding='UTF-8'); |
/** Classe Chronometre() - Permet de stocker et d'afficher |
* les temps d'éxécution de script. |
* |
* Cette classe permet de réaliser un ensemble |
* de mesure de temps prises à |
* différents endroits d'un script. |
* Ces mesures peuvent ensuite être affichées au |
* sein d'un tableau XHTML. |
* |
* |
* PHP Version 5 |
* |
* @category PHP |
* @package Framework |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright 2009 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version Release: <package_version> |
* @link /doc/framework/ |
*/ |
class Chronometre { |
/*** Attributs : ***/ |
private $_temps = array(); |
/** Constructeur : **/ |
public function __construct() { |
$this->setTemps(array('depart' => microtime())); |
} |
/** Accesseurs : |
* |
* @param string $cle la cle associée à un chronomètre particulier |
* |
* @return int le temps écoulé |
*/ |
public function getTemps($cle = null) { |
$temps = ''; |
if (!is_null($cle)) { |
$temps = $this->_temps[$cle]; |
} else { |
$temps = $this->_temps; |
} |
return $temps; |
} |
/** Setteur pour la variable temps |
* |
* @param array() $moment ajoute des points de chronométrage au tableau _temps |
* |
* @return null |
*/ |
public function setTemps($moment = array ()) { |
array_push($this->_temps, $moment); |
} |
/*** Méthodes : ***/ |
/** Méthode afficherChrono() - |
* Permet d'afficher les temps d'éxécution de différentes parties d'un script. |
* |
* Cette fonction permet d'afficher un ensemble de |
* mesure de temps prises à différents endroits d'un script. |
* Ces mesures sont affichées au sein d'un tableau XHTML |
* dont on peut controler l'indentation des balises. |
* Pour un site en production, il suffit d'ajouter un style |
* #chrono {display:none;} dans la css. De cette façon, |
* le tableau ne s'affichera pas. Le webmaster lui pourra |
* rajouter sa propre feuille de style affichant le tableau. |
* Le développeur initial de cette fonction est Loic d'Anterroches. |
* Elle a été modifiée par Jean-Pascal Milcent. |
* Elle utilise une variable gobale : $_CHRONO_ |
* |
* @author Loic d'Anterroches |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* |
* @param int $indentation_origine l'indentation de base. |
* @param int $indentation le pas d'indentation. |
* @return string la chaine XHTML de mesure des temps. |
*/ |
public function afficherChrono($indentation_origine = 8, $indentation = 4) { |
// Création du chrono de fin |
$GLOBALS['_SCRIPT_']['chrono']->setTemps(array ( |
'fin' => microtime() |
)); |
// Début création de l'affichage |
$sortie = str_repeat(' ', $indentation_origine) . |
'<table id="chrono" lang="fr" summary="Résultat du |
chronométrage du programme affichant la page actuelle.">' . "\n"; |
$sortie .= str_repeat(' ', ($indentation_origine + ($indentation * 1))) . |
'<caption>Chronométrage</caption>' . "\n"; |
$sortie .= str_repeat(' ', ($indentation_origine + ($indentation * 1))) . |
'<thead>' . "\n"; |
$sortie .= str_repeat(' ', ($indentation_origine + ($indentation * 2))) . |
'<tr><th>Action</th><th>Temps écoulé (en s.)</th> |
<th>Cumul du temps écoulé (en s.)</th></tr>' . "\n"; |
$sortie .= str_repeat(' ', ($indentation_origine + ($indentation * 1))) . |
'</thead>' . "\n"; |
$tbody = str_repeat(' ', ($indentation_origine + ($indentation * 1))) . |
'<tbody>' . "\n"; |
$total_tps_ecoule = 0; |
// Récupération de la premiére mesure |
$tab_depart = & $this->getTemps(0); |
list ($usec, $sec) = explode(' ', $tab_depart['depart']); |
// Ce temps correspond à tps_fin |
$tps_debut = ((float) $usec + (float) $sec); |
foreach ($this->getTemps() as $tab_temps) { |
foreach ($tab_temps as $cle => $valeur) { |
list ($usec, $sec) = explode(' ', $valeur); |
$tps_fin = ((float) $usec + (float) $sec); |
$tps_ecoule = abs($tps_fin - $tps_debut); |
$total_tps_ecoule += $tps_ecoule; |
$tbody .= str_repeat(' ', |
($indentation_origine + ($indentation * 2))) . |
'<tr>' . |
'<th>' . $cle . '</th>' . |
'<td>' . number_format($tps_ecoule, 3, ',', ' ') . '</td>' . |
'<td>' . number_format($total_tps_ecoule, 3, ',', ' ') . '</td>' . |
'</tr>' . "\n"; |
$tps_debut = $tps_fin; |
} |
} |
$tbody .= str_repeat(' ', ($indentation_origine + ($indentation * 1))) . |
'</tbody>' . "\n"; |
$sortie .= str_repeat(' ', ($indentation_origine + ($indentation * 1))) . |
'<tfoot>' . "\n"; |
$sortie .= str_repeat(' ', ($indentation_origine + ($indentation * 2))) . |
'<tr>' . |
'<th>' . 'Total du temps écoulé (en s.)' . '</th>' . |
'<td colspan="2">' . |
number_format($total_tps_ecoule, 3, ',', ' ') . '</td>' . |
'</tr>' . "\n"; |
$sortie .= str_repeat(' ', ($indentation_origine + ($indentation * 1))) . |
'</tfoot>' . "\n"; |
$sortie .= $tbody; |
$sortie .= str_repeat(' ', $indentation_origine) . |
'</table>' . "\n"; |
return $sortie; |
} |
} |
?> |
Property changes: |
Added: svn:keywords |
+Id Author Date Revision HeadURL |
\ No newline at end of property |
/branches/v1.0-adhemar/framework/Config.php |
---|
New file |
0,0 → 1,269 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Config permet de charger automatiquement les fichiers ini du Framework et de l'application. |
* Elle offre l'accès en lecture seule aux paramètres de config. |
* C'est une Singleton. |
* |
* PHP Version 5 |
* |
* @category PHP |
* @package Framework |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright 2009 Tela-Botanica |
* @license GPL-v3 et CECILL-v2 |
* @version SVN: <svn_id> |
* @link /doc/framework/ |
*/ |
class Config { |
/** |
* instance de la classe pointant sur elle même (pour le pattern singleton) |
*/ |
private static $instance = null; |
/** |
* paramètres de configuration |
*/ |
private static $parametres = array(); |
/** |
* Constructeur vide |
*/ |
private function __construct() { |
// Définition de paramètres avant chargement du config.ini |
self::$parametres = array( |
'fw_fichier_config' => 'config%s.ini', |
'fw_chemin' => dirname(__FILE__).DS |
); |
// Chargement du fichier config.ini du Framework |
$existe = self::parserFichierIni(self::$parametres['fw_chemin'].sprintf(self::$parametres['fw_fichier_config'], '')); |
if ($existe === false) { |
trigger_error("Veuillez configurer le Framework en renommant le fichier config.defaut.ini en config.ini.", E_USER_ERROR); |
} |
// Chargement du fichier config.ini par défaut de l'application |
$chemin_config_defaut_appli = self::$parametres['chemin_configurations'].sprintf(self::$parametres['fw_fichier_config'], ''); |
self::parserFichierIni($chemin_config_defaut_appli); |
// Chargement des fichiers config.ini contextuels |
if (PHP_SAPI == 'cli') {// mode console |
foreach ($_SERVER['argv'] as $cle => $valeur) { |
if ($valeur == '-contexte') { |
chargerFichierContexte($_SERVER['argv'][($cle+1)]); |
break; |
} |
} |
} else {// mode web |
// Pour Papyrus |
if (defined('PAP_VERSION')) { |
self::chargerFichierContexte('papyrus'); |
} |
// Via le fichie .ini par défaut de l'appli |
if (Config::existeValeur('info.contexte', self::$parametres)) { |
self::chargerFichierContexte(Config::get('info.contexte')); |
} |
// Chargement du contexte présent dans le GET |
if (isset($_GET['contexte'])) { |
self::chargerFichierContexte($_GET['contexte']); |
} |
// Chargement du contexte présent dans le POST |
if (isset($_POST['contexte'])) { |
self::chargerFichierContexte($_POST['contexte']); |
} |
} |
} |
/** |
* Charge le fichier de config correspondant au contexte |
* @param string $contexte le contexte |
*/ |
private static function chargerFichierContexte($contexte) { |
$chemin_config_appli_contextuel = self::$parametres['chemin_configurations']; |
$chemin_config_appli_contextuel .= sprintf(self::$parametres['fw_fichier_config'], '_'.$contexte); |
self::parserFichierIni($chemin_config_appli_contextuel); |
} |
/** |
* Parse le fichier ini donné en paramètre |
* @param string $fichier_ini nom du fichier ini à parser |
* @return array tableau contenant les paramètres du fichier ini |
*/ |
private static function parserFichierIni($fichier_ini) { |
$retour = false; |
if (file_exists($fichier_ini)) { |
$ini = parse_ini_file($fichier_ini, true); |
$ini = self::analyserTableauIni($ini); |
self::fusionner($ini); |
$retour = true; |
} |
return $retour; |
} |
/** |
* fusionne un tableau de paramètres avec le tableau de paramètres global |
* @param array $ini le tableau à fusionner |
*/ |
private static function fusionner(array $ini) { |
self::$parametres = array_merge(self::$parametres, $ini); |
} |
/** |
* renvoie la valeur demandé grâce une chaine de paramètres |
* @param string $param la chaine de paramètres |
* @param array $config le tableau de paramètre |
* @return string la valeur de la chaine demandée |
*/ |
private static function getValeur($param, $config) { |
if ($param === null) { |
return null; |
} else { |
if (strpos($param, '.') !== false) { |
$pieces = explode('.', $param, 2); |
if (strlen($pieces[0]) && strlen($pieces[1])) { |
if (isset($config[$pieces[0]])) { |
if (is_array($config[$pieces[0]])) { |
return self::getValeur($pieces[1], $config[$pieces[0]]); |
} |
} |
} |
} else { |
if (isset($config[$param])) { |
return $config[$param]; |
} |
} |
return null; |
} |
} |
/** |
* Teste si param existe dans le tableau config |
* @param string $param nom du paramètre |
* @param array tableau de configuration |
*/ |
private static function existeValeur($param, $config) { |
$retour = false; |
if (self::getValeur($param, $config) !== null) { |
$retour = true; |
} |
return $retour; |
} |
/** |
* 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 Config(); |
} |
} |
/** |
* analyse un tableau de paramètres |
* @param array $config le tableau de paramètres |
* @return array le tableau analysé |
*/ |
private static function analyserTableauIni($config = array()) { |
foreach ($config as $cle => $valeur) { |
if (is_array($valeur)) { |
$config[$cle] = self::analyserTableauIni($valeur); |
} else { |
self::evaluerReferences($config, $cle); |
self::evaluerPhp($config, $cle); |
self::evaluerCle($config, $cle, $config[$cle]); |
} |
} |
return $config; |
} |
/** |
* dans le cas des chaine de configuration à sous clé (ex.: cle.souscle) |
* evalue les valeurs correspondantes et crée les sous tableaux associés |
* @param array $config tableau de configuration (par référence) |
* @param string $cle la cle dans le tableau |
* @param string $valeur la valeur à affecter |
*/ |
private static function evaluerCle(&$config, $cle, $valeur) { |
if (strpos($cle, '.') !== false) { |
unset($config[$cle]); |
$pieces = explode('.', $cle, 2); |
if (strlen($pieces[0]) && strlen($pieces[1])) { |
if (!isset($config[$pieces[0]])) { |
if ($pieces[0] === '0' && !empty($config)) { |
// convert the current values in $config into an array |
$config = array($pieces[0] => $config); |
} else { |
$config[$pieces[0]] = array(); |
} |
} elseif (!is_array($config[$pieces[0]])) { |
throw new ErrorException("Ne peut pas créer de sous-clé pour '{$pieces[0]}' car la clé existe déjà"); |
} |
$config[$pieces[0]] = self::evaluerCle($config[$pieces[0]], $pieces[1], $valeur); |
} else { |
throw new ErrorException("Clé invalide '$cle'"); |
} |
} else { |
$config[$cle] = $valeur; |
} |
return $config; |
} |
/** |
* Evalue les valeurs de références à une clé dans le tableau config (cas du ref:cle) |
* @param array $config tableau de configuration |
* @param string $cle la clé dont il faut évaluer les références |
*/ |
private static function evaluerReferences(&$config, $cle) { |
if (preg_match_all('/{ref:([A-Za-z0-9_-]+)}/', $config[$cle], $correspondances, PREG_SET_ORDER)) { |
foreach ($correspondances as $ref) { |
$config[$cle] = str_replace($ref[0], self::getValeur($ref[1], $config), $config[$cle]); |
} |
} |
} |
/** |
* Evalue le code php contenu dans un clé tu tableau config |
* @param array $config tableau de configuration (par référence) |
* @param string $cle le clé du tableau dont il faut évaluer la valeur |
*/ |
private static function evaluerPhp(&$config, $cle) { |
if (preg_match('/^php:(.+)$/', $config[$cle], $correspondances)) { |
eval('$config["'.$cle.'"] = '.$correspondances[1].';'); |
} |
} |
/** |
* Charge un fichier ini dans le tableau des paramètres de l'appli |
* @param string $fichier_ini le nom du fichier à charger |
* @return array le fichier ini parsé |
*/ |
public static function charger($fichier_ini) { |
self::verifierCreationInstance(); |
return self::parserFichierIni($fichier_ini); |
} |
/** |
* Acesseur pour la valeur d'un paramètre |
* @param string $param le nom du paramètre |
* @return string la valeur du paramètre |
*/ |
public static function get($param = null) { |
self::verifierCreationInstance(); |
return self::getValeur($param, self::$parametres); |
} |
/** |
* Vérifie si la valeur d'un paramètre existe |
* @param string $param le nom du paramètre |
* @return boolean vrai si le paramètre existe, false sinon |
*/ |
public static function existe($param) { |
self::verifierCreationInstance(); |
return self::existeValeur($param, self::$parametres); |
} |
} |
?> |
Property changes: |
Added: svn:keywords |
+Id Author Date Revision HeadURL |
\ No newline at end of property |
/branches/v1.0-adhemar/framework/Modele.php |
---|
New file |
0,0 → 1,345 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Classe modèle, donc d'accés au données, elle ne devrait pas être appelée de l'extérieur. |
* Elle fait office d'abstraction légère de base de données en utilisant diveres possibilités |
* d'abstraction de base de données (PDO, mysql, mysqli, sqlite) |
* Elle est abstraite donc doit obligatoirement être étendue. |
* |
* PHP Version 5 |
* |
* @category Class |
* @package Framework |
* @author aurelien <aurelien@tela-botanica.org> |
* @copyright 2009 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$$ |
* @link /doc/framework/ |
* |
*/ |
abstract class Modele { |
/** |
* Mode de fetch associatif |
*/ |
private $ASSOC = ''; |
/** |
* Mode de fetch objet |
*/ |
private $OBJECT = ''; |
/** |
* abstraction de base de données utilisée |
*/ |
private $abstraction; |
/** |
* registre global |
*/ |
private $registre; |
/** |
* DSN pour accéder à la base de données |
*/ |
private $dsn; |
/** |
* Type de base de données (mysql, mysqli, etc ...) |
*/ |
private $type; |
/** |
* Hote herbergeant la base de données |
*/ |
private $hote; |
/** |
* Nom de la base de données à laquelle le modèle doit se connecter |
*/ |
private $bdd_nom; |
/** |
* Nom d'utilisateur |
*/ |
private $utilisateur; |
/** |
* Mot de passe |
*/ |
private $pass; |
/** |
* Encodage de la base de données |
*/ |
private $encodage = null; |
/** |
* Connexion à la base de données |
*/ |
private $connexion = null; |
/** |
* Constructeur par défaut, appelé à l'initialisation. |
*/ |
public function __construct() { |
// les différents paramètres nécessaires sont lus à partir du registre |
$this->registre = Registre::getInstance(); |
$this->abstraction = strtolower(Config::get('bdd_abstraction')); |
$this->type = Config::get('bdd_protocole'); |
$this->hote = Config::get('bdd_serveur'); |
$this->bdd_nom = Config::get('bdd_nom'); |
$this->utilisateur = Config::get('bdd_utilisateur'); |
$this->pass = Config::get('bdd_mot_de_passe'); |
$this->encodage = Config::get('bdd_encodage'); |
$this->dsn = $this->type.':dbname='.$this->bdd_nom.';host='.$this->hote; |
$this->initialiserProtocole(); |
} |
/** |
* Connection à la base de données en utilisant les informations fournies par |
* le fichier de configuration. |
* private et final car n'a pas vocation a être appelée par l'utilisateur. |
* |
* @throws Exception une exception dans le cas ou là connexion échoue |
*/ |
final private function connecter() { |
switch ($this->abstraction) { |
case 'pdo': |
$this->connexion = new PDO($this->dsn, $this->utilisateur, $this->pass); |
break; |
case 'mysql': |
$this->connexion = mysql_connect($this->hote,$this->utilisateur,$this->pass); |
if ($this->connexion != null) { |
mysql_select_db($this->bdd_nom, $this->connexion); |
} else { |
throw new Exception('Erreur de connexion à la base de données, vérifiez les paramètres du fichier de configuration'); |
} |
break; |
case 'mysqli': |
$this->connexion = new mysqli($this->hote,$this->utilisateur,$this->pass, $this->bdd_nom); |
if (!$this->connexion) { |
throw new Exception('Erreur de connexion à la base de données, vérifiez les paramètres du fichier de configuration'); |
return; |
} |
break; |
case 'sqlite3': |
// cas particulier de sqllite, on considère que le nom de la base de données correspond au fichier à ouvrir |
$this->connexion = new SQLite3($this->bdd_nom); |
if (!$this->connexion) { |
throw new Exception('Erreur de connexion à la base de données, vérifiez les paramètres du fichier de configuration'); |
return; |
} |
break; |
default: |
$this->connexion = null; |
} |
if ($this->encodage != null) { |
$this->requete("SET names '".$this->encodage."'"); |
} |
} |
/** |
* Fonction qui appelle la bonne fonction pour executer une requête suivant le type de bdd. |
* |
* @param string la requete à effectuer |
* @return PDOStatement un objet contenant le résultat de la requête |
*/ |
final protected function requete($requete) { |
// on ne se connecte que lors du premier appel à une requete (lazy connexion) |
if ($this->connexion == null) { |
$this->connecter(); |
} |
$retour = null; |
switch ($this->abstraction) { |
case 'pdo': |
$retour = $this->connexion->query($requete); |
break; |
case 'mysql': |
$retour = mysql_query($requete,$this->connexion); |
break; |
case 'mysqli': |
$retour = $this->connexion->query($requete); |
break; |
case 'sqlite3': |
$retour = $this->connexion->exec($requete); |
break; |
} |
return $retour; |
} |
final protected function requeteUn($requete,$mode = 'ASSOC') { |
// Connection seulement lors du premier appel à une requete (lazy connexion) |
if ($this->connexion == null) { |
$this->connecter(); |
} |
$retour = null; |
switch ($this->abstraction) { |
case 'pdo': |
try { |
$res_req = $this->connexion->query($requete); |
$retour =$res_req->fetch($this->$mode); |
} catch (PDOException $e) { |
$message = 'Requête echec. Fichier : "%s". Ligne : "%s". Message : %s'; |
trigger_error(sprintf($message, $e->getFile(), $e->getLine(), $e->getMessage()), E_USER_WARNING); |
} |
break; |
case 'mysql': |
$res = mysql_query($requete,$this->connexion); |
$fonction_fetch = $this->$mode; |
$retour = $fonction_fetch($res); |
break; |
case 'mysqli': |
$res = $this->connexion->query($requete); |
$fonction_fetch = $this->$mode; |
$retour = $res->$fonction_fetch(); |
break; |
case 'sqlite3': |
$retour = $this->connexion->querySingle($requete); |
break; |
} |
return $retour; |
} |
final protected function requeteTous($requete,$mode = 'ASSOC') { |
// Connexion seulement lors du premier appel à une requete (lazy connexion) |
if ($this->connexion == null) { |
$this->connecter(); |
} |
$retour = null; |
switch ($this->abstraction) { |
case 'pdo': |
try { |
$res_req = $this->connexion->query($requete); |
if ($res_req !== false) { |
$retour = $res_req->fetchAll($this->$mode); |
} else { |
$retour = false; |
} |
} catch (PDOException $e) { |
$message = 'Requête echec. Fichier : "%s". Ligne : "%s". Message : %s'; |
trigger_error(sprintf($message, $e->getFile(), $e->getLine(), $e->getMessage()), E_USER_WARNING); |
} |
break; |
case 'mysql': |
$res = mysql_query($requete, $this->connexion); |
$fonction_fetch = $this->$mode; |
while ($ligne = $fonction_fetch($res)) { |
$retour[] = $ligne; |
} |
break; |
case 'mysqli': |
$res = $this->connexion->query($requete); |
$function_fetch = $this->$mode; |
while ($ligne = $res->$function_fetch()) { |
$retour[] = $ligne; |
} |
break; |
case 'sqlite3': |
$res = $this->connexion->query($requete); |
while ($ligne = $res->fetch_array($this->ASSOC)) { |
if ($mode == $this->ASSOC) { |
$retour[] = $ligne; |
} elseif ($mode == $this->OBJECT) { |
// cas particulier de sqllite |
// qui n'a pas de fonction fetch_object |
$ligneObjet = new stdClass(); |
foreach ($ligne as $colonne => $valeur) { |
$ligneObjet->$colonne = $valeur; |
} |
$retour[] = $ligneObjet; |
} |
} |
break; |
} |
return $retour; |
} |
/** |
* protège une chaine de caractères avant l'insertion dans la base de données |
*/ |
final protected function proteger($chaine) { |
// on ne se connecte que lors du premier appel à une requete |
if ($this->connexion == null) { |
$this->connecter(); |
} |
$retour = $chaine; |
switch ($this->abstraction) { |
case 'pdo': |
$retour = $this->connexion->quote($chaine); |
break; |
case 'mysql': |
$retour = '"'.mysql_real_escape_string($chaine, $this->connexion).'"'; |
break; |
case 'mysqli': |
$retour = '"'.$this->connexion->real_escape_string($chaine).'"'; |
break; |
case 'sqlite3': |
$retour = $this->connexion->escapeString($chaine); |
break; |
} |
return $retour; |
} |
/** |
* initialise les constantes de classe à leur bonne valeur |
* et lance une exception si le protocole n'est pas bien défini |
* @throws Exception |
*/ |
final public function initialiserProtocole() { |
switch ($this->abstraction) { |
case 'pdo': |
$this->ASSOC = PDO::FETCH_ASSOC; |
$this->OBJECT = PDO::FETCH_CLASS; |
break; |
case 'mysql': |
$this->ASSOC = 'mysql_fetch_assoc'; |
$this->OBJECT = 'mysql_fetch_object'; |
break; |
case 'mysqli': |
$this->ASSOC = 'fetch_assoc'; |
$this->OBJECT = 'fetch_object'; |
break; |
case 'sqlite3': |
$this->ASSOC = 'SQLITE3_ASSOC'; |
$this->OBJECT = 'SQLITE3_OBJECT'; |
break; |
default: |
throw new Exception('Erreur : l\'abstraction '.$this->abstraction.' n\'est pas prise en charge'); |
break; |
} |
} |
/** |
* Destructeur de classe, se contente de fermer explicitement la connexion |
*/ |
final public function __destruct() { |
switch ($this->abstraction) { |
case 'pdo': |
$this->connexion = null; |
break; |
case 'mysql': |
return mysql_close($this->connexion); |
break; |
case 'mysqli': |
$this->connexion->close(); |
break; |
case 'sqlite3': |
$this->connexion->close(); |
break; |
} |
} |
} |
?> |
Property changes: |
Added: svn:keywords |
+Id Author Date Revision HeadURL |
\ No newline at end of property |
/branches/v1.0-adhemar/framework/Debug.php |
---|
New file |
0,0 → 1,123 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Classe fournissant des fonctions de débogage équivalante à var_dump et print_r. |
* L'affichage et l'utilisation de ces fonctions sont améliorés via cette classe. |
* Cette classe est inspirée de la classe Zend_Debug. |
* |
* PHP version 5 |
* |
* @category Debogage |
* @package Framework |
// Auteur principal : |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
// Autres auteurs : |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $$Id$$ |
* @copyright 1999-2009 Tela Botanica (accueil@tela-botanica.org) |
*/ |
class Debug { |
/** |
* mode de php (cli ou sapi) |
*/ |
protected static $mode = null; |
/** |
* Accesseur pour le mode |
* @return string le mode de php |
*/ |
public static function getMode() { |
if (self::$mode === null) { |
self::$mode = PHP_SAPI; |
} |
return self::$mode; |
} |
/** |
* Equivalent de var_dump |
* @param mixed $variable la variable à dumper |
* @param string $mot_cle le mot cle à associer à la variable |
* @param boolean $echo si true on affiche le résultat, si false on ne renvoie que la chaine sans l'afficher |
* @return string la chaine à afficher representant le dump ou null si echo |
*/ |
public static function dump($variable, $mot_cle = null, $echo = true) { |
// var_dump de la variable dans un buffer et récupération de la sortie |
ob_start(); |
var_dump($variable); |
$sortie = ob_get_clean(); |
// Pré-traitement de la sortie |
$sortie = preg_replace("/\]\=\>\n(\s+)/m", "] => ", $sortie); |
// Traitement général du débogage |
return self::traiterDebogage($mot_cle, $sortie, $echo); |
} |
/** |
* Equivalent de print_r |
* @param mixed $variable la variable à afficher |
* @param string $mot_cle le mot cle à associer |
* @param boolean $echo faire un echo ou non |
* @return string la chaine contenant la variable printée ou null si echo |
*/ |
public static function printr($variable, $mot_cle = null, $echo = true) { |
// Récupération de la sortie |
$sortie = print_r($variable, true); |
// Traitement général du débogage |
return self::traiterDebogage($mot_cle, $sortie, $echo); |
} |
/** |
* Traite une chaine de débogage et les mots clés associés |
* @param string $mot_cle le mot à associer à la chaine |
* @param string $sortie le chaine de debogage |
* @param boolean $echo faire un echo du resultat ou non |
* @return string la chaine de debogage formatée ou bien null si echo |
*/ |
private static function traiterDebogage($mot_cle, $sortie, $echo) { |
// Formate le mot-clé |
$mot_cle = self::formaterMotCle($mot_cle); |
// Traitement de la sortie |
$sortie = self::traiterSortieSuivantMode($mot_cle, $sortie); |
// Affichage et/ou retour |
if (Config::get('fw_debogage') == true) { |
if ($echo) { |
echo $sortie; |
return null; |
} else { |
return $sortie; |
} |
} |
} |
/** |
* formate un mot clé donné |
* @param string $mot_cle le mot clé à formaté |
* @return string le mot clé formaté ou bien un chaine vide le mot clé est null ou vide |
*/ |
private static function formaterMotCle($mot_cle) { |
return ($mot_cle === null) ? '' : rtrim($mot_cle).' '; |
} |
/** |
* traite la sortie de la chaine de débogage suivant le mode de php |
* @param string $mot_cle le mot clé associé à la chaine |
* @param string $sortie la chaine de débogage |
* @return string la sortie formatée pour le mode en cours |
*/ |
private static function traiterSortieSuivantMode($mot_cle, $sortie) { |
$corps = $mot_cle.PHP_EOL.$sortie; |
if (self::getMode() == 'cli') { |
$sortie = PHP_EOL.$corps.PHP_EOL; |
} else { |
$sortie = '<pre>'.$corps.'</pre>'; |
} |
return $sortie; |
} |
} |
?> |
Property changes: |
Added: svn:keywords |
+Id Author Date Revision HeadURL |
\ No newline at end of property |
/branches/v1.0-adhemar/framework/GestionnaireException.php |
---|
New file |
0,0 → 1,192 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Classe de gestion des exceptions. |
* C'est un Singleton. |
* |
* PHP Version 5 |
* |
* @category Class |
* @package Framework |
* @author aurelien <aurelien@tela-botanica.org> |
* @copyright 2009 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$$ |
* @link /doc/framework/ |
* |
*/ |
class GestionnaireException { |
/** |
* Liste des exceptions enregistrées |
*/ |
private static $exceptions = array(); |
/** |
* Détermine si l'on affiche ou non le contexte |
*/ |
private static $contexte = false; |
/** |
* Détermine si l'on loggue ou non les erreurs |
*/ |
private static $logger = false; |
/** |
* Détermine si l'on loggue ou non les erreurs |
*/ |
private static $afficher = false; |
/** |
* Definit si php est lancé en ligne de commande ou en mode serveur |
*/ |
private static $mode = null ; |
/** |
* le gestionnaire d'exception est un singleton |
* et possède donc un "pointeur statique sur lui-même" |
*/ |
private static $gestionnaireException; |
/** |
* Constructeur avec paramètres optionnel |
* @param bool indique si l'on veut afficher ou non le contexte des exceptions (i.e. la trace) |
*/ |
public function __construct() { |
self::$exceptions = array(); |
self::$contexte = Config::get('fw_debogage_contexte'); |
self::$logger = Config::get('fw_log_debogage'); |
self::$afficher = Config::get('fw_debogage'); |
self::$mode = php_sapi_name(); |
set_exception_handler(array(get_class($this),'gererException')); |
set_error_handler(array(get_class($this),'gererErreur')); |
} |
/** |
* Renvoie le booleen définissant si l'on affiche le contexte ou non |
*/ |
public static function getContexte() { |
return self::$contexte; |
} |
/** |
* Definit si l'on veut afficher le contexte ou non |
* @param bool true si on veut afficher le contexte, false sinon, par défaut vaut false |
*/ |
public static function setContexte($contexte) { |
self::$contexte = $contexte; |
} |
/** Fonction d'accès au singleton |
* @return GestionnaireErreur le gestionnaire d'exceptions courant |
*/ |
public static function getInstance() { |
if (self::$gestionnaireException instanceof GestionnaireException) { |
return self::$gestionnaireException; |
} |
self::$gestionnaireException = new GestionnaireException; |
return self::$gestionnaireException; |
} |
/** |
* Fonction de gestion des exceptions, remplace le handler par défaut |
* @param Exception $e l'exception à traiter |
*/ |
public static function gererException(Exception $e) { |
// pour le moment on se contente de l'ajouter au tableau et de les afficher |
self::$exceptions[] = $e; |
// si on doit logger on envoie l'exception au loggeur |
if (self::$logger) { |
self::loggerException($e); |
} |
} |
/** |
* Gère les erreurs en les convertissant en exceptions (remplace la fonction gestion d'erreurs native de php) |
* @param int $niveau le niveau de l'erreur |
* @param string $message le message associé à l'erreur |
* @param string $fichier le nom du fichier où l'erreur s'est produite |
* @param int $ligne la ligne où l'erreur s'est produite |
* @param string $contexte le contexte associé à l'erreur |
*/ |
public static function gererErreur($niveau, $message, $fichier, $ligne, $contexte){ |
// si aucun rapport d'erreur, on sort directement |
if (error_reporting() == 0) { |
return; |
} |
// sinon on crée une exception |
$e = new ErrorException($message, 0, $niveau, $fichier, $ligne); |
// que l'on donne au tableau d'exceptions |
self::$exceptions[] = $e; |
// on la logge si nécéssaire |
if (self::$logger) { |
self::loggerException($e); |
} |
return; |
} |
/** |
* Renvoie les exceptions au format (X)HTML |
* ou bien au format texte suivant le mode d'utilisation de PHP |
*/ |
public static function getExceptions() { |
$retour = ''; |
foreach (self::$exceptions as $cle => $e) { |
switch (self::$mode) { |
case 'cli' : |
$retour .= $e->getMessage()."\n"; |
$retour .= 'Fichier : '.$e->getFile()."\n"; |
$retour .= 'Ligne : '.$e->getLine()."\n"; |
if (self::getContexte()) { |
$retour .= 'Contexte : '."\n".print_r($e->getTraceAsString(), true)."\n"; |
} |
break; |
default: |
$retour .= '<pre class="debogage">'."\n"; |
$retour .= $e->getMessage()."\n"; |
$retour .= '<span class="debogage_fichier">'.'Fichier : '.$e->getFile().'</span>'."\n"; |
$retour .= '<span class="debogage_ligne">'.'Ligne : '.$e->getLine().'</span>'."\n"; |
$retour .= '</pre>'."\n"; |
if (self::getContexte()) { |
$retour .= '<pre>'."\n"; |
$retour .= '<strong>Contexte : </strong>'."\n".print_r($e->getTraceAsString(), true)."\n"; |
$retour .= '</pre>'."\n"; |
} |
} |
// Nous vidons le tableau des exceptions au fur et à mesure |
unset(self::$exceptions[$cle]); |
} |
return $retour; |
} |
/** |
* logge une exception donnée sous une forme lisible |
* @param Exception $e l'exception à logger |
*/ |
private static function loggerException($e) { |
$erreur = ''; |
$erreur .= $e->getMessage()."\n"; |
$erreur .= 'Fichier : '.$e->getFile()."\n"; |
$erreur .= 'Ligne : '.$e->getLine()."\n"; |
if (self::getContexte()) { |
$erreur .= 'Contexte : '."\n".print_r($e->getTraceAsString(), true)."\n"; |
} |
$erreur .= "\n"; |
Log::ajouterEntree('erreurs',$erreur); |
} |
public function __destruct() { |
// Si des erreurs n'ont pas été affichée nous forçons leur affichage |
if (self::$afficher && count(self::$exceptions) > 0) { |
echo self::getExceptions(); |
} |
} |
} |
?> |
Property changes: |
Added: svn:keywords |
+Id Author Date Revision HeadURL |
\ No newline at end of property |
/branches/v1.0-adhemar/framework/. |
---|
New file |
Property changes: |
Added: svn:ignore |
+config.ini |