Laravel定制服务提供商用于验证器

Laravel定制服务提供商用于验证器

问题描述:

I want to override a method (isValidatable) in the Illuminate\Validation\Validator class. I have done this by creating a class (outside Illuminate) that extends the Validator and only overrides the isValidatable method.

I think this will work, except I'm not sure how to create the service provider for the Validator class (or actually CustomLaravelValidator class). I have created service providers before, but there seems to be going on a lot inside the Validator serviceprovider (Illuminate\Validation\ValidationServiceProvider). Therefore I don't have a clue on how my custom service provider for this class should look like.

This is my CustomLaravelValidator class:

<?php namespace API\Extensions\Core;

use Illuminate\Validation\Validator;

class CustomLaravelValidator extends Validator {

    /**
     * Determine if the attribute is validatable.
     *
     * @param  string  $rule
     * @param  string  $attribute
     * @param  mixed   $value
     * @return bool
     */
    protected function isValidatable($rule, $attribute, $value)
    {
        // Validate integers on empty strings as well
        if($rule == 'IntStrict')
        {
            return true;
        }
        return $this->presentOrRuleIsImplicit($rule, $attribute, $value) &&
        $this->passesOptionalCheck($attribute);
    }

}

This is the default ValidationServiceProvider from Laravel:

<?php namespace Illuminate\Validation;

use Illuminate\Support\ServiceProvider;

class ValidationServiceProvider extends ServiceProvider {

    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = true;

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->registerPresenceVerifier();

        $this->app->bindShared('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['validation.presence']))
            {
                $validator->setPresenceVerifier($app['validation.presence']);
            }

            return $validator;
        });
    }

    /**
     * Register the database presence verifier.
     *
     * @return void
     */
    protected function registerPresenceVerifier()
    {
        $this->app->bindShared('validation.presence', function($app)
        {
            return new DatabasePresenceVerifier($app['db']);
        });
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return array('validator', 'validation.presence');
    }

}

Can anyone tell me how my custom serviceprovider have to look like?

Your service provider doesn't need to mimic the native Validator service provider. You just need to register your custom validator using the resolver method on the validator factory.

use API\Extensions\Core\CustomLaravelValidator;

class CustomValidationServiceProvider extends ServiceProvider {

    public function boot()
    {
        $this->app['validator']
             ->resolver(function($translator, $data, $rules, $messages)
        {
            return new CustomLaravelValidator(
                $translator, 
                $data, 
                $rules, 
                $messages
            );
        });
    }
}

That's it...