Передать пользовательские параметры в Laravel Validation с помощью регулярных выражений - PullRequest
0 голосов
/ 25 мая 2018

Хорошо, я попал в очень сложную ситуацию и думаю, что мне либо не хватает чего-то важного, что уже присутствует, или Laravel не предоставляет способ добиться этого прямо сейчас.Я хотел бы указать пользовательское сообщение об ошибке проверки с пользовательским заполнителем, который я хотел бы заменить в сообщении.Проблема с этим: я использую правило проверки regex, о котором документация Laravel явно указывает, что его лучше передавать в массив, чтобы избежать нежелательного поведения разделителя.Ситуация следующая: я хотел бы указать глобальное многоязычное сообщение для проверки name.regex, что я и сделал:

'custom' => [
    'name' => [
        'regex' => 'The :attribute must corespond to the given format: :format!'
    ]
]

Как видите, я поместил пользовательский заполнитель:format в этом сообщении, потому что для атрибута name разных классов я собираюсь сопоставить разные регулярные выражения.Поэтому я хотел бы иметь возможность вводить пользовательское удобочитаемое описание каждого данного регулярного выражения вдоль проверки (в качестве параметра).Итак, я делаю следующее в моем контроллере:

$input = Input::all();
$validator = Validator::make($input, [
        'name' => ['required', 'regex:/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u']
    ]);

У меня также есть Validator::replacer() метод в моем AppServiceProvider.php, который должен заменить заполнитель :format в сообщении:

Validator::replacer('regex', function($message, $attr, $rule, $parameters){
        return str_replace(':format', "I would like to be able to somehow retrieve the custom format description here, but using \$parameters[] is not an option", $message);
    });

Проблема с правилом проверки regex заключается в том, что я действительно не могу передать ему параметр в валидаторе, как, например, так:

$validator = Validator::make($input, [
        'name' => ['required', 'regex:/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u,Thats my custom validator format description']
    ]);

, потому что он полностьюпортит регулярное выражение (что должно быть так).Поэтому я не могу использовать $ параметры 1 $ в моем replacer() для замены заполнителя.Кроме того, было бы очень неудобно передавать целое предложение в качестве параметра правила валидации через запятую.Таким образом, эта концепция не соответствует потребностям.

Значение :format будет динамичным и будет сильно варьироваться в зависимости от требований полей name различных классов, поэтому мне действительно нужно, чтобы это динамическое многоязычное описание было задано каксвойство текущего экземпляра валидатора.Я подумал, что, возможно, наиболее удобным сценарием будет что-то вроде этого:

$validator = Validator::make($input, [
        'name' => ['required', 'regex:/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u', 'format:Current name requirements described here.']
    ]);

, и Laravel каким-то образом знает, что :format должно быть заменено настоящим правилом где-то в сообщениях этого экземпляра.Я думал о явном добавлении этого дополнительного параметра в качестве правила проверки, а затем управлять им, но я действительно не могу установить соединение между правилами (другими словами, получить параметр нового правила format и использовать егов правиле regex).Я действительно не знаю, как подойти к этому вопросу, и любая помощь будет принята с благодарностью.Заранее спасибо!

PS Я знаю, что могу указывать все сообщение каждый раз таким образом:

$input = Input::all();
$validator = Validator::make($input, [
        'name' => ['required', 'regex:/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u']
    ],
[
    'name.regex' => 'My custom message here'
]);

, но я не хочу каждый раз вводить все сообщение целикомпотому что позже он может содержать в себе другие заполнители (которые могут быть глобальными или около того), и я хочу использовать многоязычное базовое сообщение, предоставляемое через файлы validator.php, поэтому мне действительно нужно заменить только :format.

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

Вы можете создать собственное правило:

php artisan make:rule CustomRegex

Затем обновите конструктор, чтобы он поддерживал как регулярное выражение, так и описание формата.

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class CustomRegex implements Rule
{
    /** @var string $attribute The attribute of we are validating. */
    public $attribute;

    /** @var string $description The description of the regex format. */
    public $description;

    /** @var string $regex The regex to validate. */
    public $regex;

    /**
     * Create a new rule instance.
     *
     * @param string $regex The regex to validate.
     * @param string $description The description of the regex format.
     * @return void
     */
    public function __construct(string $regex, string $description)
    {
        $this->regex = $regex;
        $this->description = $description;
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $this->attribute = $attribute;

        return preg_match($this->regex, $value);
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return trans('validation.custom.name', [
            'attribute' => $this->attribute,
            'format' => $this->description
        ]);
    }
}

А затем при проверке:

use App\Rules\CustomRegex;

request()->validate([
    'name' => [
        'required', new CustomRegex('/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u', 'The description of your format')
    ]
]);

Тогда выходное сообщение будет выглядеть так:

Имя должно соответствовать указанному формату: описание вашего формата!

0 голосов
/ 25 мая 2018

Самый простой способ, как я понял в Laravel 5.6, - использовать замыкание:

$validator = Validator::make($input, 
    [
        'name' => 
           [
             'required',
             function($attribute, $value, $fail) {

                 $regex = '/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u';

                 if (!preg_match($regex, $value)) {

                    return $fail('Your custom message with' .
                    $attribute . ' name and its value = ' . $value);
                 }
             },
           ]
    ]);

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

...