Собственный фильтр Yii2 «Произошла ошибка при обработке другой ошибки» - PullRequest
0 голосов
/ 12 июня 2018

Добрый день.

Я создал свой собственный фильтр в базовом проекте Yii2:

class LanguageFilter extends Behavior
{
    /**
     * @var string
     */
    public $shortLanguage;

    /**
     * Declares event handlers for the [[owner]]'s events.
     * @return array events (array keys) and the corresponding event handler methods (array values).
     */
    public function events()
    {
        return [Controller::EVENT_BEFORE_ACTION => 'beforeAction'];
    }

    /**
     * @param ActionEvent $event
     * @return bool
     * @throws BadRequestHttpException
     */
    public function beforeAction($event)
    {
        if (null === $this->shortLanguage){
            throw new BadRequestHttpException('Parameter "shortLanguage" is not defined.');
        }

        $langModel = Language::find()->where([
            'shortName' => $this->shortLanguage
        ])->one();

        if (null === $langModel){
            throw new BadRequestHttpException('There are not any data for language: '.$this->shortLanguage);
        }

        Yii::$app->language = $langModel->locale;

        return true;
    }
}

И использовал его в контроллере:

class BaseController extends Controller
{
    /**
     * @var string
     */
    protected $shortLanguage;

    /**
     * Initialize.
     */
    public function init()
    {
        $this->defaultAction = 'index';

        $this->layout = '@app/views/layouts/base';

        $this->shortLanguage = Yii::$app->request->get('shortLanguage');

        $this->view->params['shortLanguage'] = $this->shortLanguage;

        $this->view->params['pages'] = Page::getMenu();

        parent::init();
    }

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            'language' => [
                'class' => LanguageFilter::class,
                'shortLanguage' => $this->shortLanguage
            ],
            'access' => [
                'class' => AccessControl::class,
                'rules' => [
                    [
                        'allow'   => true,
                        'actions' => ['reg', 'login'],
                        'roles'   => ['?'],
                    ],
                    [
                        'allow' => true,
                        'actions' => ['logout'],
                        'roles' => ['@'],
                    ],
                    [
                        'allow' => true,
                        'actions' => ['index', 'about', 'contact'],
                        'roles' => ['?', '@'],
                    ],
                    [
                        'allow' => true,
                        'actions' => ['error'],
                        'roles' => ['?', '@'],
                    ],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::class,
                'actions' => [
                    'index' => ['get'],
                    'logout' => ['post', 'get'],
                ],
            ],
        ];
    }

    /**
     * @inheritdoc
     */
    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
        ];
    }
}

В веб-конфигурацииобработчик ошибок файла:

'components' => [
    ...
    ...
    'errorHandler' => [
        'errorAction' => 'base/error',
    ],
    ...
    ...
]

Но когда фильтр выдает исключение, обработчик ошибок отображает сообщение об ошибке БЕЗ ШАБЛОНА !!!И с другой ошибкой.

An Error occurred while handling another error:
yii\web\BadRequestHttpException: There are not any data for language: fr in C:\xampp\htdocs\pack-develop\filters\LanguageFilter.php:44
Stack trace:
#0 [internal function]: app\filters\LanguageFilter->beforeAction(Object(yii\base\ActionEvent))
#1 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Component.php(627): call_user_func(Array, Object(yii\base\ActionEvent))
#2 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Controller.php(274): yii\base\Component->trigger('beforeAction', Object(yii\base\ActionEvent))
#3 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\web\Controller.php(164): yii\base\Controller->beforeAction(Object(yii\web\ErrorAction))
#4 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Controller.php(155): yii\web\Controller->beforeAction(Object(yii\web\ErrorAction))
#5 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Module.php(528): yii\base\Controller->runAction('error', Array)
#6 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\web\ErrorHandler.php(108): yii\base\Module->runAction('base/error')
#7 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\ErrorHandler.php(111): yii\web\ErrorHandler->renderException(Object(yii\web\BadRequestHttpException))
#8 [internal function]: yii\base\ErrorHandler->handleException(Object(yii\web\BadRequestHttpException))
#9 {main}
Previous exception:
yii\web\BadRequestHttpException: There are not any data for language: fr in C:\xampp\htdocs\pack-develop\filters\LanguageFilter.php:44
Stack trace:
#0 [internal function]: app\filters\LanguageFilter->beforeAction(Object(yii\base\ActionEvent))
#1 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Component.php(627): call_user_func(Array, Object(yii\base\ActionEvent))
#2 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Controller.php(274): yii\base\Component->trigger('beforeAction', Object(yii\base\ActionEvent))
#3 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\web\Controller.php(164): yii\base\Controller->beforeAction(Object(yii\base\InlineAction))
#4 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Controller.php(155): yii\web\Controller->beforeAction(Object(yii\base\InlineAction))
#5 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Module.php(528): yii\base\Controller->runAction('index', Array)
#6 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\web\Application.php(103): yii\base\Module->runAction('home/index', Array)
#7 C:\xampp\htdocs\pack-develop\vendor\yiisoft\yii2\base\Application.php(386): yii\web\Application->handleRequest(Object(yii\web\Request))
#8 C:\xampp\htdocs\pack-develop\web\index.php(33): yii\base\Application->run()
#9 {main}

Странно то, что когда другие фильтры (AccessControl, VerbFilter) выдают исключения, обработчик ошибок обычно отображает сообщение об ошибке через шаблон представления.

Пожалуйста, помогите мне понять причину этого!

1 Ответ

0 голосов
/ 12 июня 2018

Это фильтр, а не поведение, я изменил ваш фильтр, который работает.

use Yii;
use yii\web\Controller;
use yii\base\ActionFilter;
use yii\web\BadRequestHttpException;

class LanguageFilter extends ActionFilter
{
    /**
     * @var string
     */
    public $shortLanguage;

    /**
     * @param ActionEvent $action
     * @return bool
     * @throws BadRequestHttpException
     */
    public function beforeAction($action)
    {
        if ($this->shortLanguage === null && !$action instanceof yii\web\ErrorAction)) {
            throw new BadRequestHttpException('Parameter "shortLanguage" is not defined.');
        }

        $langModel = Language::find()->where([
            'shortName' => $this->shortLanguage,
        ])->one();

        if ($langModel === null && !$action instanceof yii\web\ErrorAction) {
            throw new BadRequestHttpException('There are not any data for language: ' . $this->shortLanguage);
        }

        Yii::$app->language = $langModel->locale;

        return true; //return parent::beforeAction($action);
    }
}
...