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.

144 lines
3.5 KiB

  1. <?php
  2. /**
  3. * Класс для работы с роутерами
  4. *
  5. * @copyright
  6. * @link
  7. * @package Majestic
  8. * @subpackage Core
  9. * @since
  10. * @version SVN: $Id$
  11. * @filesource $URL$
  12. */
  13. final class Router
  14. {
  15. protected $routes = array();
  16. static protected $rewrite_base = '';
  17. static protected $decorator = DEFAULT_DECORATOR;
  18. static protected $route_name = '';
  19. /**
  20. * Добавить роутер
  21. *
  22. * @param string $name - имя роутера
  23. * @param string $path - путь
  24. * @param string $action - имя действия
  25. * @param array $params - массив параметров
  26. */
  27. function add($name, $path, $action, $params = array())
  28. {
  29. $this->routes[$name] = new Route($path, $action, $params);
  30. $this->routes[$name]->decorator = self::$decorator;
  31. }
  32. /**
  33. * Установить декоратор для роута (действия), отличный от стандартного
  34. *
  35. * @param string $name - имя роута (действия)
  36. * @param string $decorator - имя декоратора
  37. */
  38. function setDecorator($name, $decorator)
  39. {
  40. if (isset($this->routes[$name])) {
  41. $this->routes[$name]->decorator = $decorator.DECORATOR_POSTFIX;
  42. }
  43. }
  44. /**
  45. * Найти роутер соответствующий заданному пути
  46. *
  47. * @param stirng $path - путь
  48. * @return Route - роутер
  49. */
  50. function proccess($path)
  51. {
  52. if(self::getRewriteBase()){
  53. $path = trim(ltrim($path, self::getRewriteBase()), '/');
  54. }
  55. $path = explode('/', $path);
  56. foreach($this->routes as $name => $route) {
  57. if ($route->match($path)) {
  58. $route->action .= ACTION_POSTFIX;
  59. Env::setParams($route->params);
  60. self::$route_name = $name;
  61. return $route;
  62. }
  63. }
  64. throw new Exception(E_404);
  65. }
  66. static public function setRewriteBase($value = '')
  67. {
  68. self::$rewrite_base = $value;
  69. }
  70. static public function getRewriteBase()
  71. {
  72. return self::$rewrite_base;
  73. }
  74. static public function setDefaultDecorator($decorator)
  75. {
  76. self::$decorator = $decorator.DECORATOR_POSTFIX;
  77. }
  78. static public function getRouteName()
  79. {
  80. return self::$route_name;
  81. }
  82. }
  83. /**
  84. * Роутер
  85. *
  86. */
  87. final class Route
  88. {
  89. const URL_VARIABLE = '&';
  90. protected $path;
  91. public $decorator = DEFAULT_DECORATOR;
  92. public $action;
  93. public $params;
  94. function __construct($path, $action, $params=array())
  95. {
  96. $this->path = $path;
  97. $this->action = $action;
  98. $this->params = $params;
  99. }
  100. /**
  101. * Проверяет соответствие роутера и пути
  102. *
  103. * @param string $path - путь для сравнения
  104. * @return boolean - соответствует или нет
  105. */
  106. function match($path_arr)
  107. {
  108. $parts = explode('/', $this->path);
  109. $cnt = count($parts);
  110. if (end($parts) == self::URL_VARIABLE) {
  111. $cnt--;
  112. } elseif ($cnt != count($path_arr)) {
  113. return false;
  114. }
  115. for ($i=0; $i<$cnt; $i++) {
  116. if (substr($parts[$i], 0, 1) == self::URL_VARIABLE) {
  117. $this->params[substr($parts[$i], 1)] = $path_arr[$i];
  118. } elseif ($parts[$i] != $path_arr[$i]) {
  119. return false;
  120. }
  121. }
  122. return true;
  123. }
  124. }
  125. ?>