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.

139 lines
3.4 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. if ($trim = self::getRewriteBase()) {
  52. if (substr($path, 0 , strlen($trim)) == $trim) {
  53. $path = substr($path, strlen($trim));
  54. }
  55. }
  56. $path = explode('/', $path);
  57. foreach($this->routes as $name => $route) {
  58. if ($route->match($path)) {
  59. $route->action .= ACTION_POSTFIX;
  60. Env::setParams($route->params);
  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. }
  79. /**
  80. * Роутер
  81. *
  82. */
  83. final class Route
  84. {
  85. const URL_VARIABLE = '&';
  86. protected $path;
  87. public $decorator = DEFAULT_DECORATOR;
  88. public $action;
  89. public $params;
  90. function __construct($path, $action, $params=array())
  91. {
  92. $this->path = $path;
  93. $this->action = $action;
  94. $this->params = $params;
  95. }
  96. /**
  97. * Проверяет соответствие роутера и пути
  98. *
  99. * @param string $path - путь для сравнения
  100. * @return boolean - соответствует или нет
  101. */
  102. function match($path_arr)
  103. {
  104. $parts = explode('/', $this->path);
  105. $cnt = count($parts);
  106. if (end($parts) == self::URL_VARIABLE) {
  107. $cnt--;
  108. } elseif ($cnt != count($path_arr)) {
  109. return false;
  110. }
  111. for ($i=0; $i<$cnt; $i++) {
  112. if (substr($parts[$i], 0, 1) == self::URL_VARIABLE) {
  113. $this->params[substr($parts[$i], 1)] = $path_arr[$i];
  114. } elseif ($parts[$i] != $path_arr[$i]) {
  115. return false;
  116. }
  117. }
  118. return true;
  119. }
  120. }
  121. ?>