Subversion Repositories eFlore/Applications.moissonnage

Rev

Blame | Last modification | View Log | RSS feed

<?php
// In : utf8 url_encoded (get et post)
// Out : utf8
/**
 * La classe Widget analyser l'url et chage le widget correspondant.
 * Format d'url :
 * /widget/nom_du_widget?parametres1=ma_valeur1&parametre2=ma_valeur2
 * Les widget sont dans des dossiers en minuscule correspondant au nom de la classe du widget.
 * Exemple : /widget/carto avec la classe Carto.php dans le dossier carto.
 *
 * 
 * @author jpm
 *
 */
class Widget {

        /** Les paramètres de configuration extrait du fichier .ini */
    private static $config;

        /** Le nom du widget demandé. */
        private $widget = null;
        
        /** Les chemins où l'autoload doit chercher des classes. */
        private static $autoload_chemins = array();
        
        /** Les paramètres de l'url $_GET nettoyés. */
        private $parametres = null;

        /**
         * Constructeur.
         * Parse le fichier de configuraion "widget.ini" et parse l'url à la recherche du widget demandé.
         * @param str iniFile Configuration file to use
         */
        public function __construct($fichier_ini = 'widget.ini.php') {
                // Chargement de la configuration
                self::$config = parse_ini_file($fichier_ini, TRUE);
                
                // Paramêtres de config dynamiques
                self::$config['chemins']['baseURLAbsoluDyn'] = 'http://'.$_SERVER['SERVER_NAME'].self::$config['chemins']['baseURL'].'%s';
                
                // Gestion de la mémoire maximum allouée aux services
                ini_set('memory_limit', self::$config['parametres']['limiteMemoire']);
                
                // Réglages de PHP
                setlocale(LC_ALL, self::$config['parametres']['locale']);
                date_default_timezone_set(self::$config['parametres']['fuseauHoraire']);
                
                // Gestion des erreurs
                error_reporting(self::$config['parametres']['erreurNiveau']);
                
                if (isset($_SERVER['REQUEST_URI']) && isset($_SERVER['QUERY_STRING'])) {
                        $url_morceaux = $this->parserUrl();
                        if (isset($url_morceaux[0])) {
                                $this->widget = strlen($url_morceaux[0]) == 0 ? $url_morceaux[1] : $url_morceaux[0];
                                self::$config['chemins']['widgetCourantDossier'] = self::$config['chemins']['widgetsDossier'].strtolower($this->widget).DIRECTORY_SEPARATOR;
                                $this->chargerWidgetConfig();
                        }
                        // Chargement des chemins pour l'autoload
                        $this->chargerCheminAutoload();
                        
                        // Enregistrement de la méthode gérant l'autoload des classes
                        spl_autoload_register(array('Widget', 'chargerClasse'));
                        
                        // Nettoyage du $_GET (sécurité)
                        $this->collecterParametres();
                } else {
                        $e = 'Les widget nécessite les variables serveurs suivantes pour fonctionner : REQUEST_URI et QUERY_STRING.';
                        trigger_error($e, E_USER_ERROR);
                }
        }
        
        private function parserUrl() {
                if (strlen($_SERVER['QUERY_STRING']) == 0) {
                        $len = strlen($_SERVER['REQUEST_URI']);
                } else {
                        $len = -(strlen($_SERVER['QUERY_STRING']) + 1);
                }
                $url = substr($_SERVER['REQUEST_URI'], strlen(self::$config['chemins']['baseURL']), $len);
                $url_morceaux = explode('/', $url);
                return $url_morceaux;
        }
        
        private function collecterParametres() {
                if (isset($_GET) && $_GET != '') {
                        $this->nettoyerGet();
                        $this->parametres = $_GET;
                }
        }
        
        private function nettoyerGet() {
                foreach ($_GET as $cle => $valeur) {
                        $verifier = array('NULL', "\n", "\r", "\\", '"', "\x00", "\x1a", ';');
                        $_GET[$cle] = strip_tags(str_replace($verifier, '', $valeur));
                }
        }
        
        private function chargerCheminAutoload() {
                $chemins_communs = explode(';', self::$config['chemins']['autoload']);
                $chemins_communs = array_map('trim', $chemins_communs);
                array_unshift($chemins_communs, '');
                
                $chemins_widget = array();
                if (isset(self::$config[$this->widget]['autoload'])) {
                        $chemins_widget = explode(';', self::$config[$this->widget]['autoload']);
                        foreach ($chemins_widget as $cle => $chemin) {
                                $chemins_widget[$cle] = self::$config['chemins']['widgetCourantDossier'].trim($chemin);
                        }
                }
                
                self::$autoload_chemins = array_merge($chemins_communs, $chemins_widget);
        }
        
        /**
        * La méthode chargerClasse() charge dynamiquement les classes trouvées dans le code.
        * Cette fonction est appelée par php5 quand il trouve une instanciation de classe dans le code.
        *
        *@param string le nom de la classe appelée.
        *@return void le fichier contenant la classe doit être inclu par la fonction.
        */
        public static function chargerClasse($classe) {
                if (class_exists($classe)) {
                        return null;
                }
                foreach (self::$autoload_chemins as $chemin) {
                        $chemin = $chemin.$classe.'.php';
                        if (file_exists($chemin)) {
                                require_once $chemin;
                        }
                }
        }
        
        
        /**
         * Execute le widget.
         */
        function executer() {
                if (!is_null($this->widget)) {
                        $classe_widget = ucfirst($this->widget);
                        $fichier_widget = self::$config['chemins']['widgetCourantDossier'].$classe_widget.'.php';
                        if (file_exists($fichier_widget))  {
                                include_once $fichier_widget;
                                if (class_exists($classe_widget)) {
                                        $widget = new $classe_widget(self::$config, $this->parametres);
                                        $widget->executer();
                                }
                        }
                }
        }
        
        /**
         * Charge le fichier de config spécifique du wiget et fusionne la config avec celle partagés par l'ensemble des widgets.
         */
        private function chargerWidgetConfig() {
                $widget_config_ini_fichier = self::$config['chemins']['widgetCourantDossier'].'config.ini';
                if (file_exists($widget_config_ini_fichier))  {
                        $widget_config = parse_ini_file($widget_config_ini_fichier, TRUE);
                        self::$config = array_merge(self::$config, $widget_config);
                }
        }
}
?>