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.

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