Use Yii::$App->Controller Outside Of View

Hello everybody.

We’ve started using Yii2 in 3rd party application.

In short, we use Yii to handle some new written actions with backward-compatibility for old application.

All old application pages use "fake" controller which returns null (no output).

[size=“1”]If someone is interested, here is code example how I did it (but it’s not the point of this topic):

www.yiiframework.ru/forum/viewtopic.php?f=19&t=17139&p=101186#p101186[/size]


And here is my problem:

I wanted to show correctly link from Yii app in 3rd party app:


<?= Html::a('Manager Users', ['multiuser/manage']) ?>

And get Exception:


Unable to resolve the relative route: multiuser/index. No active controller is available.

It doesn’t work because Yii::$app->controller is null outside of Yii view.

As I found, controller got null value here:

(because $oldController is null).


So my question is:

How can I correctly overwrite Core yii\base\Module::runAction() method?

Here is how it is:




    public function runAction($route, $params = [])

    {

        $parts = $this->createController($route);

        if (is_array($parts)) {

            /** @var Controller $controller */

            list($controller, $actionID) = $parts;

            $oldController = Yii::$app->controller;

            Yii::$app->controller = $controller;

            $result = $controller->runAction($actionID, $params);

            Yii::$app->controller = $oldController;


            return $result;

        } else {

            $id = $this->getUniqueId();

            throw new InvalidRouteException('Unable to resolve the request "' . ($id === '' ? $route : $id . '/' . $route) . '".');

        }

    }



Here is how I want it:




    public function runAction($route, $params = [])

    {

        $parts = $this->createController($route);

        if (is_array($parts)) {

            /** @var Controller $controller */

            list($controller, $actionID) = $parts;

            $oldController = Yii::$app->controller;

            Yii::$app->controller = $controller;

            $result = $controller->runAction($actionID, $params);

            if ($oldController !== null) { // ADDED!

                Yii::$app->controller = $oldController;

            } // ADDED!


            return $result;

        } else {

            $id = $this->getUniqueId();

            throw new InvalidRouteException('Unable to resolve the request "' . ($id === '' ? $route : $id . '/' . $route) . '".');

        }

    }



This way I will get ‘first active’ controller outside of Yii view.

Also what’s the point of overwriting Yii::$app->controller with $oldController, when $oldController is null?

Thanks everyone who will dig into this.

Solution for this special case with links from Yii in 3rd party app:

Just used Absolute route:


<?= Html::a('Manager Users', ['/multiuser/manage']) ?>

instead of Relative Route which requires active Controller:


<?= Html::a('Manager Users', ['multiuser/manage']) ?>