0

I have a Livewire Component Import.php:

<?php

namespace Modules\Donor\app\Livewire\Modals;

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Str;
use Laravel\Pennant\Feature;
use Livewire\Attributes\Validate;
use Livewire\Component;
use Livewire\WithFileUploads;
use Maatwebsite\Excel\Facades\Excel;
use Modules\Batch\App\Models\Batchable;
use Modules\Donor\App\Notifications\ImportNotification;
use Modules\Donor\Imports\DonorsImport;
use Modules\MailCode\App\Features\ImportNotificationFeature;
use Modules\MailCode\App\Models\MailCode;
use Modules\User\App\Models\User;

class Import extends Component
{
    use WithFileUploads;

    #[Validate(['required', 'file', 'mimes:csv,xlsx', 'max:131072'])] // 128MB
    public $file;

    public $filename;

    #[Validate()]
    public $mail_group;

    public $mail_code;

    public $number_records;

    public $upload_date;

    public $pro_forma_cost;

    public $final_cost;

    public $listeners = [
        'refresh' => '$refresh',
    ];

    public function render()
    {
        return view('donor::livewire.modals.import');
    }

    /**
     * Refresh livewire component
     */
    public function refresh()
    {
        $this->reset();
        $this->dispatch('refresh');
    }

    /**
     * Extract the file name about to be uploaded and send to parse function
     */
    public function updatedFile()
    {
        // Get the filename from the uploaded file
        if ($this->file) {
            $this->filename = $this->file->getClientOriginalName();

            // Example: Parse the filename and fill other form fields
            $this->parseFilename($this->filename);
        }
    }

    /**
     * Parse file name in order to prefill other inputs
     */
    private function parseFilename(string $filename)
    {
        // Parsing file into parts for filling inputs
        $filenameWithoutExtension = substr(basename($filename), 0, strrpos(basename($filename), '.'));
        $parts = explode('_', $filenameWithoutExtension);

        // Example Filename: IGN_IGN47_0301_Qty10359_Finders
        if (count($parts) >= 4) {
            $this->mail_group = substr($parts[1], 0, 3);
            $this->mail_code = substr($parts[1], 0, strpos($parts[1], 'ph') !== false ? strpos($parts[1], 'ph') : strlen($parts[1]));
            foreach ($parts as $key => $part) {
                if (stripos($part, 'qty') !== false) {
                    $this->number_records = str_ireplace('qty', '', $part);
                }
            }
        }
    }

    public function import()
    {
        $this->validate();

        // Check for duplicates
        $duplicate = MailCode::where('mail_group', $this->mail_group)
            ->where('mail_code', $this->mail_code)
            ->where('number_records', $this->number_records)
            ->where('file_name', $this->filename)
            ->first();

        if ($duplicate) {
            session()->flash('error', 'A record with the same mail group, mail code, number of records, and file name already exists.');

            return;
        }

        // Proceed with import if no duplicates are found.
        activity('donors.import')->log("Importing file: {$this->filename}");

        // Generate one UUID for the entire file
        $batch = Batchable::create([
            'number' => (string) Str::uuid(),
        ]);

        Excel::import(new DonorsImport($batch->number), $this->file); // Import the file.

        // Notifications.
        if (Feature::active(ImportNotificationFeature::class)) {
            $data = [
                'batch' => 1000,
                'start' => session('import.start'),
                'end' => session('import.end'),
                'lines' => [
                    ['type' => 'line', 'value' => 'Your file: '.$this->filename.' has been uploaded sucessfully!'],
                    ['type' => 'line', 'value' => 'The importing of this file will begin soon and we will update you once it has been completed.'],
                    ['type' => 'action', 'text' => 'View Import Progress', 'url' => config('app.url').'/mailcode'],
                    ['type' => 'line', 'value' => 'Thank you for using '.config('app.name').'!'],
                ],
            ];
            $user = User::find(Auth::id());

            Notification::send($user, new ImportNotification($data));
        }

        $mailCode = MailCode::create([
            'mail_group' => $this->mail_group,
            'mail_code' => $this->mail_code,
            'number_records' => $this->number_records,
            'upload_date' => now()->toDateString(),
            'pro_forma_cost' => $this->pro_forma_cost,
            'final_cost' => $this->final_cost,
            'file_name' => $this->filename,
        ]);

        $batch->update([
            'batchable_id' => $mailCode->id,
            'batchable_type' => get_class($mailCode),
        ]);

        $this->refresh();

        session()->flash('status', 'File Uploaded and Mail Code created successfully.');

        $this->close();

        // Check if the request is coming from /donors and redirect if so
        if (str_contains(request()->headers->get('referer'), '/donors')) {
            return redirect()->to('/mailcode');
        }
    }

    public function close(): void
    {
        $this->reset('file');
    }

    /**
     * Define the validation rules
     */
    protected function rules(): array
    {
        return [
            'mail_group' => 'required|string|max:10',
            'mail_code' => 'required|string|max:10',
            'number_records' => 'required|string|max:15',
            // 'upload_date' => 'required|date',
            'pro_forma_cost' => 'nullable|string|max:50',
            'final_cost' => 'nullable|string|max:50',
        ];
    }
}

