Yii2: Getting unknown property: yii\rest\UrlRule::name

Created on 23 Nov 2015  路  13Comments  路  Source: yiisoft/yii2

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.

rest test

Most helpful comment

this error applies to both classes extending from \yii\webCompositeUrlRule:

  • \yiirest\Rule (this topic)
  • yii\web\GroupUrlRule (https://github.com/yiisoft/yii2/issues/13037)

All 13 comments

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:

  • [ ] make sure the reported bug does not appear when nesting yii\rest\UrlRule or yii\web\GroupUrllRule inside a GroupUrllRule.
  • [ ] make sure that the prefix of GroupUrllRule is propageted to sub-rules that are not yii\web\UrlRule

Fixing 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:

  1. /dictionary/countries => Dictionary module, CountryController
  2. /products => Product module, ProductController
  3. /bo/products => Product module, BoProductController

First 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:

  • \yiirest\Rule (this topic)
  • yii\web\GroupUrlRule (https://github.com/yiisoft/yii2/issues/13037)

@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.

Was this page helpful?
0 / 5 - 0 ratings