ACC SHELL
<?php
class Router {
public static $routes = array(self::PRIORITY_HIGH => array(), self::PRIORITY_NORMAL => array(), self::PRIORITY_LOW => array());
private static $method; // ROUTE/REDIRECT
public static $source; // Source that provided the route scanned. This is recorded along with router::add() when the route is passed in hook_routes().
private static $pattern; // Matching pattern
private static $ctrl; // Matching controller after preg_replace()
public static $found = false; // Is item found?
private static $scanned = FALSE; // Flag for scanning routes
const ROUTE_PCRE = 0; // Route uses PCRE
const ROUTE_STATIC = 1; // Route is static
const REDIRECT_PCRE = 2; // Redirect using PCRE
const REDIRECT_STATIC = 3; // Redirect with literal strings
const PRIORITY_HIGH = 0; // High priority route, used for "emergency" pages or redirects
const PRIORITY_NORMAL = 1; // Normal priority route, this is the most common
const PRIORITY_LOW = 2; // Low priority route, used for special 404s or very generic routes (pages)
public function __construct() { }
private static function scan($force = FALSE) {
$found = FALSE;
if (!self::$scanned || $force) {
foreach (self::$routes as $priority => $routes) {
if ($found) { break; }
foreach ($routes as $route) {
if ($found) { break; }
unset($ctrl, $redirect);
list($pattern, $replacement, $method, $source) = $route;
switch ($method) {
case self::ROUTE_STATIC: if (URI_PATH === $pattern) { $ctrl = $replacement; } break;
case self::ROUTE_PCRE: if (preg_match($pattern, URI_PATH)) { $ctrl = preg_replace($pattern, $replacement, URI_PATH); } break;
case self::REDIRECT_STATIC: if (URI_PATH === $pattern) { $redirect = $replacement; } break;
case self::REDIRECT_PCRE: if (preg_match($pattern, URI_PATH)) { $redirect = preg_replace($pattern, $replacement, URI_PATH); } break;
}
if (isset($ctrl) || isset($redirect)) {
if (isset($ctrl) && is_readable($ctrl)) {
self::$pattern = $pattern;
self::$ctrl = $ctrl;
self::$method = $method;
self::$source = $source;
$found = TRUE;
}
}
}
}
if (!self::$ctrl && !isset($redirect) && substr(URI_PATH, -1) !== '/')
{
$redirect = URI_PATH.'/';
if (strlen(URI_PARAM)) { $redirect .= '?'.URI_PARAM; }
}
if (isset($redirect)) { header('Location: '.$redirect); exit; }
self::$scanned = !$force;
}
}
//}}}
//{{{ public static function controller($scan = FALSE)
/**
* Controller called for the matching route
* @return string
*/
public static function controller($scan = FALSE) { self::scan($scan); return self::$ctrl; }
//}}}
//{{{ public static function pattern($scan = FALSE)
/**
* Pattern of the matching route
* @return string
*/
public static function pattern($scan = FALSE) { self::scan($scan); return self::$pattern; }
//}}}
//{{{ public static function method($scan = FALSE)
/**
* @return int
*/
public static function method($scan = FALSE) { self::scan($scan); return self::$method; }
//}}}
//{{{ public static function source($scan = FALSE)
/**
* Gets the source that provided the matching route
* @return string|NULL
*/
public static function source($scan = FALSE) { self::scan($scan); return self::$source; }
//}}}
//{{{ public static function add($pattern, $ctrl, $route = Router::ROUTE_STATIC, $priority = Router::PRIORITY_NORMAL, $source = NULL)
/**
* Register a single route for the system
* If $route is router::ROUTE_PCRE, both $pattern and $ctrl can be in PCRE
* string format for pcre_replace(). if $route is router::ROUTE_STATIC then
* it will do a fast string compare to URI_PATH. $ctrl must always be an
* absolute filename.
*
* @return void
*/
public static function add($pattern, $ctrl, $source = NULL, $route = Router::ROUTE_STATIC, $priority = Router::PRIORITY_NORMAL) {
self::$routes[$priority][] = array($pattern, $ctrl, $route, $source);
}
//}}}
}
/**
* Router::add('/', DIR_CTRL.'/index.php');
* Router::add('#^/regex/(test1|test2|test3)/$#', DIR_CTRL.'/regex.php', Router::ROUTE_PCRE);
* Routes are added with the static method Router::add($pattern, $replacement)
* It is processed as preg_replace($pattern, $replace) in the router class, so
* use any style for $pattern. Though it would be best to use # for pattern
* delimiters and ${n} for the replacement string variables. To carry a string
* from the pattern, just put them in parentheses (). These are run in order,
* and first one that matches and has a readable controller file is used.
*
* PHP's preg_replace: http://php.net/preg_replace/
*
* examples:
*
* Router::add('#/#', DIR_CTRL.'index.php', Router::ROUTE_PCRE);
* sends index page to the index.php contoller
*
* Router::add('#/news/(archive|latest)/#', DIR_CTRL.'news.${1}.php', Router::ROUTE_PCRE);
* /news/archive/ goes to news.archive.php
*
* you can also do this
*
* Router::add('#/news/(archive|latest)/#', DIR_CTRL.'news/${1}.php', Router::ROUTE_PCRE);
* /news/archive/ goes to news/archive.php
*/
ACC SHELL 2018