With Blade View import.blade.php:

<form enctype="multipart/form-data" wire:submit="import">
    <div aria-hidden="true" aria-labelledby="staticBackdropLabel" class="modal fade" data-bs-backdrop="static"
        id="import-donors" style="display: none;" tabindex="-1" wire:ignore.self x-data="{ uploading: false, progress: 0 }"
        x-on:livewire-upload-cancel="uploading = false" x-on:livewire-upload-error="uploading = false"
        x-on:livewire-upload-finish="uploading = false"
        x-on:livewire-upload-progress="progress = $event.detail.progress" x-on:livewire-upload-start="uploading = true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header bg-primary">
                    <h5 class="modal-title text-white" id="staticBackdropLabel">{{ __('Import') }}</h5>
                    <button aria-label="{{ __('Close') }}" class="btn p-1" data-bs-dismiss="modal" type="button">
                        <span class="fas fa-times fs--1 text-white"></span>
                    </button>
                </div>

                <div class="modal-body">
                    <x-alert />

                    <div class="row mb-3">
                        <div class="-mb-3">
                            <input class="form-control" id="file" type="file" wire:model="file" />
                            @error('file')
                                <div class="form-text">{{ $message }}</div>
                            @enderror
                        </div>

                        {{-- <div wire:loading wire:target="file">Uploading...</div> --}}
                        <!-- Progress Bar -->
                        <div x-show="uploading">
                            <progress class="w-100 m-0 pt-1" max="100" x-bind:value="progress"></progress>
                        </div>
                    </div>

                    <div class="row">
                        <div class="mb-3 col-md-4">
                            <input class="form-control" id="mail_group" placeholder="{{ __('Mail Group') }}" type="text"
                                wire:model.blur="mail_group" required />
                            @error('mail_group')
                                <div class="form-text">{{ $message }}</div>
                            @enderror
                        </div>

                        <div class="mb-3 col-md-4">
                            <input class="form-control" id="mail_code" placeholder="{{ __('Mail Code') }}" type="text"
                                wire:model.blur="mail_code" required />
                            @error('mail_code')
                                <div class="form-text">{{ $message }}</div>
                            @enderror
                        </div>

                        {{-- <div class="mb-3 col-md-4">
                            <input class="form-control" id="upload_date" placeholder="{{ __('Upload Date') }}" type="date"
                                wire:model.blur="upload_date" required />
                            @error('upload_date')
                                <div class="form-text">{{ $message }}</div>
                            @enderror
                        </div> --}}

                        <div class="mb-3 col-md-4">
                            <input class="form-control" id="pro_forma_cost" placeholder="{{ __('Pro Forma Cost') }}" type="text"
                                wire:model.blur="pro_forma_cost" />
                            @error('pro_forma_cost')
                                <div class="form-text">{{ $message }}</div>
                            @enderror
                        </div>

                        <div class="mb-3 col-md-4">
                            <input class="form-control" id="final_cost" placeholder="{{ __('Final Cost') }}" type="text"
                                wire:model.blur="final_cost" />
                            @error('final_cost')
                                <div class="form-text">{{ $message }}</div>
                            @enderror
                        </div>

                        <div class="mb-3 col-md-4">
                            <input class="form-control" id="number_records" placeholder="{{ __('# of Records') }}" type="text"
                                wire:model.blur="number_records" required />
                            @error('number_records')
                                <div class="form-text">{{ $message }}</div>
                            @enderror
                        </div>
                    </div>

                </div>

                <div class="modal-footer">
                    <button class="btn btn-primary" type="submit" wire:loading.attr="disabled">
                        <span wire:loading.remove>
                            <i aria-hidden="true" class="fa fa-paper-plane"></i>
                            Submit
                        </span>

                        <span wire:loading>
                            <i aria-hidden="true" class="fa fa-spinner fa-spin"></i>
                            Submitting...
                        </span>
                    </button>

                    <button class="btn btn-outline-primary" data-bs-dismiss="modal" type="button" wire:click="close"
                        wire:loading.attr="disabled">
                        <i aria-hidden="true" class="fa fa-times-circle"></i>
                        Cancel
                    </button>
                </div>

                {{-- @csrf --}}
            </div>
        </div>
    </div>
</form>

The Issue

The issue I am facing is that when I select a file, the /upload-file route is not triggered. Therefore, the updatedFile() function is not triggered.

Additional Info / Current Troubleshooting

  1. This laravel 11 app is running in Docker.
  2. When I mount the volume to my local directory, everything works fine, but when I do not mount it, it does not work.
  3. I have run multiple checks to find the difference in environment between my local system and the Docker container and cannot find anything different that would be relevant to the problem.
  4. Livewire is correctly applied (I can run Livewire in the Dev Console and it works.
  5. File and Directory permissions are all correct and it is able to write to the storage/framework/livewire-tmp directory (even though it does not when not working).
  6. No errors in the Error Log and no other indications from anything else.

Any help to point me in the right direction for further troubleshooting would be amazing!

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.