Laravel-excel: validation rules reference other field

Created on 2 Apr 2020  路  7Comments  路  Source: Maatwebsite/Laravel-Excel

Prerequisites

  • [X] Checked if your Laravel Excel version is still supported: https://docs.laravel-excel.com/3.1/getting-started/support.html#supported-versions
  • [X] Able to reproduce the behaviour outside of your code, the problem is isolated to Laravel Excel.
  • [X] Checked that your issue isn't already filed.
  • [X] Checked if no PR was submitted that fixes this problem.
  • [X] Filled in the entire issue template

Versions

  • PHP version: 7.2.8
  • Laravel version: Laravel Framework 7.3.0
  • Package version: 3.1

    Description

Hi everybody,

Is there any way to build validation rules based on other field content?

For example:

  • row['phone'] required if row['mobile鈥橾 is null,

  • row['postCode'] max:4 if row['country] == Belgium and row['postCode'] max:5 if row['country] == France..

I know the way to do this in laravel validation but i can't catch the current vlaidate row values.

I implements ToModel, WithValidation, WithHeadingRow.

Thx.

question

Most helpful comment

I've been able to implement multi-attribute validation by creating a validator extension. Create a validator class like this:

<?php

namespace App\Services\Validators;

use Illuminate\Validation\Validator;

class MyValidator
{
    /**
     * @param  string  $attribute
     * @param  string  $value
     * @param  array  $parameters
     * @param  Validator  $validator
     *
     * @return bool
     */
    public function validate($attribute, $value, $parameters, Validator $validator)
    {
        $attributes = $validator->attributes();
        $attributes = $attributes[array_key_first($attributes)];

        $isValid = ('some condition' === $attributes['attribute_1']
                        && 'another condition' === $attributes['attribute_2']);

        return $isValid;
    }
}

In your AppServiceProvider, add something like this to your boot() method:

Validator::extend(
    'my_validator',
    'App\Services\Validators@validate',
    'Failed MyValidator validation'
);

Finally, in your rules() array, add the name you've given to your validator, e.g.

public function rules(): array
{
    return [
        'attribute_1' => [
            'string',
            'required',
            'my_validator',
        ],
    ];
}

All 7 comments

Thanks for submitting the ticket. Unfortunately the information you provided is incomplete. We need to know which version you use and how to reproduce it. Please include code examples. Before we can pick it up, please check (https://github.com/Maatwebsite/Laravel-Excel/blob/3.1/.github/ISSUE_TEMPLATE.md) and add the missing information. To make processing of this ticket a lot easier, please make sure to check (https://laravel-excel.maatwebsite.nl/3.1/getting-started/contributing.html) and double-check if you have filled in the issue template correctly. This will allow us to pick up your ticket more efficiently. Issues that follow the guidelines correctly will get priority over other issues.

Sorry that isn't possible with WithValidation

Thank you for your unbelievable job @patrickbrouwers ...
It's pity, but is there any way to manually trigger a failure?

You could put the validator inside your toModel method (like normal Laravel validator usage)

Yea I have the same issue. If we did the validation in the toModel method and it fails, would those still get appended to the failures collection of the import?

Not 100% sure, give it a try.

I've been able to implement multi-attribute validation by creating a validator extension. Create a validator class like this:

<?php

namespace App\Services\Validators;

use Illuminate\Validation\Validator;

class MyValidator
{
    /**
     * @param  string  $attribute
     * @param  string  $value
     * @param  array  $parameters
     * @param  Validator  $validator
     *
     * @return bool
     */
    public function validate($attribute, $value, $parameters, Validator $validator)
    {
        $attributes = $validator->attributes();
        $attributes = $attributes[array_key_first($attributes)];

        $isValid = ('some condition' === $attributes['attribute_1']
                        && 'another condition' === $attributes['attribute_2']);

        return $isValid;
    }
}

In your AppServiceProvider, add something like this to your boot() method:

Validator::extend(
    'my_validator',
    'App\Services\Validators@validate',
    'Failed MyValidator validation'
);

Finally, in your rules() array, add the name you've given to your validator, e.g.

public function rules(): array
{
    return [
        'attribute_1' => [
            'string',
            'required',
            'my_validator',
        ],
    ];
}
Was this page helpful?
0 / 5 - 0 ratings