Расширение валидатора Laravel несколько раз

Подобно правилу confirmation , я создаю правило проверки, основанное на значении другого атрибута. Из того, что я нашел, единственный способ добиться этого – расширить класс Validator и получить значение через $this->data .

Документы говорят, чтобы расширить Validator, а затем использовать Validator::resolver для регистрации нового класса расширения. Это работает отлично, но только в случае одного резольвера, поскольку каждый последующий определенный распознаватель просто переопределяет предыдущий.

Как решить эту проблему? Как мы можем определить пользовательские валидаторы, которые все еще имеют доступ к другим атрибутам, не помещая все методы в один класс …?

благодаря

//

Примечание. Я спрашиваю об этом, потому что я хотел бы выпустить несколько пакетов валидатора, но, следуя рассуждениям выше, они просто стали бесполезными, если кто-то установил несколько пакетов …

Related of "Расширение валидатора Laravel несколько раз"

Yup, причина, по которой он переопределяется, – это класс Validator\Factory хранится только один resolver . Код для функции:

 public function resolver(Closure $resolver) { $this->resolver = $resolver; } 

Я бы предположил, что точка метода resolver заключается в том, чтобы расширить базовый класс проверки со своим собственным. Это имеет смысл, поскольку вы можете создать экземпляр UserRegistrationValidator добавляя свои собственные правила проверки, которые имеют всю гибкость, как существующие.

Одна из проблем заключается в том, что его можно легко переопределить, это указывает на то, что вы должны только вызвать метод resolver непосредственно перед вызовом make . Хотя больше усилий, это остановит правила из разных пакетов, потенциально переопределяя другие правила и даже базовые автоматически.

Но это не подходит для пакета, который предоставляет только дополнительные полезные правила. Более простая версия для добавления правила:

 Validator::extend('foo', 'FooValidator@validate'); 

Это не позволяет получить доступ к входным данным, что важно для сложных правил. Пример документации также показывает нам следующее:

 class CustomValidator extends Illuminate\Validation\Validator { public function validateFoo($attribute, $value, $parameters) { return $value == 'foo'; } } 

Но ждать! Что документация не говорит вам, так это то, что вы можете добавить еще один параметр, чтобы получить экземпляр Validator . Который я только что узнал сам, написав этот ответ и углубившись в классы!

 class TestRulesValidator { public function validateTestRule($attribute, $value, $params, $validator) { var_dump($validator->getData()); } } Validator::extend('test_rule', 'TestRulesValidator@validateTestRule'); 

Итак, завершите, передайте дополнительный параметр, который будет экземпляром используемого валидатора. Я подозреваю, что это также будет работать с обратным вызовом.

Надеюсь, это поможет, это было для меня!

Я подклассифицировал Illuminate\Validation\Factory , Illuminate\Validation\ValidationServiceProvider и Illuminate\Validation\Validator как (например) MyFactory , MyValidationServiceProvider и MyValidator , соответственно.

MyFactory.php выглядел так:

 <?php use Illuminate\Validation\Factory; class MyFactory extends Factory { /** * {@inheritDoc} * * @param array $data * @param array $rules * @param array $messages * @param array $customAttributes * @return MyValidator */ protected function resolve(array $data, array $rules, array $messages, array $customAttributes) { if (is_null($this->resolver)) { return new MyValidator($this->translator, $data, $rules, $messages, $customAttributes); } else { return call_user_func($this->resolver, $this->translator, $data, $rules, $messages, $customAttributes); } } } 

MyValidationServiceProvider.php выглядел так:

 <?php use Illuminate\Validation\ValidationServiceProvider; class MyValidationServiceProvider extends ValidationServiceProvider { /** * {@inheritDoc} * * @return void */ public function register() { $this->registerPresenceVerifier(); $this->app->bindShared('validator', function($app) { $validator = new MyFactory($app['translator'], $app); // The validation presence verifier is responsible for determining the existence // of values in a given data collection, typically a relational database or // other persistent data stores. And it is used to check for uniqueness. if (isset($app['validation.presence'])) { $validator->setPresenceVerifier($app['validation.presence']); } return $validator; }); } } 

MyValidator.php выглядел следующим образом:

 <?php namespace MuThetaTau\MuThetaTau\Validation; use Illuminate\Validation\Validator; class MyValidator extends Validator { // custom validation logic } 

Наконец, мне пришлось обновить поставщика услуг в app.php, чтобы указать на MyValidationServiceProvider' instead of Illuminate \ Validation \ ValidationServiceProvider`.

Теперь Validator фасада указывает на MyValidator . Вы могли бы даже дойти до создания нескольких фабрик, добавив (и вызывая) методы в MyValidationServiceProvider чтобы зарегистрировать другие классы валидатора, чтобы сопоставить новые фабрики с новыми привязками IoC, созданием новых классов фасадов и добавлением записей на фасады в app.php иметь разные фасады для каждого валидатора, который вы делаете.