Skip to content

Latest commit

 

History

History
516 lines (400 loc) · 16.1 KB

validation.md

File metadata and controls

516 lines (400 loc) · 16.1 KB

Validation

⬆️ Menú principal ⬅️ Anterior (Routing) ➡️ Siguiente (Collections)

Image validation

Mientras validamos imagenes, puedes especificar las dimensiones que necesites.

['photo' => 'dimensions:max_width=4096,max_height=4096']

Add Values to the Form Request After Validation

class UpdatedBookRequest extends FormRequent
{
     public function validated()
     {
          return array_merge(parent::validated(), [
               'user_id' => Auth::user()->id,
          ]);
     }
}

Access model binding in FormRequests

Cuando usamos FormRequest, siempre puedes acceder al modelo usnado la siguiente expresión.

Aquí un ejemplo:

class CommunityController extends Controller
{
     // ...
     public function update(CommunityUpdateRequest $request, Community $community)
     {
          $community->update($request->validated());

          return to_route('communities.index')->withMessage('Community updated successfully.');
     }
     // ...
}

class CommunityUpdateRequest extends FormRequest
{
     // ...
     public function rules()
     {
          return [
               'name' => ['required', Rule::unique('communities', 'name')->ignore($this->community)],
               'description' => ['required', 'min:5'],
          ];
     }
     // ...
}

⭐ Aportación de @bhaidar

Rule which ensures the field under validation is required if another field is accepted

Puedes utilizar la regla de validación required_if_accepted, la cual asegura que el campo en validación es requerido si otro campo es aceptado (un valor de yes, on, 1 o true).

Validator::make([
     'is_company' => 'on',
     'company_name' => 'Apple',
], [
     'is_company' => 'required|boolean',
     'company_name' => 'required_if_accepted:is_company',
]);

⭐ Aportación de @iamgurmandeep

Custom validation error messages

Puedes personalizar mensajes de errores por campo, regla y lenguaje. Solo crea un lenguaje nuevo en el archivo resources/lang/xx/validation.php con la apropiada estructura.

'custom' => [
     'email' => [
        'required' => 'We need to know your e-mail address!',
     ],
],

Validate dates with "now" or "yesterday" words

Puedes validar fechas con reglas before/after y pasar varios parametros como: tomorrow, now, yesterday. Ejemplo: 'start_date' => 'after:now'. Usa el método strtotime() por debajo.

$rules = [
    'start_date' => 'after:tomorrow',
    'end_date' => 'after:start_date'
];

Validation Rule with Some Conditions

SI tus reglas de validación dependen de alguna condición, puedes modificar las reglas añadiendo withValidator() a tu clase FormRequest y especificar tu lógica, por ejemplo si quieres añadir algunas reglas de validaciones para algun rol de usuario.

use Illuminate\Validation\Validator;
class StoreBlogCategoryRequest extends FormRequest {
    public function withValidator(Validator $validator) {
        if (auth()->user()->is_admin) {
            $validator->addRules(['some_secret_password' => 'required']);
        }
    }
}

Change Default Validation Messages

Si quieres cambiar los mensajes de error por defecto para un específico campo y una regla de validación específica, solo añade a tu clase FormRequest el méotodo messages() .

class StoreUserRequest extends FormRequest
{
    public function rules()
    {
        return ['name' => 'required'];
    }

    public function messages()
    {
        return ['name.required' => 'User name should be real name'];
    }
}

Prepare for Validation

Si quieres modificar algunso campos antes de la Vlidación de Laravel, es decir, preparar el campo para cierta lógica, añade a la clase FormRequest el método prepareForValidation().

protected function prepareForValidation()
{
    $this->merge([
        'slug' => Illuminate\Support\Str::slug($this->slug),
    ]);
}

Stop on First Validation Error

Por defecto, los errores de validación serán retornados en una lista,. Pero si quieres parar el proceso de validación después del primer error sobre un campo específico usa la regla de validación bail:

$request->validate([
    'title' => 'bail|required|unique:posts|max:255',
    'body' => 'required',
]);

