When creating REST controller rest for module user I have the following properties of the module
public $urlRules = [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['user/users'=>'user/rest'], //http://www.yiiframework.com/doc-2.0/yii-rest-urlrule.html
],
...
];
but when I turn to the address /user/users the script returns an error Getting unknown property: yii\rest\UrlRule::name
really logger tries to access this property
Yii::trace("Request parsed with URL rule: {$rule->name}", __METHOD__);
$rule
in
vendor/yiisoft/yii2/web/CompositeUrlRule.php:51
but in this class this property does not exist.
Do you work with Yii stable release 2.0.6, or with current development version?
"name": "yiisoft/yii2",
"version": "2.0.6",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/yii2-framework.git",
"reference": "f42b2eb80f61992438661b01d0d74c6738e2ff38"
},
@bscheshirwork seems you are nesting UrlRules, can you give more info about how?
I see the following: in a separate rule \yii\rest\UrlRule passes logging in \yii\rest\UrlRule::parseRequest, but after that it is impossible to write in the log and crash in
\yii\web\CompositeUrlRule::parseRequest
My rules in module:
...
class Module extends \dektrium\user\Module
{
/** @var array The rules to be used in URL management. */
public $urlRules = [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['user/users'=>'user/rest'], //http://www.yiiframework.com/doc-2.0/yii-rest-urlrule.html
],
'<id:\d+>' => 'profile/show',
'<action:(login|logout)>' => 'security/<action>',
'<action:(register|resend)>' => 'registration/<action>',
'confirm/<id:\d+>/<code:[A-Za-z0-9_-]+>' => 'registration/confirm',
'forgot' => 'recovery/request',
'recover/<id:\d+>/<code:[A-Za-z0-9_-]+>' => 'recovery/reset',
'settings/<action:\w+>' => 'settings/<action>',
// '<_c:[\w\-]+>' => '<_c>/index',
];
...
}
Interesting... This is a bug that prevents a feature that is not already implemented :) at least, fixing the bug allows to define nested url rules. When allowing this we should also fix the fact that the GroupUrlRule does not propagate its prefix to sub-rules. So to fix this:
yii\rest\UrlRule or yii\web\GroupUrllRule inside a GroupUrllRule.yii\web\UrlRuleFixing the bug is easy by checking the type of UrlRule:
diff --git a/framework/web/CompositeUrlRule.php b/framework/web/CompositeUrlRule.php
index 997a0ae..7424ebe 100644
--- a/framework/web/CompositeUrlRule.php
+++ b/framework/web/CompositeUrlRule.php
@@ -48,7 +48,9 @@ abstract class CompositeUrlRule extends Object implements UrlRuleInterface
foreach ($this->rules as $rule) {
/* @var $rule \yii\web\UrlRule */
if (($result = $rule->parseRequest($manager, $request)) !== false) {
- Yii::trace("Request parsed with URL rule: {$rule->name}", __METHOD__);
+ if ($rule instanceof UrlRule) {
+ Yii::trace("Request parsed with URL rule: {$rule->name}", __METHOD__);
+ }
return $result;
}
not sure how to best propagate the prefix here though: https://github.com/yiisoft/yii2/blob/master/framework/web/GroupUrlRule.php#L91-L111
I can confirm this bug. Yii version: stable 2.0.9. But we are using yii\rest\UrlRule inside yii\web\GroupUrlRule.
We are using next url configuration:
'rules' => [
0 => [
'class' => 'yii\\web\\GroupUrlRule'
'prefix' => ''
'routePrefix' => 'bo'
'rules' => [
0 => [
'class' => 'yii\\rest\\UrlRule'
'prefix' => 'bo' // this is required to propagate prefix to nested rules
'controller' => [
'products' => 'product/bo-product'
]
'only' => [
0 => 'view'
1 => 'index'
]
]
]
]
1 => [
'class' => 'yii\\rest\\UrlRule'
'controller' => 'dictionary/country'
'only' => [
0 => 'view'
1 => 'index'
]
'tokens' => [
'{id}' => '<id:\\w[\\w,]*>'
]
]
2 => [
'class' => 'yii\\rest\\UrlRule'
'controller' => [
'products' => 'product/product'
]
'only' => [
0 => 'view'
1 => 'index'
]
]
]
So we can use next routes for our REST API:
/dictionary/countries => Dictionary module, CountryController/products => Product module, ProductController/bo/products => Product module, BoProductControllerFirst big group of routes prefixed with bo is required to add more controllers in future in our project. So we will have /bo/* routes to manipulate data by administrators and other non-prefixed rules for general use by our customers. This is how we design out REST API and we do not want to change this.
And first two rules work as expected. But third one - /bo/products, leads to mentioned error (accessing to unknown property name in CompositeUrlRule).
So, how to avoid this error?
@cebe, please, look at my example. May be propagation of routePrefix from GroupUrlRule to other nested composite rules can take place?
P.S. Sorry for my English, not a native language for me :-)
why involving yii\web\GroupUrlRule with yii\rest\UrlRule ?
If I'm not wrong yii\web\GroupUrlRule is meant to group many yii\web\UrlRule within a $prefix while yii\rest\UrlRule is already a collection of yii\web\UrlRule instances and that is why there is also yii\rest\UrlRule::$prefix so sub-rules could be grouped like here: https://github.com/yiisoft/yii2/issues/9474#issue-101950485
Well I see, we can change our logic to prepare url rules in another way - provide same prefix for all special REST rules and do not set them inside GroupUrlRule.
But if we can group many of REST rules with same prefix into one parent GroupUrlRule - why not?
this error applies to both classes extending from \yii\webCompositeUrlRule:
@cebe @samdark
I can see this issue have been resolved in be4ebdd04926fd62c2afa2a87c107afd8d2f263c
related #13134
the original bug is fixed, but it there are some other things about nesting rules that should be fixed or if they are working now, covered with a test.
Most helpful comment
this error applies to both classes extending from \yii\webCompositeUrlRule: