Yii2根据条件添加规则

时间:2018-10-13 07:51:59

标签: php dynamic yii2 rules

我正在使用PHP Yii2 Framework和dektrium \ yii2-user扩展名进行网站建设以进行用户身份验证。

我想询问用户验证码,如果登录失败次数超过三,但是默认情况下,扩展名不支持此操作。

现在,我已经覆盖了扩展程序的User和LoginForm模型,并添加了所需的字段和检查。但是,我无法弄清楚如何添加规则以仅从第四次尝试开始就需要验证码。

是否可以动态添加规则?我在下面显示了简化的代码视图以及需要帮助的地方。我将编写函数,只需要注释部分的帮助即可。

<?php

namespace app\models\dektrium\user;


class LoginForm extends \dektrium\user\models\LoginForm
{
    public $captcha;
    public $need_captcha;

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

        //This is how you'd normally add a rule, but this will require it for every login
        //The following rule should be added from the login()
        $rules[] = ['captcha', 'captcha', 'message' => 'Too many attempts. Captcha required.'];
        $rules[] = ['need_captcha', 'boolean'];

        return $rules;
    }

    public function login() {
        $success = false;
        $requireCaptcha = false;

        if ($this->validate() && $this->user) {
            if ($this->user->login_attempts > 3) {
                //add rule here to require captcha

                $requireCaptcha = true;
            }

            $success = !$requireCaptcha && $this->validateCaptcha() && $this->validateLogin();

            if ($success) {
                $this->user->updateAttributes(['last_login_at' => time()]);
            }
        }

        return $success;
    }
}

?>

编辑:

如果有一个“可选”参数与“必需”相反,那么就足够了。我可以在我的login()中检查验证码。

编辑2:

我尝试使用以下方案,但是在进行验证之前,该模型未在控制器操作中加载验证码值。

<?php

namespace app\models\dektrium\user;


class LoginForm extends \dektrium\user\models\LoginForm
{
    public $captcha;
    public $need_captcha;
    public $login_count;

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

        $rules[] = ['captcha', 'captcha', 'message' => 'Too many attempts. Captcha required.', 'on' => ['required_captcha']];
        $rules[] = ['need_captcha', 'boolean'];
        $rules[] = ['login_count', 'integer'];

        return $rules;
    }

    public function login() {
        $this->user = $this->finder->findUserByUsernameOrEmail(trim($this->login));

        if($this->user && $this->user->login_count > 3) {
            $this->scenario = 'required_captcha';
            $this->need_captcha = true;
        }

        $success = parent::login();

        if ($success) {
            $this->user->login_count = 0;
            $this->user->save();
        } else {
            $this->login_count++;

            if ($this->user) {
                $this->user->login_count++;
                $this->user->save();
            }
        }

        if ($this->login_count > 3) {
            $this->scenario = 'required_captcha';
            $this->need_captcha = true;
        }

        return $success;
    }
}

2 个答案:

答案 0 :(得分:1)

使用 设置验证规则时,GMTEXT

条件可以来自会话/ cookie,例如您每次都会增加的整数

答案 1 :(得分:-1)

所以这就是我最终完成此操作的方式...

我使用了基于场景的规则,并且在控制器操作中,当我需要验证码的条件为true时,设置了场景。实际上,控制器也可以进行任何扩展,因此我必须做一些受支持的控制器映射,并通过事件设置场景。

自从我在验证功能期间设置方案以来,我第一次尝试执行此操作失败,但是在执行此操作之前应该已经对其进行了设置。

<?php

namespace app\models\dektrium\user;


class LoginForm extends \dektrium\user\models\LoginForm
{
    public $captcha;
    public $need_captcha;
    public $login_count;

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

        $rules[] = ['captcha', 'required', 'on' => ['use_captcha']];
        $rules[] = ['captcha', 'captcha', 'on' => ['use_captcha']];
        $rules[] = ['need_captcha', 'boolean'];
        $rules[] = ['login_count', 'integer'];

        return $rules;
    }

    public function login() {
        $success = true;
        $this->user = $this->finder->findUserByUsernameOrEmail(trim($this->login));

        if(!$this->need_captcha && $this->user && $this->user->login_count > 3) {
            $this->need_captcha = true;
            $success = false;
        }

        $success = $success && parent::login();

        if ($success) {
            $this->user->login_count = 0;
            $this->user->save();
        } else {
            $this->login_count++;

            if ($this->user) {
                $this->user->login_count++;
                $this->user->save();
            }

            if ($this->login_count > 2)
                $this->need_captcha = true;
        }

        return $success;
    }
}