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

Ладно, я попал в очень сложную ситуацию и думаю, что мне либо не хватает чего-то важного, что уже присутствует, или 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.']
]);

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

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

$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

Решение

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

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')
]
]);

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

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

2

Другие решения

Самый простой способ, который я понял в 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);
}
},
]
]);

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

0

По вопросам рекламы [email protected]