1

In my CI4 learning, I have started by trying to simulate user sign in functionality. I have a Controller, two Views (not shown here, but really simply pages- one a pretty much just single form, and the other one a “blank” success HTML page), a set of custom rules in the Validation.php file, and a CustomRule.php file with the first of the methods that will implement all my custom rules (which, ultimately, I’d like to have all set in the Validation.php file). For lack of a better idea, I’ve stuck the CustomRules.php file in the app\Config\ folder.

Here is my problem:

For the life of me, I can’t figure out how to get the Validation service to pass additional parameters (from the form) to my custom rules function called ‘user_validated’. The CI4 documentation describes what the custom function needs to cater for when accepting additional parameters, but not how to trigger the Validation service to pass these additional parameters to one’s custom function… so although ‘user_validated’ is called, only ‘user_email_offered’ is ever passed as in as a string- nothing else goes in, from what I can tell. How do I get around this?

I have tried inserting < $validation->setRuleGroup('user_signin'); > before the call to validate, but found that I could move the setting of the rule group into the call to validate, using: $validationResult = $this->validate('user_signin'), which seemed to do the same, and which doesn't seem to work without the rule-group as a parameter (?). This still doesn't seem to be what triggers the additional data to be passed to the custom rule's method.

Extracts from my hack are appended below.

I’d be very grateful one of you knowledgeable folk could please point me in the right direction.


In app\Controllers\SignupTest.php:

<?php

    namespace App\Controllers;

    use CodeIgniter\Controller;

    class SignupTest extends BaseController
    {

            public function index() {   // redirection from the default to signup(), signin(), ...

                return $this->signup();

            }


            public function signup() {

                helper(['form']);

                $validation = \Config\Services::validation();

                if ($this->request->getPost()) {     // still TBD: any different to using $this->request->getGetPost() ?

                    $validationResult = $this->validate('user_signin'); // set the rules to use: 'user_signin', 'user_signup'

                    if (!$validationResult) {

                        $validationErrors = $validation->getErrors();

                        return view('SignupTestView', $validationErrors);   // redisplay simple html form view with list of validation errors

                    } else {

                        return view('SignupTestViewSuccess');  // display view to show success 
                    }
                } else {

                    return view('SignupTestView');   // initial display, in the event of there being no POST data 

                }
            }
    }

In \app\Config\CustomRules.php:

<?php

    namespace Config;

    use App\Models\UserModel;

    //--------------------------------------------------------------------
    // Custom Rule Functions 
    //--------------------------------------------------------------------

    class CustomRules
    { 


        public function user_validated(string $str, string $fields = NULL, array $data = NULL, string &$error = NULL) : bool{            

             $user_email_offered = $str;
             $user_password_offered = '';    // to be extracted using $fields = explode(',', $fields), but $fields is never provided in the call to this user_validated method


            if (($user_email_offered !== NULL) && ($user_password_offered !== NULL)) {

                $usermodel = new UserModel();   // intended to create a UserEntity to permit connectivity to the database 

                $user_found = $usermodel->find($user_email_offered);    // we're going to assume that user_email is unique (which is a rule configured in the database table)

                if ($user_found === NULL) { // check if user exists before doing the more involved checks in the else-if section below, which may throw exceptions if there's nothing to compare (?)

                ...   

          }

}

In \app\Config\Validation.php:

?php 
    namespace Config;

    class Validation
    {
        //--------------------------------------------------------------------
        // Setup
        //--------------------------------------------------------------------

        /**
         * Stores the classes that contain the
         * rules that are available.
         *
         * @var array
         */
        public $ruleSets = [
            \CodeIgniter\Validation\Rules::class,
            \CodeIgniter\Validation\FormatRules::class,
            \CodeIgniter\Validation\FileRules::class,
            \CodeIgniter\Validation\CreditCardRules::class,
            \Config\CustomRules::class,
        ];

        /**
         * Specifies the views that are used to display the
         * errors.
         *
         * @var array
         */
        public $templates = [
            'list'   => 'CodeIgniter\Validation\Views\list',
            'single' => 'CodeIgniter\Validation\Views\single',
        ];

        //--------------------------------------------------------------------
        // Custom Rules
        //--------------------------------------------------------------------

        /* configurable limits for validation rules array below*/
        const user_email_min_lenth = 9;  
        const user_email_max_lenth = 50; 
        const user_password_min_lenth = 6;   
        const user_password_max_lenth = 25;  


        public $user_signin = [
            'user_email' => [
                'label' => 'e-mail address',
                'rules' => 'trim|required|valid_email|user_validated',  // user_validated is custom rule, that will have a custom error message
                'errors' => [
                    'required' => 'You must provide an {field}',
                    'valid_email' => 'Please enter a valid {field}',
                ]
            ],
            'user_password' => [
                'label' => 'password',
                'rules' => 'trim|required',
                'errors' => [
                    'required' => 'Enter a {field} to sign in',
                    'user_password_check' => 'No such user/{field} combination found',
                ] 
4

1 回答 1

3

带参数调用自定义规则应该和调用 CI4 的常规规则完全一样。例如,让我们获取“required_without”。您可以像在此示例中一样使用它:

$validation->setRule('username', 'Username', 'required_without[id,email]');

函数声明如下:

public function required_without($str = null, string $fields, array $data): bool
{
    $fields = explode(',', $fields);
//...
}

其中 $str - 这是您的主要字段,$fields - 字符串,打包一个逗号分隔的数组。

至于分组规则,您无需对规则进行分组即可使用带参数的自定义规则。

如果您只有 2 个要测试的字段,则可以便宜一些,这并不完美,但仍然有效:

功能:

public function myrule(string $mainfield, string $fieldtotestwith): bool
{
//doing stuff
}

验证规则:

$validation->setRule('somemainfield', 'Something', 'myrule[somesecondfield]');
于 2019-11-05T14:33:17.477 回答