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.

140 lines
3.4 KiB

<?php
/**
* Класс для работы с роутерами
*
* @copyright
* @link
* @package Majestic
* @subpackage Core
* @since
* @version SVN: $Id$
* @filesource $URL$
*/
final class Router
{
protected $routes = array();
static protected $rewrite_base = '';
static protected $decorator = DEFAULT_DECORATOR;
/**
* Добавить роутер
*
* @param string $name - имя роутера
* @param string $path - путь
* @param string $action - имя действия
* @param array $params - массив параметров
*/
function add($name, $path, $action, $params = array())
{
$this->routes[$name] = new Route($path, $action, $params);
$this->routes[$name]->decorator = self::$decorator;
}
/**
* Установить декоратор для роута (действия), отличный от стандартного
*
* @param string $name - имя роута (действия)
* @param string $decorator - имя декоратора
*/
function setDecorator($name, $decorator)
{
if (isset($this->routes[$name])) {
$this->routes[$name]->decorator = $decorator.DECORATOR_POSTFIX;
}
}
/**
* Найти роутер соответствующий заданному пути
*
* @param stirng $path - путь
* @return Route - роутер
*/
function proccess($path)
{
if ($trim = self::getRewriteBase()) {
if (substr($path, 0 , strlen($trim)) == $trim) {
$path = substr($path, strlen($trim));
}
}
$path = explode('/', $path);
foreach($this->routes as $name => $route) {
if ($route->match($path)) {
$route->action .= ACTION_POSTFIX;
Env::setParams($route->params);
return $route;
}
}
throw new Exception(E_404);
}
static public function setRewriteBase($value = '')
{
self::$rewrite_base = $value;
}
static public function getRewriteBase()
{
return self::$rewrite_base;
}
static public function setDefaultDecorator($decorator)
{
self::$decorator = $decorator.DECORATOR_POSTFIX;
}
}
/**
* Роутер
*
*/
final class Route
{
const URL_VARIABLE = '&';
protected $path;
public $decorator = DEFAULT_DECORATOR;
public $action;
public $params;
function __construct($path, $action, $params=array())
{
$this->path = $path;
$this->action = $action;
$this->params = $params;
}
/**
* Проверяет соответствие роутера и пути
*
* @param string $path - путь для сравнения
* @return boolean - соответствует или нет
*/
function match($path_arr)
{
$parts = explode('/', $this->path);
$cnt = count($parts);
if (end($parts) == self::URL_VARIABLE) {
$cnt--;
} elseif ($cnt != count($path_arr)) {
return false;
}
for ($i=0; $i<$cnt; $i++) {
if (substr($parts[$i], 0, 1) == self::URL_VARIABLE) {
$this->params[substr($parts[$i], 1)] = $path_arr[$i];
} elseif ($parts[$i] != $path_arr[$i]) {
return false;
}
}
return true;
}
}
?>