В моем проекте Laravel я использую unique_with валидатор и в основном у меня есть textarea, который позволяет мне добавлять массовые категории. Мне нужно проверить каждую строку этого текстового поля, потому что будет добавлено несколько строк в базу данных, поэтому мне также нужно использовать мой пользовательский валидатор.
В моем app/config/app.php
файл, который я использую:
'Felixkiss\UniqueWithValidator\UniqueWithValidatorServiceProvider',
'Providers\TextareaNameValidatorServiceProvider',
зарегистрировать этот валидатор и мой пользовательский.
Код, который я использую для проверки:
$data = Input::except('submit');
$data['parent'] = Input::get('parent') ?: null;$names = explode(PHP_EOL, trim($data['name']));
if (count($names) == 1) {
$rules['name']
= '
required |
unique_with:categories, parent = par_cat';
}
else {
$rules['name'] = 'textareaname'; // my custom validator
}$validator = Validator::make($data, $rules,
Lang::get('forms.validation'));if ($validator->passes()) {
// ...
если у меня есть только одна строка, она работает без проблем, потому что она использует unique_with
валидатор.
Мой валидатор определяется следующим образом:
Поставщик услуг:
<?php
namespace Providers;
use Illuminate\Support\ServiceProvider;
class TextareaNameValidatorServiceProvider extends ServiceProvider {
public function register(){}
public function boot()
{
$this->app->validator->resolver(function($translator, $data, $rules, $messages)
{
return new \Utils\TextareaNameValidator($translator, $data, $rules, $messages);
});
}
}
Сам валидатор:
<?php
namespace Utils;
use Validator;class TextareaNameValidator extends \Illuminate\Validation\Validator
{
public function validateTextareaName($attribute, $value, $parameters)
{
$array = explode(PHP_EOL, trim($value));
if (count($array) !== count(array_unique($array))) {
return false;
}foreach ($array as $item) {
$data['name'] = $item;$rules['name']
= '
required |
unique_with:categories, parent = par_cat ';
$validator = Validator::make($data, $rules);
if (!$validator->passes()) {
return false;
}
}
return true;
}
}
Если я запустить этот код и перейти к textareaname
валидатор и намеренно заполняю форму так, что unique_with
должен быть запущен в этом валидаторе я получаю:
Метод [validateUniqueWith] не существует.
Однако, как я уже сказал, когда unique_with
валидатор запускается не из textareaname
валидатор ошибки не возникает.
Если я изменю порядок в моих провайдерах с:
'Felixkiss\UniqueWithValidator\UniqueWithValidatorServiceProvider',
'Providers\TextareaNameValidatorServiceProvider',
в
'Providers\TextareaNameValidatorServiceProvider',
'Felixkiss\UniqueWithValidator\UniqueWithValidatorServiceProvider',
Я получаю следующую ошибку:
Метод [validateTextareaname] не существует.
Таким образом, кажется, есть проблема с использованием двух пользовательских валидаторов.
Вопрос — как зарегистрировать 2 пользовательских валидатора в Laravel, не имеющих такой проблемы? Или, возможно, по какой-то причине невозможно запустить пользовательский валидатор из другого пользовательского валидатора (но, глядя на ошибку, когда изменение порядка провайдеров вызывает похожую ошибку, кажется, что это не так)?
РЕДАКТИРОВАТЬ
Поскольку я пытаюсь решить эту проблему, я переместил свой код, чтобы не использовать поставщика услуг. Поэтому я прокомментировал эту строку в app/config/app.php
:
// 'Providers\TextareaNameValidatorServiceProvider',
и в моем app/start/global.php
Я добавил:
Validator::extend('TextareaName', function($attribute, $value, $parameters)
{
$array = explode(PHP_EOL, trim($value));
if (count($array) !== count(array_unique($array))) {
return false;
}foreach ($array as $item) {
$data['name'] = $item;$rules['name']
= '
required |
unique_with:categories, parent = par_cat ';
$validator = Validator::make($data, $rules);
if (!$validator->passes()) {
return false;
}
}
return true;
});
код внутри валидатора такой же, как и предыдущий. Теперь это работает без проблем. Таким образом, проблема заключается в том, когда я использую поставщика услуг для регистрации моего валидатора. Вопрос — почему?
EDIT2
Кажется, что это происходит, даже если у меня есть 2 пользовательских валидатора, использующих поставщика услуг (и не использующих unique_with
). ЕСЛИ я копирую код моего TextAreaName (поставщика услуг и валидатора), переименовываю их правильно и добавляю их обоих в поставщиков, с одним из них всегда будут проблемы.
Там нет четкой информации в руководстве, но невозможно добавить несколько провайдеров валидаторов. Ссылка на SO.
Похоже, об этом мало кто знает. Четное unique_with
валидатор (о котором я упоминал в начале) поддерживает только регистрацию в качестве провайдера. Если бы у нас был другой валидатор поставщиков, который также должен был бы быть зарегистрирован как поставщик услуг, это было бы невозможно сделать.
Таким образом, окончательное решение использовать мой textarea_name
валидатор это:
Удаление из app/config/app.php
линия:
// 'Providers\TextareaNameValidatorServiceProvider',
добавить в app/start/global.php
:
Validator::extend('textarea_name', '\Utils\TextAreaNameValidator@validateTextareaName');
и определить мой валидатор следующим образом:
<?php
namespace Utils;
use Validator;
class TextareaNameValidator
{
public function validateTextareaName($attribute, $value, $parameters)
{
$array = explode(PHP_EOL, trim($value));
if (count($array) !== count(array_unique($array))) {
return false;
}foreach ($array as $item) {
$data['name'] = $item;$rules['name']
= '
required
|
unique_with:categories, parent = par_cat
';
$validator = Validator::make($data, $rules);
if (!$validator->passes()) {
return false;
}
}
return true;
}
}
(обратите внимание, это не распространяется Validator
класс больше)
Я заметил, что ошибка:
validateTextareaname
но твой класс
validateTextareaName
(обратите внимание на заглавную букву «N»).
Попробуйте изменить
$rules['name'] = 'textareaname'; // my custom validator
в
$rules['name'] = 'textarea_name'; // my custom validator