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
4.3KB

  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\web;
  8. use Yii;
  9. use yii\base\InvalidConfigException;
  10. /**
  11. * GroupUrlRule represents a collection of URL rules sharing the same prefix in their patterns and routes.
  12. *
  13. * GroupUrlRule is best used by a module which often uses module ID as the prefix for the URL rules.
  14. * For example, the following code creates a rule for the `admin` module:
  15. *
  16. * ```php
  17. * new GroupUrlRule([
  18. * 'prefix' => 'admin',
  19. * 'rules' => [
  20. * 'login' => 'user/login',
  21. * 'logout' => 'user/logout',
  22. * 'dashboard' => 'default/dashboard',
  23. * ],
  24. * ]);
  25. *
  26. * // the above rule is equivalent to the following three rules:
  27. *
  28. * [
  29. * 'admin/login' => 'admin/user/login',
  30. * 'admin/logout' => 'admin/user/logout',
  31. * 'admin/dashboard' => 'admin/default/dashboard',
  32. * ]
  33. * ```
  34. *
  35. * The above example assumes the prefix for patterns and routes are the same. They can be made different
  36. * by configuring [[prefix]] and [[routePrefix]] separately.
  37. *
  38. * Using a GroupUrlRule is more efficient than directly declaring the individual rules it contains.
  39. * This is because GroupUrlRule can quickly determine if it should process a URL parsing or creation request
  40. * by simply checking if the prefix matches.
  41. *
  42. * @author Qiang Xue <qiang.xue@gmail.com>
  43. * @since 2.0
  44. */
  45. class GroupUrlRule extends CompositeUrlRule
  46. {
  47. /**
  48. * @var array the rules contained within this composite rule. Please refer to [[UrlManager::rules]]
  49. * for the format of this property.
  50. * @see prefix
  51. * @see routePrefix
  52. */
  53. public $rules = [];
  54. /**
  55. * @var string the prefix for the pattern part of every rule declared in [[rules]].
  56. * The prefix and the pattern will be separated with a slash.
  57. */
  58. public $prefix;
  59. /**
  60. * @var string the prefix for the route part of every rule declared in [[rules]].
  61. * The prefix and the route will be separated with a slash.
  62. * If this property is not set, it will take the value of [[prefix]].
  63. */
  64. public $routePrefix;
  65. /**
  66. * @var array the default configuration of URL rules. Individual rule configurations
  67. * specified via [[rules]] will take precedence when the same property of the rule is configured.
  68. */
  69. public $ruleConfig = ['class' => 'yii\web\UrlRule'];
  70. /**
  71. * @inheritdoc
  72. */
  73. public function init()
  74. {
  75. if ($this->routePrefix === null) {
  76. $this->routePrefix = $this->prefix;
  77. }
  78. $this->prefix = trim($this->prefix, '/');
  79. $this->routePrefix = trim($this->routePrefix, '/');
  80. parent::init();
  81. }
  82. /**
  83. * @inheritdoc
  84. */
  85. protected function createRules()
  86. {
  87. $rules = [];
  88. foreach ($this->rules as $key => $rule) {
  89. if (!is_array($rule)) {
  90. $rule = [
  91. 'pattern' => ltrim($this->prefix . '/' . $key, '/'),
  92. 'route' => ltrim($this->routePrefix . '/' . $rule, '/'),
  93. ];
  94. } elseif (isset($rule['pattern'], $rule['route'])) {
  95. $rule['pattern'] = ltrim($this->prefix . '/' . $rule['pattern'], '/');
  96. $rule['route'] = ltrim($this->routePrefix . '/' . $rule['route'], '/');
  97. }
  98. $rule = Yii::createObject(array_merge($this->ruleConfig, $rule));
  99. if (!$rule instanceof UrlRuleInterface) {
  100. throw new InvalidConfigException('URL rule class must implement UrlRuleInterface.');
  101. }
  102. $rules[] = $rule;
  103. }
  104. return $rules;
  105. }
  106. /**
  107. * @inheritdoc
  108. */
  109. public function parseRequest($manager, $request)
  110. {
  111. $pathInfo = $request->getPathInfo();
  112. if ($this->prefix === '' || strpos($pathInfo . '/', $this->prefix . '/') === 0) {
  113. return parent::parseRequest($manager, $request);
  114. } else {
  115. return false;
  116. }
  117. }
  118. /**
  119. * @inheritdoc
  120. */
  121. public function createUrl($manager, $route, $params)
  122. {
  123. if ($this->routePrefix === '' || strpos($route, $this->routePrefix . '/') === 0) {
  124. return parent::createUrl($manager, $route, $params);
  125. } else {
  126. return false;
  127. }
  128. }
  129. }