/laravel-validation-rules

A set of useful Laravel validation rules

Primary LanguagePHP

A set of useful Laravel validation rules

Latest Version on Packagist Tests Total Downloads

This repository contains some useful Laravel validation rules.

Installation

You can install the package via composer:

composer require spatie/laravel-validation-rules

The package will automatically register itself.

Translations

If you wish to edit the package translations, you can run the following command to publish them into your resources/lang folder

php artisan vendor:publish --provider="Spatie\ValidationRules\ValidationRulesServiceProvider"

Available rules

Authorized

Determine if the user is authorized to perform an ability on an instance of the given model. The id of the model is the field under validation

Consider the following policy:

class ModelPolicy
{
    use HandlesAuthorization;

    public function edit(User $user, Model $model): bool
    {
        return $model->user->id === $user->id;
    }
}

This validation rule will pass if the id of the logged in user matches the user_id on TestModel who's it is in the model_id key of the request.

// in a `FormRequest`

use Spatie\ValidationRules\Rules\Authorized;

public function rules()
{
    return [
        'model_id' => [new Authorized('edit', TestModel::class)],
    ];
}

Optionally, you can provide an authentication guard as the third parameter.

new Authorized('edit', TestModel::class, 'guard-name')

Model resolution

If you have implemented the getRouteKeyName method in your model, it will be used to resolve the model instance. For further information see Customizing The Default Key Name

CountryCode

Determine if the field under validation is a valid 2 letter ISO3166 country code (example of valid country codes: GB, DK, NL).

Note that this rule require the package league/iso3166 to be installed: composer require league/iso3166

// in a `FormRequest`

use Spatie\ValidationRules\Rules\CountryCode;

public function rules()
{
    return [
        'country_code' => ['required', new CountryCode()],
    ];
}

If you want to validate a nullable country code field, you can call the nullable() method on the CountryCode rule. This way null and 0 are also passing values:

// in a `FormRequest`

use Spatie\ValidationRules\Rules\CountryCode;

public function rules()
{
    return [
        'country_code' => [(new CountryCode())->nullable()],
    ];
}

Currency

Determine if the field under validation is a valid 3 letter ISO4217 currency code (example of valid currencies: EUR, USD, CAD).

Note that this rule require the package league/iso3166 to be installed: composer require league/iso3166

// in a `FormRequest`

use Spatie\ValidationRules\Rules\Currency;

public function rules()
{
    return [
        'currency' => ['required', new Currency()], // Must be present and a valid currency
    ];
}

If you want to validate a nullable currency field, simple do not let it be required as described in the Laravel Docs for implicit validation rules:

... when an attribute being validated is not present or contains an empty string, normal validation rules, including custom rules, are not run

// in a `FormRequest`

use Spatie\ValidationRules\Rules\Currency;

public function rules()
{
    return [
        'currency' => [new Currency()], // This will pass for any valid currency, an empty value or null
    ];
}

Enum

This rule will validate if the value under validation is part of the given enum class. We assume that the enum class has a static toArray method that returns all valid values. If you're looking for a good enum class, take a look at spatie/enum or myclabs/php-enum.

Consider the following enum class:

class UserRole extends MyCLabs\Enum\Enum
{
    const ADMIN = 'admin';
    const REVIEWER = 'reviewer';
}

The Enum rule can be used like this:

// in a `FormRequest`

use Spatie\ValidationRules\Rules\Enum;

public function rules()
{
    return [
        'role' => [new Enum(UserRole::class)],
    ];
}

The request will only be valid if role contains ADMIN or REVIEWER.

ModelsExist

Determine if all of the values in the input array exist as attributes for the given model class.

By default the rule assumes that you want to validate using id attribute. In the example below the validation will pass if all model_ids exist for the Model.

// in a `FormRequest`

use Spatie\ValidationRules\Rules\ModelsExist;

public function rules()
{
    return [
        'model_ids' => ['array', new ModelsExist(Model::class)],
    ];
}

You can also pass an attribute name as the second argument. In the example below the validation will pass if there are users for each email given in the user_emails of the request.

// in a `FormRequest`

use Spatie\ValidationRules\Rules\ModelsExist;

public function rules()
{
    return [
        'user_emails' => ['array', new ModelsExist(User::class, 'emails')],
    ];
}

Delimited

This rule can validate a string containing delimited values. The constructor accepts a rule that is used to validate all separate values.

Here's an example where we are going to validate a string containing comma separated email addresses.

// in a `FormRequest`

use Spatie\ValidationRules\Rules\Delimited;

public function rules()
{
    return [
        'emails' => [new Delimited('email')],
    ];
}

Here's some example input that passes this rule:

  • 'sebastian@example.com, alex@example.com'
  • ''
  • 'sebastian@example.com'
  • 'sebastian@example.com, alex@example.com, brent@example.com'
  • ' sebastian@example.com , alex@example.com , brent@example.com '

This input will not pass:

  • '@example.com'
  • 'nocomma@example.com nocommatoo@example.com'
  • 'valid@example.com, invalid@'

Setting a minimum

You can set minimum amout of items that should be present:

(new Delimited('email'))->min(2)
  • 'sebastian@example.com, alex@example.com' // passes
  • 'sebastian@example.com' // fails

Setting a maximum

(new Delimited('email'))->max(2)
  • 'sebastian@example.com' // passes
  • 'sebastian@example.com, alex@example.com, brent@example.com' // fails

Allowing duplicate items

By default the rule will fail if there are duplicate items found.

  • 'sebastian@example.com, sebastian@example.com' // fails

You can allowing duplicate items like this:

(new Delimited('numeric'))->allowDuplicates()

Now this will pass: 1,1,2,2,3,3

Customizing the separator

(new Delimited('email'))->separatedBy(';')
  • 'sebastian@example.com; alex@example.com; brent@example.com' // passes
  • 'sebastian@example.com, alex@example.com, brent@example.com' // fails

Skip trimming of items

(new Delimited('email'))->doNotTrimItems()
  • 'sebastian@example.com,freek@example.com' // passes
  • 'sebastian@example.com, freek@example.com' // fails
  • 'sebastian@example.com , freek@example.com' // fails

Composite rules

The constructor of the validator accepts a validation rule string, a validate instance, or an array.

new Delimited('email|max:20')
  • 'short@example.com' // passes
  • 'invalid' // fails
  • 'loooooooonnnggg@example.com' // fails

Passing custom error messages

The constructor of the validator accepts a custom error messages array as second parameter.

// in a `FormRequest`

use Spatie\ValidationRules\Rules\Delimited;

public function rules()
{
    return [
        'emails' => [new Delimited('email', $this->messages())],
    ];
}

public function messages()
{
    return [
        'emails.email' => 'Not all the given e-mails are valid.',
    ];
}

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you've found a bug regarding security please mail laravelloversofficial@gmail.com instead of using the issue tracker.