<?PHP
class Router {
private static
$defined = false, // shows if controller and action was already set
$args = array(), // contains arguments passed through request
$args_keys = array(), // contains names of arguments passed through request
$args_values = array(), // contains values of arguments passed through request
$routes = array(), // contains named routes
$link_args = array(); // contains arguments sent to a get_link method
private function __construct() {
// nothing to do here
}
// sets GET route
static public function GET($path, $route, $name) {
self::add_route($path, $name);
self::request ($path, $route, 'GET');
}
// sets POST route
static public function POST($path, $route, $name) {
self::add_route($path, $name);
self::request ($path, $route, 'POST');
}
// sets home route
static public function HOME($route, $name) {
self::GET('/', $route, $name);
}
// sets default route
static public function SET($route) {
if ( self::$defined )
return;
self::define_route($route);
}
// returns args passed through request
static public function args() {
return self::$args;
}
// returns named link
static public function get_link($name, $args = array()) {
if ( !isset(self::$routes[$name]) )
die("Router: route with name `$name` not found.");
$path = self::$routes[$name];
self::$link_args = $args;
return $url.preg_replace_callback('#/:([^/]+)#iu', 'self::link_gen', $path);
}
private static function link_gen($matches) {
return '/'.array_shift(self::$link_args);
}
// handles request
static private function request($path, $route, $method) {
if ( self::$defined )
return;
$path = rtrim($path,'/');
$request = preg_replace('#(\?.*)#','',$_SERVER['REQUEST_URI']);
$request = rtrim($request,'/');
$modified_path = preg_replace('#/:([^/]+)#iu','/([^/]+)',$path);
if ( preg_match("#^$modified_path$#iu", $request) && $_SERVER['REQUEST_METHOD'] == $method ) {
self::define_args($path, $request);
self::define_route($route);
}
}
// adds named route
static private function add_route($path, $name) {
if ( !preg_match('#^[a-z_][a-z0-9_]*$#iu',$name) )
die("Router: route name should contain only letters, numbers and underscores and should not start with a number. You've endered: `$name`.");
self::$routes[$name] = $path;
}
// extracts args from request
static private function define_args($path, $route) {
$modified_path = preg_replace('#/:([^/]+)#iu','/:([^/]+)',$path);
$modified_route = preg_replace('#/:([^/]+)#iu','/([^/]+)',$path);
preg_replace_callback("#^$modified_path$#", 'self::set_keys', $path);
preg_replace_callback("#^$modified_route$#", 'self::set_values', $route);
if ( count(self::$args_keys) )
self::$args = array_combine(self::$args_keys,self::$args_values);
else
self::$args = array();
}
static private function set_keys($matches) {
array_shift($matches);
self::$args_keys = $matches;
}
static private function set_values($matches) {
array_shift($matches);
self::$args_values = $matches;
}
// sets controller and action for matched route
static private function define_route($route) {
list($controller, $action) = explode('#', $route);
if ( !defined('controller') && !defined('action') ) {
define('controller', $controller);
define('action', $action);
}
self::$defined = true;
}
}