web-dev-qa-db-fra.com

Comment ajouter des règles de validation personnalisées lors de l’utilisation de la validation de demande de formulaire dans Laravel 5

J'utilise une méthode de validation de demande de formulaire pour valider une demande dans laravel) validation numeric_array avec des éléments de champ.

  protected $rules = [
      'shipping_country' => ['max:60'],
      'items' => ['array|numericarray']
];

Ma fonction de cusotom est donnée ci-dessous

 Validator::extend('numericarray', function($attribute, $value, $parameters) {
            foreach ($value as $v) {
                if (!is_int($v)) {
                    return false;
                }
            }
            return true;
        });

Comment utiliser cette méthode de validation avec la validation de demande de formulaire dans laravel5?

37
gsk

Utiliser Validator::extend() comme vous le faites est parfaitement bien, il vous suffit de le mettre dans un fournisseur de service comme ceci:

<?php namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class ValidatorServiceProvider extends ServiceProvider {

    public function boot()
    {
        $this->app['validator']->extend('numericarray', function ($attribute, $value, $parameters)
        {
            foreach ($value as $v) {
                if (!is_int($v)) {
                    return false;
                }
            }
            return true;
        });
    }

    public function register()
    {
        //
    }
}

Enregistrez ensuite le fournisseur en l'ajoutant à la liste dans config/app.php:

'providers' => [
    // Other Service Providers

    'App\Providers\ValidatorServiceProvider',
],

Vous pouvez maintenant utiliser la règle de validation numericarray partout où vous le souhaitez

41
lukasgeiter

Bien que la réponse ci-dessus soit correcte, dans de nombreux cas, vous souhaiterez peut-être créer une validation personnalisée uniquement pour une demande de formulaire donnée. Vous pouvez utiliser laravel FormRequest et utiliser l’injection de dépendances pour étendre l’usine de validation. Je pense que cette solution est beaucoup plus simple que de créer un fournisseur de services.

Voici comment cela peut être fait.

use Illuminate\Validation\Factory as ValidationFactory;

class UpdateMyUserRequest extends FormRequest {

    public function __construct(ValidationFactory $validationFactory)
    {

        $validationFactory->extend(
            'foo',
            function ($attribute, $value, $parameters) {
                return 'foo' === $value;
            },
            'Sorry, it failed foo validation!'
        );

    }

    public function rules()
    {
        return [
            'username' => 'foo',
        ];
    }
}
39
Adrian Gunawan

La réponse acceptée fonctionne pour les règles de validation globales, mais vous devrez souvent valider certaines conditions très spécifiques à un formulaire. Voici ce que je recommande dans ces circonstances (cela semble être quelque peu destiné à partir de Laravel à ligne 75 de FormRequest.php ):

Ajoutez une méthode de validation au parent. Vos demandes seront étendues:

<?php namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Validator;

abstract class Request extends FormRequest {

    public function validator(){

        $v = Validator::make($this->input(), $this->rules(), $this->messages(), $this->attributes());

        if(method_exists($this, 'moreValidation')){
            $this->moreValidation($v);
        }

        return $v;
    }
}

Toutes vos demandes spécifiques ressembleront à ceci:

<?php namespace App\Http\Requests;

use App\Http\Requests\Request;

class ShipRequest extends Request {

    public function rules()
    {
        return [
            'shipping_country' => 'max:60',
            'items' => 'array'
        ];
    }

    // Here we can do more with the validation instance...
    public function moreValidation($validator){

        // Use an "after validation hook" (see laravel docs)
        $validator->after(function($validator)
        {
            // Check to see if valid numeric array
            foreach ($this->input('items') as $item) {
                if (!is_int($item)) {
                    $validator->errors()->add('items', 'Items should all be numeric');
                    break;
                }
            }
        });
    }

    // Bonus: I also like to take care of any custom messages here
    public function messages(){
        return [
            'shipping_country.max' => 'Whoa! Easy there on shipping char. count!'
        ];
    }
}
19
prograhammer

Vous devez redéfinir la méthode getValidatorInstance dans votre classe Request, par exemple de cette façon:

protected function getValidatorInstance()
{
    $validator = parent::getValidatorInstance();
    $validator->addImplicitExtension('numericarray', function($attribute, $value, $parameters) {
        foreach ($value as $v) {
            if (!is_int($v)) {
                return false;
            }
        }
        return true;
    });

    return $validator;
}
5
Marcin Nabiałek

