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.

130 lines
3.3 KiB

  1. <?php
  2. /**
  3. * Класс для работы с роутерами
  4. *
  5. * @copyright NetMonsters <team@netmonsters.ru>
  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. $path = explode('/', $path);
  53. foreach($this->routes as $name => $route) {
  54. if ($route->match($path)) {
  55. $route->action .= ACTION_POSTFIX;
  56. Env::setParams($route->params);
  57. self::$route_name = $name;
  58. return $route;
  59. }
  60. }
  61. throw new StaticPageException(E_404);
  62. }
  63. static public function setDefaultDecorator($decorator)
  64. {
  65. self::$decorator = $decorator.DECORATOR_POSTFIX;
  66. }
  67. static public function getRouteName()
  68. {
  69. return self::$route_name;
  70. }
  71. }
  72. /**
  73. * Роутер
  74. *
  75. */
  76. final class Route
  77. {
  78. const URL_VARIABLE = '&';
  79. protected $path;
  80. public $decorator = DEFAULT_DECORATOR;
  81. public $action;
  82. public $params;
  83. function __construct($path, $action, $params=array())
  84. {
  85. $this->path = $path;
  86. $this->action = $action;
  87. $this->params = $params;
  88. }
  89. /**
  90. * Проверяет соответствие роутера и пути
  91. *
  92. * @param string $path - путь для сравнения
  93. * @return boolean - соответствует или нет
  94. */
  95. function match($path_arr)
  96. {
  97. $parts = explode('/', $this->path);
  98. $cnt = count($parts);
  99. if (end($parts) == self::URL_VARIABLE) {
  100. $cnt--;
  101. } elseif ($cnt != count($path_arr)) {
  102. return false;
  103. }
  104. for ($i=0; $i<$cnt; $i++) {
  105. if (substr($parts[$i], 0, 1) == self::URL_VARIABLE) {
  106. $this->params[substr($parts[$i], 1)] = $path_arr[$i];
  107. } elseif ($parts[$i] != $path_arr[$i]) {
  108. return false;
  109. }
  110. }
  111. return true;
  112. }
  113. }
  114. ?>