Ладно, я попал в очень сложную ситуацию и думаю, что мне либо не хватает чего-то важного, что уже присутствует, или 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
только.
Вы можете создать собственное правило:
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')
]
]);
Тогда выходное сообщение будет выглядеть так:
Имя должно соответствовать указанному формату: описание вашего формата!
Самый простой способ, который я понял в 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);
}
},
]
]);
Внутри этого закрытия вы можете добавить все, что вы хотите. Вы можете рассчитать читаемый формат и добавить его в сообщение об ошибке.