diff options
Diffstat (limited to 'lib/minz/Dispatcher.php')
| -rw-r--r-- | lib/minz/Dispatcher.php | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/lib/minz/Dispatcher.php b/lib/minz/Dispatcher.php new file mode 100644 index 000000000..9d08c142b --- /dev/null +++ b/lib/minz/Dispatcher.php @@ -0,0 +1,152 @@ +<?php +/** + * MINZ - Copyright 2011 Marien Fressinaud + * Sous licence AGPL3 <http://www.gnu.org/licenses/> +*/ + +/** + * Le Dispatcher s'occupe d'initialiser le Controller et d'executer l'action + * déterminée dans la Request + * C'est un singleton + */ +class Dispatcher { + const CONTROLLERS_PATH_NAME = '/controllers'; + + /* singleton */ + private static $instance = null; + + private $router; + private $controller; + + /** + * Récupère l'instance du Dispatcher + */ + public static function getInstance ($router) { + if (is_null (self::$instance)) { + self::$instance = new Dispatcher ($router); + } + return self::$instance; + } + + /** + * Constructeur + */ + private function __construct ($router) { + $this->router = $router; + } + + /** + * Lance le controller indiqué dans Request + * Remplit le body de Response à partir de la Vue + * @exception MinzException + */ + public function run () { + $cache = new Cache(); + // Le ob_start est dupliqué : sans ça il y a un bug sous Firefox + // ici on l'appelle avec 'ob_gzhandler', après sans. + // Vraisemblablement la compression fonctionne mais c'est sale + // J'ignore les effets de bord :( + ob_start ('ob_gzhandler'); + + if (Cache::isEnabled () && !$cache->expired ()) { + ob_start (); + $cache->render (); + $text = ob_get_clean(); + } else { + while (Request::$reseted) { + Request::$reseted = false; + + try { + $this->createController ( + Request::controllerName () + . 'Controller' + ); + + $this->controller->init (); + $this->controller->firstAction (); + $this->launchAction ( + Request::actionName () + . 'Action' + ); + $this->controller->lastAction (); + + if (!Request::$reseted) { + ob_start (); + $this->controller->view ()->build (); + $text = ob_get_clean(); + } + } catch (MinzException $e) { + throw $e; + } + } + + if (Cache::isEnabled ()) { + $cache->cache ($text); + } + } + + Response::setBody ($text); + } + + /** + * Instancie le Controller + * @param $controller_name le nom du controller à instancier + * @exception FileNotExistException le fichier correspondant au + * > controller n'existe pas + * @exception ControllerNotExistException le controller n'existe pas + * @exception ControllerNotActionControllerException controller n'est + * > pas une instance de ActionController + */ + private function createController ($controller_name) { + $filename = APP_PATH . self::CONTROLLERS_PATH_NAME . '/' + . $controller_name . '.php'; + + if (!file_exists ($filename)) { + throw new FileNotExistException ( + $filename, + MinzException::ERROR + ); + } + require_once ($filename); + + if (!class_exists ($controller_name)) { + throw new ControllerNotExistException ( + $controller_name, + MinzException::ERROR + ); + } + $this->controller = new $controller_name ($this->router); + + if (! ($this->controller instanceof ActionController)) { + throw new ControllerNotActionControllerException ( + $controller_name, + MinzException::ERROR + ); + } + } + + /** + * Lance l'action sur le controller du dispatcher + * @param $action_name le nom de l'action + * @exception ActionException si on ne peut pas exécuter l'action sur + * > le controller + */ + private function launchAction ($action_name) { + if (!Request::$reseted) { + if (!is_callable (array ( + $this->controller, + $action_name + ))) { + throw new ActionException ( + get_class ($this->controller), + $action_name, + MinzException::ERROR + ); + } + call_user_func (array ( + $this->controller, + $action_name + )); + } + } +} |
