<?php
namespace Filament\Actions\Imports\Http\Controllers;
use Filament\Actions\Imports\Models\FailedImportRow;
use Filament\Actions\Imports\Models\Import;
use Illuminate\Support\Facades\Gate;
use League\Csv\ByteSequence;
use League\Csv\Writer;
use SplTempFileObject;
use Symfony\Component\HttpFoundation\StreamedResponse;
use function Filament\authorize;
class DownloadImportFailureCsv
{
public function __invoke(Import $import): StreamedResponse
{
if (filled(Gate::getPolicyFor($import::class))) {
authorize('view', $import);
} else {
abort_unless($import->user()->is(auth()->user()), 403);
}
$csv = Writer::createFromFileObject(new SplTempFileObject);
$csv->setOutputBOM(ByteSequence::BOM_UTF8);
$firstFailedRow = $import->failedRows()->first();
$columnHeaders = $firstFailedRow ? array_keys($firstFailedRow->data) : [];
$columnHeaders[] = __('filament-actions::import.failure_csv.error_header');
$csv->insertOne($columnHeaders);
$import->failedRows()
->lazyById(100)
->each(fn (FailedImportRow $failedImportRow) => $csv->insertOne([
...$failedImportRow->data,
'error' => $failedImportRow->validation_error ?? __('filament-actions::import.failure_csv.system_error'),
]));
return response()->streamDownload(function () use ($csv) {
foreach ($csv->chunk(1000) as $offset => $chunk) {
echo $chunk;
if ($offset % 1000) {
flush();
}
}
}, __('filament-actions::import.failure_csv.file_name', [
'import_id' => $import->getKey(),
'csv_name' => (string) str($import->file_name)->beforeLast('.')->remove('.'),
]) . '.csv', [
'Content-Type' => 'text/csv',
]);
}
}