En la clase FormRequest puedes colocar la propiedad stopOnFirstFailure en true para parar la validaicón de todos los campos:

protected $stopOnFirstFailure = true;

Throw 422 status code without using validate() or Form Request

Si no quieres usar validate() o un FomrRequest, pero aun necesitas lanzar errores con el mismo status 422 y un envíar el error estructuradamente , puedes hacerlo manualmente con throw ValidationException::withMessages()

if (! $user || ! Hash::check($request->password, $user->password)) {
    throw ValidationException::withMessages([
        'email' => ['The provided credentials are incorrect.'],
    ]);
}

Rules depending on some other conditions

Si tus reglas son dinámicas y dependen de otras condiciones, puedes crear el arreglo de reglas en la marcha.

    public function store(Request $request)
    {
        $validationArray = [
            'title' => 'required',
            'company' => 'required',
            'logo' => 'file|max:2048',
            'location' => 'required',
            'apply_link' => 'required|url',
            'content' => 'required',
            'payment_method_id' => 'required'
        ];

        if (!Auth::check()) {
            $validationArray = array_merge($validationArray, [
                'email' => 'required|email|unique:users',
                'password' => 'required|confirmed|min:5',
                'name' => 'required'
            ]);
        }
        //
    }

With Rule::when() we can conditionally apply validation rules

Gracias a la regla Rule::when() podemos condicionalmente aplicar reglas de validación en Laravel.

En este ejemplo validamos el valor del campo voto solo si el usuario tiene permisos para participar.

use Illuminate\Validation\Rule;

public function rules()
{
    return [
        'vote' => Rule::when($user->can('vote', $post), 'required|int|between:1,5'),
    ]
}

⭐ Aportación de @cerbero90

Use this property in the request classes to stop the validation of the whole request attributes

Utiliza esta propiedad en las clases de solicitud para detener la validación de todos los atributos de la solicitud.

Pista Directa

Esto es diferente de la regla Bail, que detiene la validación de un solo atributo si una de sus reglas no se cumple.

/**
 * Indica si el validator debería parar todas las validaciones cuando falla una sola regla.
 */
protected $stopOnFirstFailure = true;

⭐ Aportación de @Sala7JR

Rule::unique doesn't take into the SoftDeletes Global Scope applied on the Model

Es extraño que Rule::unique no tenga en cuenta el alcance global de SoftDeletes aplicado al modelo de forma predeterminada.

Sin embargo, el método withoutTrashed() está disponible.

Rule::unique('users', 'email')->withoutTrashed();

Tip given by @Zubairmohsin33 ⭐ Aportación de @Zubairmohsin33

Validator::sometimes() method allows us to define when a validation rule should be applied

El método Validator::sometimes() nos permite definir cuando una regla de validación debe ser aplicada, basada en los parametros pasados.

$data = [
    'coupon' => 'PIZZA_PARTY',
    'items' => [
        [
            'id' => 1,
            'quantity' => 2
        ],
        [
            'id' => 2,
            'quantity' => 2,
        ],
    ],
];

$validator = Validator::make($data, [
    'coupon' => 'exists:coupons,name',
    'items' => 'required|array',
    'items.*.id' => 'required|int',
    'items.*.quantity' => 'required|int',
]);

$validator->sometimes('coupon', 'prohibited', function (Fluent $data) {
    return collect($data->items)->sum('quantity') < 5;
});

// throws a ValidationException as the quantity provided is not enough
$validator->validate();

⭐ Aportación de @cerbero90

Array elements validation

Si quieres validar los elementos dentro de cada posición de un arreglo usa la palabra * en las reglas:

// say you have this array
// array in request 'user_info'
$request->validated()->user_info = [
    [
        'name' => 'Qasim',
        'age' => 26,
    ],
    [
        'name' => 'Ahmed',
        'age' => 23,
    ],
];

// Rule
$rules = [
    'user_info.*.name' => ['required', 'alpha'],
    'user_info.*.age' => ['required', 'numeric'],
];

