Laravel 5.2 - extending the Validator class


Laravel 5.2 - extending the Validator class

我正在尝试覆盖Illuminate'Validation'Validator中的doReplacements方法。当我扩展本机ValidatorRequest类时,我会得到以下错误:

ReflectionException in Route.php第270行:

类App''Http''Requests''FooRequest不存在

这就是我所做的:

  1. 扩展本机Illuminate'Validation'Validator:

    class MyCustomValidator extends Validator {
        protected function doReplacements($message, $attribute, $rule, $parameters) {
            //override this method
        }
    }
    
  2. 在本机App'Http'Requests'Request:的抽象扩展中使用MyCustomValidator

    abstract class MyCustomRequest extends Request {
        //Override native method by injecting the extending validator
        protected function formatErrors( MyCustomValidator $validator )
        {
            return $validator->getMessageBag()->toArray();
        }
    }
    
  3. 用混凝土等级扩展MyCustomRequest

    class FooRequest extends MyCustomRequest
    {
        public function authorize()
        {
            return true;
        }
    
        public function rules()
        {
            return [
                // rules go here
            ];
        }
    }
    
  4. 在控制器中使用FooRequest方法:

    public function store(FooRequest $request) {
        //use the request and persist
    }
    


我猜我缺少所需的facade、provider或容器绑定。我还在学习这些主题,对它们的理解还不够好,不知道下一步该怎么做。

参考文献:

  • Laravel 5中的自定义验证器-我照做了,但还是犯了同样的错误。在排除我在这里尝试的问题之前,我想知道这是否与我的问题有很大关系。

  • 扩展自定义验证类-问题看起来类似,答案建议使用Validator::extend,我知道这可以在AppServiceProvider中完成,但理想情况下,我的代码应该在自己的供应商包中。同样,不确定是否相关。

我遇到了同样的问题,我就是这么做的。

首先,创建一个类并将其命名为CustomValidatorServiceProvider或任何您想要的名称。在CustomValidatorServiceProvider内部添加以下行。

<?php
namespace App'Providers;
use Illuminate'Support'Facades'Event;
use Illuminate'Validation'ValidationServiceProvider as ServiceProvider;
use App'Services'Validator'Factory;
class CustomValidatorServiceProvider extends ServiceProvider
{
    /**
     * Register the validation factory.
     *
     * @return void
     */
    protected function registerValidationFactory()
    {
        $this->app->singleton('validator', function ($app) {
            $validator = new Factory($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['db']) && isset($app['validation.presence'])) {
                $validator->setPresenceVerifier($app['validation.presence']);
            }
            return $validator;
        });
    }
}

如果您注意到我添加了自己的Validator''Factory并导入了它。在验证程序''工厂内部,我有以下代码。

<?php
namespace App'Services'Validator;
use Illuminate'Validation'Factory as ParentFactory;
class Factory extends ParentFactory
{
    /**
     * Resolve a new Validator instance.
     *
     * @param  array  $data
     * @param  array  $rules
     * @param  array  $messages
     * @param  array  $customAttributes
     * @return 'Illuminate'Validation'Validator
     */
    protected function resolve(array $data, array $rules, array $messages, array $customAttributes)
    {
        if (is_null($this->resolver)) {
            return new Validator($this->translator, $data, $rules, $messages, $customAttributes);
        }
        return call_user_func($this->resolver, $this->translator, $data, $rules, $messages, $customAttributes);
    }
}

Validator''Factory所在的同一目录中,我还添加了我的自定义ValidatorClass,它将是扩展框架的验证器类的类。它包含以下代码。

<?php
namespace App'Services'Validator;
use Illuminate'Validation'Validator as ParentValidator;
use Illuminate'Support'Str;
class Validator extends ParentValidator
{
    /**
     * Replace all place-holders for the greater_than_equal rule.
     *
     * @param  string  $message
     * @param  string  $attribute
     * @param  string  $rule
     * @param  array   $parameters
     * @return string
     */
    protected function replaceGreaterThanEqual($message, $attribute, $rule, $parameters)
    {
        $replacers[0] = str_replace('_', ' ', Str::snake($parameters[0]));
        $replacers[1] = $attribute;
        return str_replace([':other', ':attribute'], $replacers, $message);
    }
    /**
     * Replace all place-holders for the after_or_equal rule.
     *
     * @param  string  $message
     * @param  string  $attribute
     * @param  string  $rule
     * @param  array   $parameters
     * @return string
     */
    protected function replaceAfterOrEqual($message, $attribute, $rule, $parameters)
    {
        return $this->replaceGreaterThanEqual($message, $attribute, $rule, $parameters);
    }
}

最后,我们应该在providers数组下添加我们在config/app.php中创建的服务提供程序

App'Providers'CustomValidatorServiceProvider::class,

您已经可以删除或注释ValidationServiceProvider

Illuminate'Validation'ValidationServiceProvider::class,

您可以将validator规则添加到Request类中,例如:

public function validator('Illuminate'Contracts'Validation'Factory $factory)
{
    $this->addExtraRules($factory);
    return $factory->make(
        $this->all(), $this->container->call([$this, 'rules']),
        $this->messages(), $this->attributes()
    );
}

现在您需要实现addExtraRules方法,例如:

protected function addExtraRules('Illuminate'Contracts'Validation'Factory $validator)
{
    $validator->extendImplicit('equals_2',
        function ($attribute, $value, $parameters, $validator) {
           return $value == 2;
        });
}

关于这个错误:App'Http'Requests'FooRequest,请确保您已经在FooRequest类文件中这样定义了名称空间:

namespace App'Http'Requests;