A free, self-hostable aggregator…
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

152 lines
3.5 KiB

<?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
));
}
}
}