Home > Mobile >  TypeError at Exporting CSV and Passing Data to Mail View - Laravel 9
TypeError at Exporting CSV and Passing Data to Mail View - Laravel 9

Time:12-06

I have two problems with Queue Jobs in Laravel 9.

At one job, I'm trying to export some relational data to a .CSV file and want to notify users when exporting is finished. For this task I'm using Jobs.

This is my controller:

  $report = new ExportReport();
  $this->dispatch($report);

This is my Jobs/ExportReport.php file:

<?php

namespace App\Jobs;
use Illuminate\Support\Facades\Mail;
use App\Models\Report;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Storage;

class ExportReport implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;


    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct()
    {

    }

    /**
     * Execute the job.
     * @return $response
     */
    public function handle()
    {
        // Generate our file name
        $filename="Report_Export_" . date("YmdHis") . time() . ".csv";

        // Set the file path to the temporary location
        $handler = Storage::path('public/').$filename;

        // Open file handler for writing output
        $file = fopen($handler, 'w');

        /*
         * Add headers
         */
        $headers = [
            'Inspection Number',
            'Identification of Inspection',
            'Request or Planned Date',
            'Designation of Inspection',
            'Type of Inspection',
            'Inspector Name',
            'Inspector Last Name',
            'Inspection End Date',
            'Result of Inspection',
            'Status of Inspection',
            'Reject Reason',
            'Reason of Cancellation',
            'Comments'
        ];
        fputcsv($file, $headers);

        Report::chunk(1000, function ($reports) use ($headers, $file) {
            foreach ($reports as $report) {
                fputcsv($file, [
                $report->inspection_number,
                $report->identification_of_inspection,
                $report->request_or_planned_date,
                $report->designation_of_inspection,
                $report->type_of_inspection ?? '',
                $report->employee->first_name ?? '',
                $report->employee->last_name ?? '',
                $report->inspection_end_date,
                $report->result_of_inspection->result ?? '',
                $report->status_of_inspection->status ?? '',
                $report->reject_reason->agg ?? '',
                $report->reason_of_cancellation->reason_of_cancellation ?? '',
                $report->comments ?? ''
                ]);
            }
        });

        fclose($file);

        Storage::put('public/', $file );
        Mail::to('[email protected]')->send(new \App\Mail\ExportReport());
    }

}

\App\Mail\ExportReport.php

public function build()
    {
        return $this->markdown('mails.export-report');
    }

These are my problems:

1- I am not able to pass any data to my mail view. I need to pass $filename to link the export file in mail and need to pass auth()->user()->email to know to which user to send.

2- Job exporting the file but everytime it fails with that exception message: TypeError: League\Flysystem\Filesystem::write(): Argument #2 ($contents) must be of type string, resource given, called in... Normally it generates the file but if I had a serious problem in fails the job, it will be impossible to trace. I have to solve this.

I am stuck and don't have any idea.

CodePudding user response:

For your first issue, you can pass data to your mail view by using the with method on the $this->markdown call in your build method. Here's an example:

public function build()
{
    return $this->markdown('mails.export-report')
                ->with([
                    'filename' => $this->filename,
                    'email' => auth()->user()->email
                ]);
}

Then, in your mail view, you can access these variables like you would in a Blade view.

For your second issue, it looks like you are trying to write a file handle to storage, rather than the contents of the file. Instead of this line:

Storage::put('public/', $file);

You can use the Storage::put method to write the contents of the file to storage, like this:

Storage::put('public/' . $filename, file_get_contents($handler));

This should fix the issue with the exception being thrown.

CodePudding user response:

I've solved the in this way. It may help other users. I removed the line:

Storage::put('public/', $file );

Jobs/ExportReport.pdf

protected $user;

/**
 * Create a new job instance.
 *
 * @return void
 */
public function __construct()
{
    $this->user = \auth()->user();
}

/**
 * Execute the job.
 * @return $response
 */
public function handle()
{

    // Generate our file name
    $filename="Report_Export_" . date("YmdHis") . time() . ".csv";

    $data = [
        'user' => $this->user,
        'filename'=>$filename,
    ];

    //dd($data);
    //dd(\auth()->user()->email);

    Mail::send('mails.export-report', $data, function ($m) use($data){
        $m->from('[email protected]', 'Sender Name');
        $m->to($this->user['email'], $this->user['first_name'].' '.$this->user['last_name'])->subject('Your export file is ready!');
    });
  • Related