php - validaciones - validar campo unico laravel
Cómo agregar reglas de validación personalizadas al usar la validación de solicitud de formulario en Laravel 5 (7)
El uso de Validator::extend()
como usted lo hace está realmente bien, solo tiene que ponerlo en un proveedor de servicios así:
<?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()
{
//
}
}
Luego registre el proveedor agregándolo a la lista en config/app.php
:
''providers'' => [
// Other Service Providers
''App/Providers/ValidatorServiceProvider'',
],
Ahora puede usar la regla de validación numericarray
donde quiera
Estoy utilizando el método de validación de solicitud de formulario para validar solicitud en laravel 5. Me gustaría agregar mi propia regla de validación con el método de validación de solicitud de formulario. Mi clase de solicitud se proporciona a continuación. Deseo agregar validación numérica_array personalizada con elementos de campo.
protected $rules = [
''shipping_country'' => [''max:60''],
''items'' => [''array|numericarray'']
];
Mi función de cusotom se da a continuación
Validator::extend(''numericarray'', function($attribute, $value, $parameters) {
foreach ($value as $v) {
if (!is_int($v)) {
return false;
}
}
return true;
});
¿Cómo se puede utilizar este método de validación con la validación de solicitud de formulario en laravel5?
La respuesta aceptada funciona para reglas de validación globales, pero muchas veces validará ciertas condiciones que son muy específicas para un formulario. Esto es lo que recomiendo en esas circunstancias (que parece ser algo intencionado del código fuente de Laravel en la línea 75 de FormRequest.php ):
Agregue un método de validación al padre. Solicite que se extiendan sus solicitudes:
<?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;
}
}
Ahora todas sus solicitudes específicas se verán así:
<?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!''
];
}
}
No necesita extender el validador para validar los elementos de la matriz, puede validar cada elemento de una matriz con "*" como puede ver en Validación de matriz
protected $rules = [
''shipping_country'' => [''max:60''],
''items'' => [''array''],
''items.*'' => ''integer''
];
Para mí funciona la solución que nos da lukasgeiter, pero con la diferencia de que creamos una clase con nuestras validaciones personalizadas, como esta, para laravel 5.2. * El siguiente ejemplo es para agregar una validación a un rango de fecha donde la segunda fecha tiene que ser igual o más grande que el primero
En la aplicación / Proveedores crea 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
De acuerdo. ahora permite crear el proveedor de servicios. Crear ValidationExtensionServiceProvider.php dentro de la aplicación / Proveedores, y codificamos
<?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
Ahora le pedimos a Laravel que cargue este proveedor de servicios, que se agregue a la matriz de proveedores al final en config / app.php y
//Servicio para extender validaciones
App/Providers/ValidationExtensionServiceProvider::class,
ahora podemos usar esta validación en nuestra solicitud en las reglas de funciones
public function rules()
{
return [
''fDesde'' => ''date'',
''fHasta'' => ''date|after_or_equal:fDesde''
];
}
o en Validator: hacer
$validator = Validator::make($request->all(), [
''fDesde'' => ''date'',
''fHasta'' => ''date|after_or_equal:fDesde''
], $messages);
debe notar que el nombre del método que realiza la validación tiene el prefijo validado y está en el estilo de caja de camello validateAfterOrEqual, pero cuando usa la regla de validación, cada letra mayúscula se reemplaza con un guión bajo y la letra en minúscula.
Todo esto lo tomo de https://www.sitepoint.com/data-validation-laravel-right-way-custom-validators// aquí explico en detalle. gracias a ellos.
Si bien la respuesta anterior es correcta, en muchos casos es posible que desee crear una validación personalizada solo para una determinada solicitud de formulario. Puede aprovechar la solicitud FormRequest de laravel y usar la inyección de dependencia para ampliar la fábrica de validación. Creo que esta solución es mucho más simple que crear un proveedor de servicios.
Aquí es cómo se puede hacer.
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'',
];
}
}
getValidatorInstance
sobrescribir el método getValidatorInstance
en su clase Request
, por ejemplo de esta manera:
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;
}
Objeto de regla personalizado
Una forma de hacerlo es mediante el uso de Custom Rule Object , de esta manera puede definir tantas reglas como desee sin necesidad de hacer cambios en los proveedores y en el controlador / servicio para establecer nuevas reglas.
php artisan make:rule NumericArray
En 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...'';
}
}
Luego, en la solicitud de forma, tenga
use App/Rules/NumericArray;
.
.
protected $rules = [
''shipping_country'' => [''max:60''],
''items'' => [''array'', new NumericArray]
];