Как использовать правило иногда в классе Laravel 5 request

У меня есть следующий класс запроса:

<?php namespace App\Http\Requests\User;

use App\Http\Requests\Request;
use Validator;
use Session;
use Auth;
use App\User;

class RegisterStep1Request extends Request {

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Set up the validation rules
     */
    public function rules()
    {
        Validator::extend('valid_date', function($attribute, $value, $parameters)
        {
            $pieces = explode('/', $value);
            if(strpos($value, '/')===FALSE) {
                return false;
            } else {
                if(checkdate($pieces[1], $pieces[0], $pieces[2])) {
                    return true;
                } else {
                    return false;
                }
            }
        });

        return [
            'first_name' => 'required',
            'last_name' => 'required',
            'email' => 'required|email|unique:users,email',
            'dob' => 'required|regex:/[0-9]{2}\/[0-9]{2}\/[0-9]{4}/|valid_date',
            'mobile' => 'required',
            'password' => 'required|confirmed'
        ];
    }

    public function messages()
    {
        return [
            'first_name.required' => 'The first name field is required.',
            'last_name.required' => 'The last name field is required.',
            'email.required' => 'The email address field is required.',
            'email.email' => 'The email address specified is not a valid email address.',
            'email.unique' => 'The email address is already registered with this website.',
            'dob.required' => 'The date of birth field is required.',
            'dob.regex' => 'The date of birth is invalid. Please use the following format: DD/MM/YYYY.',
            'dob.valid_date' => 'The date of birth is invalid. Please check and try again.',
            'mobile.required' => 'The mobile number field is required.',
            'password.required' => 'The password field is required.',
            'password.confirmed' => 'The confirm password field does not match the password field.'
        ];
    }

}

Я хочу добавить следующее правило:

Validator::sometimes('dob', 'valid_date', function($input)
{
    return apply_regex($input->dob) === true;
});

Как добавить это в класс запроса?

Я изменил свой метод правил следующим образом:

public function rules()
{
    Validator::extend('valid_date', function($attribute, $value, $parameters)
    {
        $pieces = explode('/', $value);
        if(strpos($value, '/')===FALSE) {
            return false;
        } else {
            if(checkdate($pieces[1], $pieces[0], $pieces[2])) {
                return true;
            } else {
                return false;
            }
        }
    });

    Validator::sometimes('dob', 'valid_date', function($input)
    {
        return apply_regex($input->dob) === true;
    });

    return [
        'first_name' => 'required',
        'last_name' => 'required',
        'email' => 'required|email|unique:users,email',
        'dob' => 'sometimes|required|regex:/[0-9]{2}\/[0-9]{2}\/[0-9]{4}/|valid_date',
        'mobile' => 'required',
        'password' => 'required|confirmed'
    ];
}

Но теперь я получаю следующую ошибку при отправке формы:

FatalErrorException in Facade.php line 216:
Call to undefined method Illuminate\Validation\Factory::sometimes()

Ответ 1

Вы можете прикрепить правило sometimes(), переопределив функцию getValidatorInstance() в запросе формы:

protected function getValidatorInstance(){
    $validator = parent::getValidatorInstance();

    $validator->sometimes('dob', 'valid_date', function($input)
    {
        return apply_regex($input->dob) === true;
    });

    return $validator;
}

Ответ 2

Существует документированный путь, чтобы внести изменения в экземпляр проверки валидатора запроса в Laravel 5.4. Для этого вы должны реализовать метод withValidator.

На основе примера из ответа @lukasgeiter вы можете добавить следующее к вашему классу запросов:

/**
 * Configure the validator instance.
 *
 * @param  \Illuminate\Validation\Validator  $validator
 * @return void
 */
public function withValidator($validator)
{
    $validator->sometimes('dob', 'valid_date', function ($data) {
        return apply_regex($input->dob) === true;
    });
}

При этом вам не нужно беспокоиться о переопределении внутренних методов. Кроме того, это, по-видимому, официальный способ настройки валидатора.

Ответ 3

Согласно вашему комментарию

Я хочу, чтобы правило valid_date выполнялось только в том случае, если правило регулярного выражения возвращает true. В противном случае ошибки правила valid_date, если дата не в правильном формате.

Validator::extend('valid_date', function($attribute, $value, $parameters)
    {
       \\use the regex here instead

        if (!preg_match('/[0-9]{2}\/[0-9]{2}\/[0-9]{4}/', $value)) return false; 


        $pieces = explode('/', $value);
        if(strpos($value, '/')===FALSE) {
            return false;
        } else {
            if(checkdate($pieces[1], $pieces[0], $pieces[2])) {
                return true;
            } else {
                return false;
            }
        }
    });


$validator = Validator::make($data, [
   'first_name' => 'required',
    'last_name' => 'required',
    'email'     => 'required|email|unique:users,email',
    'dob'       => 'required|valid_date',
    'mobile'    => 'required',
    'password'  => 'required|confirmed'
]);

Ответ 4

Вам просто нужно добавить ключ dob к возвращаемому массиву вместе с набором правил проверки, который следует выполнить, включая sometimes.

В этом случае:

'dob' : 'sometimes|required|regex:/[0-9]{2}\/[0-9]{2}\/[0-9]{4}/|valid_date'