Objet de règle personnalisé

Une façon de le faire consiste à utiliser objet règle personnalisé . Vous pouvez ainsi définir autant de règles que vous le souhaitez sans qu'il soit nécessaire de modifier les fournisseurs et le contrôleur/service pour définir de nouvelles règles.

php artisan make:rule NumericArray

Dans NumericArray.php

namespace App\Rules;
class NumericArray implements Rule
{
   public function passes($attribute, $value)
   {
     foreach ($value as $v) {
       if (!is_int($v)) {
         return false;
       }
     }
     return true;
   }


  public function message()
  {
     return 'error message...';
  }
}

Puis dans la demande de formulaire ont

use App\Rules\NumericArray;
.
.
protected $rules = [
      'shipping_country' => ['max:60'],
      'items' => ['array', new NumericArray]
];
4
gk.

Vous n'avez pas besoin d'étendre le validateur pour valider les éléments du tableau, vous pouvez valider chaque élément d'un tableau avec "*" comme vous pouvez le voir dans Validation du tablea

protected $rules = [
      'shipping_country' => ['max:60'],
      'items' => ['array'],
      'items.*' => 'integer'
];
3
Félix Díaz

Pour moi fonctionne la solution qui nous donne lukasgeiter, mais à la différence que nous créons une classe avec nos validations personnalisées, comme celle-ci, pour laravel 5.2. * L’exemple suivant concerne l’ajout d’une validation à une plage de date dans laquelle la deuxième date doit être égale ou plus grande que la première

Dans l'application/les fournisseurs créent ValidatorExtended.php

<?php
namespace App\Providers;
use Illuminate\Validation\Validator as IlluminateValidator;

class ValidatorExtended extends IlluminateValidator {

private $_custom_messages = array(
 "after_or_equal" => ":attribute debe ser una fecha posterior o igual a 
 :date.",
);

public function __construct( $translator, $data, $rules, $messages = array(),      
$customAttributes = array() ) {
  parent::__construct( $translator, $data, $rules, $messages, 
  $customAttributes );
  $this->_set_custom_stuff();
}

protected function _set_custom_stuff() {
   //setup our custom error messages
  $this->setCustomMessages( $this->_custom_messages );
}

/**
 * La fecha final debe ser mayor o igual a la fecha inicial
 *
 * after_or_equal
 */
protected function validateAfterOrEqual( $attribute, $value, $parameters, 
$validator) {
   return strtotime($validator->getData()[$parameters[0]]) <= 
  strtotime($value);
}

}   //end of class

D'accord. permet maintenant de créer le fournisseur de services. Créez ValidationExtensionServiceProvider.php dans l’application/Fournisseurs, et nous codons

<?php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Validator;

class ValidationExtensionServiceProvider extends ServiceProvider {

public function register() {}

public function boot() {
  $this->app->validator->resolver( function( $translator, $data, $rules, 
  $messages = array(), $customAttributes = array() ) {
    return new ValidatorExtended( $translator, $data, $rules, $messages, 
    $customAttributes );
} );
}

}   //end of class

Maintenant, nous devons dire Laravel pour charger ce fournisseur de service, ajouter au tableau des fournisseurs à la fin dans config/app.php et

//Servicio para extender validaciones
App\Providers\ValidationExtensionServiceProvider::class,

maintenant nous pouvons utiliser cette validation dans notre requête en règles de fonctionnement

public function rules()
{
  return [
    'fDesde'     => 'date',
    'fHasta'     => 'date|after_or_equal:fDesde'
 ];
}

ou dans Validator: make

$validator = Validator::make($request->all(), [
    'fDesde'     => 'date',
    'fHasta'     => 'date|after_or_equal:fDesde'
], $messages);

vous devez remarquer que le nom de la méthode qui effectue la validation a le préfixe validate et est dans le style de casse du chameau validateAfterOrEqual, mais lorsque vous utilisez la règle de validation, chaque lettre majuscule est remplacée par un trait de soulignement et la lettre en minuscule.

Tout cela, je le prends de https://www.sitepoint.com/data-validation-laravel-right-way-custom-validators// expliquer ici en détail. Merci à eux.

0
Carolina