Using a base controller

In many frameworks, the concept of a base controller that is being extended by other ones is described right in the guide. In Yii, it is not in the guide, as you can achieve flexibility in many other ways. Still, using a base controller is possible and can be useful.

Let's say we want to add some controllers that will be accessible only when the user is logged in. We can certainly set this constraint for each controller separately, but we will do it in a better way.

Getting ready

Create a new application using the Composer package manager, as described in the official guide at http://www.yiiframework.com/doc-2.0/guide-startinstallation.html.

How to do it…

  1. First, we will need a base controller that our user-only controllers will use. Let's create @app/components/BaseController.php with the following code:
    <?php
    
    namespace appcomponents;
    
    use Yii;
    use yiiwebController;
    use yiifiltersAccessControl;
    
    class BaseController extends Controller
    {
        public function actions()
        {
            return [
                'error' => ['class' => 'yiiwebErrorAction'],
            ];
        }
    
        public function behaviors()
        {
            return [
                'access' => [
                    'class' => AccessControl::className(),
                    'rules' => [
                        [
                            'allow' => true,
                            'actions' => 'error'
                        ],
                        [
                            'allow' => true,
                            'roles' => ['@'],
                        ],
                    ],
                ]
            ];
        }
    }

    This controller has an action map with an error action also.

  2. Now, create TestController by Gii, but set the value of the base class field as app/components/BaseController:
    How to do it…

    You will get something similar to the following:

    <?php
    namespace appcontrollers;
    class TestController extends appcomponentsBaseController
    {
        public function actionIndex()
        {
            return $this->render('index');
        }
    }
  3. Now, your TestController will be only accessible if the user is logged in, even though we have not declared it explicitly in the TestController class. You can check it by visiting http://yii-book.app/index.php?r=test/index while logged out.

How it works…

The trick is nothing more than a basic class inheritance. If filters or access control rules are not found in TestController, then they will be called from SecureController.

There's more…

If you need to extend the base controller's method, keep in the mind that it must not be overridden. For example, we need to add a page action to the controller's action map:

<?php

namespace appcontrollers;

use yiihelpersArrayHelper;
use appcomponentsBaseController;

class TestController extends BaseController
{
    public function actions()
    {
        return ArrayHelper::merge(parent::actions(), [
            'page' => [
                'class' => 'yiiwebViewAction',
            ],
        ]);
    }

    public function behaviors()
    {
        $behaviors = parent::behaviors();

        $rules = $behaviors['access']['rules'];

        $rules = ArrayHelper::merge(
            $rules,
            [
                [
                    'allow' => true,
                    'actions' => ['page']
                ]
            ]
        );

        $behaviors['access']['rules'] = $rules;

        return $behaviors;
    }

    public function actionIndex()
    {
        return $this->render('index');
    }
}

For further information, refer to http://www.yiiframework.com/doc-2.0/yii-base-controller.html.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.67.251