⭐ Aportación de HydroMoon

Password::defaults method

Puedes especificar algunas reglas cuando validamos contraseñas usando el método Password::defaults . Incluye opciones para letras, simbolos y más.

class AppServiceProvider
{
    public function boot(): void
    {
        Password::defaults(function () {
            return Password::min(12)
                ->letters()
                ->numbers()
                ->symbols()
                ->mixedCase()
                ->uncompromised();
        })
    }
}

request()->validate([
    ['password' => ['required', Password::defaults()]]
])

⭐ Aportación de @mattkingshott

Form Requests for validation redirection

Cuando usamos FormRequest para validaciones, por defecto los errores de validación serán redireccionados a la página anterior, pero puedes sobrescribirla. SOlo define la propiedad $redirect o $redirectRoute.

// La URI que el usuario debería ser redireccionado si la validación falla
protected $redirect = '/dashboard';

// La ruta que los uusarios deberían ser redireccionados si la validación falla
protected $redirectRoute = 'dashboard';

Mac validation rule

En Laravel 8.77 se han agregado reglas de validación para direcciones MAC .

$trans = $this->getIlluminateArrayTranslator();
$validator = new Validator($trans, ['mac' => '01-23-45-67-89-ab'], ['mac' => 'mac_address']);
$this->assertTrue($validator->passes());

⭐ Aportación de @Teacoders

Validate email with TLD domain required

Por defecto, las reglas de validación para los email aceptarán un email sin un tld dominio,

Pero si quieres asegurarte que el email tenga un tld dominio, usa la regla email:filter .

[
    'email' => 'required|email', // before
    'email' => 'required|email:filter', // after
],

⭐ Aportación de @Chris1904

New array validation rule required_array_keys

Laravel 8.82 añade una regla de validación required_array_keys que verifica que todos las llaves(keys) de un arreglo existan.

$data = [
    'baz' => [
        'foo' => 'bar',
        'fee' => 'faa',
        'laa' => 'lee'
    ],
];

$rules = [
    'baz' => [
        'array',
        'required_array_keys:foo,fee,laa',
    ],
];

$validator = Validator::make($data, $rules);
$validator->passes(); // true

Datos que estén en la validación pero no se encuentren en el arreglo aunque todos los demás sí, fallarían la validaición:

$data = [
    'baz' => [
        'foo' => 'bar',
        'fee' => 'faa',
    ],
];

$rules = [
    'baz' => [
        'array',
        'required_array_keys:foo,fee,laa',
    ],
];

$validator = Validator::make($data, $rules);
$validator->passes(); // false

⭐ Aportación de @AshAllenDesign

Position placeholder in validation messages

En Laravel 9 puedes usar el atributo :position en los mensjaes de validación si esque estas trabajando con arreglos.

En este ejemplo el resultado sería "Porfavor provee una cantidad para el precio #2".

class CreateProductRequest extends FormRequest
{
    public function rules(): array
    {
        return  [
            'title' => ['required', 'string'];
            'description' => ['nullable', 'sometimes', 'string'],
            'prices' => ['required', 'array'],
            'prices.*.amount' => ['required', 'numeric'],
            'prices.*.expired_at' => ['required', 'date'],
        ];
    }

    public function messages(): array
    {
        'prices.*.amount.required' => 'Please provide an amount for price #:position'
    }
}

⭐ Aportación de @mmartin_joo

Exclude validation value

Cuando necesitas validar un campo, pero en realidad no lo necesitas más adelante, por ejemplo el campo marcado 'Acepto terminos y condiciones', asegurate de usar la regla exclude. De esta menera el método validated no lo regresará.

class StoreRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'name' => 'required|string',
            'email_address' => 'required|email',
            'terms_and_conditions' => 'required|accepted|exclude',
        ];
    }
class RegistrationController extends Controller
{
    public function store(StoreRequest $request)
    {
        $payload = $request->validated(); // only name and email

        $user = User::create($payload);

        Auth::login($user);

        return redirect()->route('dashboard');
    }

⭐ Aportación de @mattkingshott