fanpero87's avatar

Per row validation while importing CSV file

Hello,

I'm Importing a CSV file to a livewire component and trying to run some validation for each row of the file but I'm having problems doing this. It seems that my validation is doing nothing.

Here is how my Livewire component looks like:

namespace App\Http\Livewire\Modals;

use Validator;
use Livewire\Component;
use App\Http\Traits\Csv;
use App\Models\AccountUser;
use Livewire\WithFileUploads;
use Illuminate\Support\Facades\Auth;

class ImportExtensions extends Component
{

use WithFileUploads;

public $clientID;
public $showModal = false;
public $upload;
public $columns;
public $fieldColumnMap = [
    'first_name' => '',
    'last_name' => '',
    'email' => '',
    'password' => '',
    'extension' => '',
    'user_type' => '',
];

protected $rules = [
        'fieldColumnMap.first_name' => 'required|max:255',
        'fieldColumnMap.last_name' => 'required|max:255',
        'fieldColumnMap.email' => 'required|max:255',
        'fieldColumnMap.password' => 'required|max:255',
        'fieldColumnMap.extension' => 'required|max:255',
        'fieldColumnMap.user_type' => 'required|max:255',
];

protected $validationAttributes = [
    'fieldColumnMap.first_name' => 'First Name',
    'fieldColumnMap.last_name' => 'Last Name',
    'fieldColumnMap.email' => 'Email',
    'fieldColumnMap.password' => 'Password',
    'fieldColumnMap.extension' => 'Extension',
    'fieldColumnMap.user_type' => 'User Type',
];

public function updatingUpload($value)
{
    Validator::make(
        ['upload' => $value],
        ['upload' => 'required|mimes:txt,csv'],
    )->validate();
}

public function updatedUpload()
{
    $this->columns = Csv::from($this->upload)->columns();
    $this->guessWhichColumnsMapToWhichFields();
}

public function import()
{
    // Validate that you are importing any data
    $this->validate();

    $importCount = 0;
    Csv::from($this->upload)
    ->eachRow( function ($row) use (&$importCount){
        $eachRow = $this->extractFieldsFromRow($row);

		//Validate the data of each Row to make to make sure you don't import duplicate records   
        $this->validateOnly(collect($eachRow), [
            'fieldColumnMap.first_name' => 'required|max:255',
            'fieldColumnMap.last_name' => 'required|max:255',
            'fieldColumnMap.email' => 'required|max:255|email|unique:account_users, email',
            'fieldColumnMap.extension' => 'required|numeric|unique:account_users, extension',
            'fieldColumnMap.password' => 'required|max:255',
            'fieldColumnMap.user_type' => 'required|in:user,admin',
        ]);

        //If validation fails, it should skip the create extension part and run the next row

		//If validation pass, then create the Extension
        AccountUser::create([
            'user_id' => Auth::user()->id,
            'account_id' => $this->clientID,
            'first_name' => $eachRow['first_name'],
            'last_name' => $eachRow['last_name'],
            'email' => $eachRow['email'],
            'password' => $eachRow['password'],
            'extension' => $eachRow['extension'],
            'user_type' => $eachRow['user_type'],
        ]);
        $importCount++;
    });
    $this->reset();
    $this->emit('refreshExtensions');
    $this->notify('Successfully Imported '.$importCount.' Extensions');
}

Also, how can I make so that if the validation fails it goes to the next row instead of trying to create the extension.

Thanks.

0 likes
1 reply
fanpero87's avatar
fanpero87
OP
Best Answer
Level 11

I was able to created a custom Validation rule for this case and just throw an error if any row fails. Basically, or all rows pass or all fails. Here is how it looks like now:

public function import()
{
    // Validate that you are importing any data
    $this->validate();

    $importCount = 0;
    Csv::from($this->upload)
    ->eachRow( function ($row) use (&$importCount){
        $eachRow = $this->extractFieldsFromRow($row);

        $validatedData = Validator::make([
            'first_name' => $eachRow['first_name'],
            'last_name' => $eachRow['last_name'],
            'email' => $eachRow['email'],
            'password' => $eachRow['password'],
            'extension' => $eachRow['extension'],
            'user_type' => $eachRow['user_type'],
            ],[
            'first_name' => 'required',
            'last_name' => 'required',
            'email' => 'required|email|unique:account_users',
            'extension' => 'required|numeric|unique:account_users',
            'password' => 'required|max:255',
            'user_type' => 'required|in:user,admin',
        ],);

        if($validatedData->fails()){
            $this->notify(['error','Oops something went wrong!']);
        }else{
            AccountUser::create([
                'user_id' => Auth::user()->id,
                'account_id' => $this->clientID,
                'first_name' => $eachRow['first_name'],
                'last_name' => $eachRow['last_name'],
                'email' => $eachRow['email'],
                'password' => $eachRow['password'],
                'extension' => $eachRow['extension'],
                'user_type' => $eachRow['user_type'],
            ]);
            $importCount++;
        }
    });

    $this->reset();
    $this->emit('refreshExtensions');
    if($importCount!=0) $this->notify(['success','Successfully Imported '.$importCount.' Extensions']);
}
1 like

Please or to participate in this conversation.