Location: PHPKode > projects > GnomePHP > peec-GnomePHP-b5a360b/gnomephp/mvc/Dispatcher.php
<?php
namespace gnomephp\mvc;

use \gnomephp\mvc\router\Router,
\gnomephp\mvc\router\RouterParseException;

/**
 * The dispatcher is the entry point of where all gnomephp
 * applications will start.
 * 
 * @see gnomephp\mvc\Dispatcher.dispatch()
 * @author peec
 *
 */
class Dispatcher{
	/**
	 *
	 * Keeps the microtime of when dispatch() was initialized.
	 * @var float
	 */
	protected $startTime = 0;


	/**
	 * Router object.
	 *
	 * @var gnomephp\mvc\router\Router
	 */
	public $router = null;

	/**
	 * The active router rule.
	 * @var gnomephp\mvc\router\Rule
	 */
	public $activeRoute = null;


	/**
	 * Singleton instance of dispatcher when dispatch() method is run.
	 * @var gnomephp\mvc\Dispatcher
	 */
	static public $dispatcher = null;

	public function __construct(\gnomephp\mvc\router\Router $router){
		$this->router = $router;
	}

	/**
	 * Runs the router and tries to find a route.
	 * If we get
	 * @throws RouterException
	 */
	public function run(){

		$route = $this->router->route();

		if ($route === null){
			// no route object was returned
			throw new RouterException("404 - No application route was found for that URI path.", 404);
		}

		$route->setBaseNamespace(GNOME_APP_NS.'\controller');

		$controller = $route->getController();
		$action = $route->getMethod();

		// instantiate the controller class
		$page = new $controller();

		if (!method_exists($page, $action)){
			throw new RouterException("404 - No Route found for URL: ".self::getUrl().". Could not load Action.");
		}

		$this->activeRoute = $route;

		// invoke the action method with the route values
		$args = $route->getArguments();
			
		// Try security check.
		$this->securityCheck($page, $action);


		try{
			call_user_func_array(array($page, $action), array_values($args));
		}catch(\gnomephp\cache\CatchedCacheException $e){
			// Do nothing, this is totally OK.
		}
		// Delete data that should not be here anymore.
		// This is one time data that should be deleted.
		$session = new \gnomephp\Session();
		$session->delete('gnomephp.messages');
		$session->save();

	}

	/**
	 * Throws AccessException if user has no access.
	 * 
	 *
	 * @param object $page Controller object
	 * @param string $action String method
	 * @throws gnomephp\security\AccessException
	 */
	protected function securityCheck($page, $action){
		$refObject = new \ReflectionObject($page);

		// Lets do a security check if it does implement the Secure interface.
		if ($refObject->implementsInterface('gnomephp\security\Secure')){
				
			\gnomephp\doctrine\Doctrine::load();
				
			$ns = \gnomephp\security\Security::getSessionModelPath();
			$userSession = $ns::getValidSession($page->session->get(\gnomephp\security\Security::SECURITY_TOKEN), $ns);
				
			if (!$page->hasAccessTo($action, $userSession)){
				throw new \gnomephp\security\AccessException();
			}
		}
		unset($refObject);
	}

	/**
	 * Gets the amount of time since Router::route() was called.
	 */
	public function getRuntime(){
		return microtime(true) - self::$startTime;
	}


	/**
	 * Gets the current URL.
	 */
	static public function getUrl(){
		$len = strlen($_SERVER['SCRIPT_NAME']);

		$out =  substr($_SERVER['PHP_SELF'], $len, strlen($_SERVER['PHP_SELF']));
		if (!$out)$out = '/';

		return $out;
	}


	/**
	 * Returns the current dispatcher if dispatch() is run.
	 * @return gnomephp\mvc\Dispatcher
	 */
	static public function getInstance(){
		return self::$dispatcher;
	}

	/**
	 * Static method for normal runs.
	 * This is the absolute entry point of where your website php code starts.
	 * Do not change this if you do not know what you are doing.
	 */
	static public function dispatch(){
		session_start();

		// get the incoming request URI path
		$path = self::getUrl();

		// Setup router.
		$router = new Router($path, $_SERVER);
		$router->parse(file_get_contents(GNOME_APP_PATH.DIRECTORY_SEPARATOR.'config'. DIRECTORY_SEPARATOR . 'routes.conf'));

		self::$dispatcher = new Dispatcher($router);
		try{
				
			self::$dispatcher->run();
		}catch(\gnomephp\security\AccessException $e){
			$controller = new DispatcherController();
			$controller->redirect($controller->view->url->linkTo('Auth', 'login'));
		}catch(\Exception $e){
			// Send header.
			header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
			header('Status: 404 Not Found');

			// Deal with the error in a good way.
			// Create dispatcher controller.
			$errorExceptionHandlers = (array)\gnomephp\Configuration::get('application', 'errors');
			$controller = new DispatcherController();
			if ($e instanceof \gnomephp\mvc\RouterException || $e instanceof \gnomephp\AutoLoaderException){
				$method = 'routerException';
			}else{
				$method = 'index';
			}
			foreach($errorExceptionHandlers as $exName => $set){
				if ($e instanceof $exName){
					if (isset($set['backend'])){
						$ex = explode('.',$set['backend']);
						$c = $ex[0];
						$controller = new $c();
						$method = $ex[1];
						$controller->$method($e);
					}else{
						$controller->view->render($set['view']);
					}
					return;
				}
			}

			// Run controller / method.
			$controller->$method($e);

		}
	}

}
Return current item: GnomePHP