From 5fb48e1fdd17803309187c1cb6b01f7a8bbf54f8 Mon Sep 17 00:00:00 2001 From: Dazza Date: Sat, 11 May 2024 19:02:05 -0500 Subject: [PATCH 1/9] Allow queue jobs with batches --- src/ChunkReader.php | 13 ++++++++++++- src/Concerns/BatchableTrait.php | 19 +++++++++++++++++++ src/Concerns/ShouldBatch.php | 7 +++++++ src/Excel.php | 3 ++- src/Jobs/AfterImportJob.php | 11 ++++++++++- src/Jobs/AppendDataToSheet.php | 10 +++++++++- src/Jobs/AppendQueryToSheet.php | 10 +++++++++- src/Jobs/AppendViewToSheet.php | 10 +++++++++- src/Jobs/CloseSheet.php | 12 +++++++++++- src/Jobs/QueueExport.php | 11 ++++++++++- src/Jobs/ReadChunk.php | 10 +++++++++- src/Jobs/StoreQueuedExport.php | 13 ++++++++++++- src/QueuedWriter.php | 16 ++++++++++++++-- 13 files changed, 133 insertions(+), 12 deletions(-) create mode 100644 src/Concerns/BatchableTrait.php create mode 100644 src/Concerns/ShouldBatch.php diff --git a/src/ChunkReader.php b/src/ChunkReader.php index 3e55cc929..d3564dc9c 100644 --- a/src/ChunkReader.php +++ b/src/ChunkReader.php @@ -2,6 +2,7 @@ namespace Maatwebsite\Excel; +use Maatwebsite\Excel\Concerns\ShouldBatch; use Illuminate\Bus\Queueable; use Illuminate\Container\Container; use Illuminate\Contracts\Queue\ShouldQueue; @@ -9,6 +10,8 @@ use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\Jobs\SyncJob; use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Bus; +use Illuminate\Bus\PendingBatch; use Maatwebsite\Excel\Concerns\ShouldQueueWithoutChain; use Maatwebsite\Excel\Concerns\WithChunkReading; use Maatwebsite\Excel\Concerns\WithEvents; @@ -37,7 +40,7 @@ public function __construct(Container $container) * @param WithChunkReading $import * @param Reader $reader * @param TemporaryFile $temporaryFile - * @return PendingDispatch|Collection|null + * @return PendingDispatch|PendingBatch|Collection|null */ public function read(WithChunkReading $import, Reader $reader, TemporaryFile $temporaryFile) { @@ -94,6 +97,14 @@ public function read(WithChunkReading $import, Reader $reader, TemporaryFile $te $jobs->push($afterImportJob); + // Check if the import class is batchable + if ($import instanceof ShouldBatch) { + return Bus::batch([ + $jobs->toArray(), + ]); + } + + // Check if the import class is queueable if ($import instanceof ShouldQueue) { return new PendingDispatch( (new QueueImport($import))->chain($jobs->toArray()) diff --git a/src/Concerns/BatchableTrait.php b/src/Concerns/BatchableTrait.php new file mode 100644 index 000000000..90271104f --- /dev/null +++ b/src/Concerns/BatchableTrait.php @@ -0,0 +1,19 @@ +batch()?->cancelled(); + } + } +} else { + trait BatchableTrait + { + } +} diff --git a/src/Concerns/ShouldBatch.php b/src/Concerns/ShouldBatch.php new file mode 100644 index 000000000..613ddbbc6 --- /dev/null +++ b/src/Concerns/ShouldBatch.php @@ -0,0 +1,7 @@ +reader->read($import, $filePath, $readerType, $disk); - if ($response instanceof PendingDispatch) { + if ($response instanceof PendingDispatch || $response instanceof PendingBatch) { return $response; } diff --git a/src/Jobs/AfterImportJob.php b/src/Jobs/AfterImportJob.php index 15be0e19c..fb7326778 100644 --- a/src/Jobs/AfterImportJob.php +++ b/src/Jobs/AfterImportJob.php @@ -4,8 +4,10 @@ use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Support\Collection; +use Maatwebsite\Excel\Concerns\BatchableTrait; use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Events\ImportFailed; use Maatwebsite\Excel\HasEventBus; @@ -14,7 +16,7 @@ class AfterImportJob implements ShouldQueue { - use HasEventBus, InteractsWithQueue, Queueable; + use BatchableTrait, HasEventBus, InteractsWithQueue, Queueable, Dispatchable; /** * @var WithEvents @@ -57,6 +59,13 @@ public function setDependencies(Collection $jobs) public function handle() { + // Determine if the batch has been cancelled... + if (method_exists($this, 'batchCancelled')) { + if ($this->batchCancelled()) { + return; + } + } + foreach ($this->dependencyIds as $id) { if (!ReadChunk::isComplete($id)) { // Until there is no jobs left to run we put this job back into the queue every minute diff --git a/src/Jobs/AppendDataToSheet.php b/src/Jobs/AppendDataToSheet.php index c1c294314..1cb90f709 100644 --- a/src/Jobs/AppendDataToSheet.php +++ b/src/Jobs/AppendDataToSheet.php @@ -6,13 +6,14 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; +use Maatwebsite\Excel\Concerns\BatchableTrait; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\Jobs\Middleware\LocalizeJob; use Maatwebsite\Excel\Writer; class AppendDataToSheet implements ShouldQueue { - use Queueable, Dispatchable, ProxyFailures, InteractsWithQueue; + use BatchableTrait, Queueable, Dispatchable, ProxyFailures, InteractsWithQueue; /** * @var array @@ -73,6 +74,13 @@ public function middleware() */ public function handle(Writer $writer) { + // Determine if the batch has been cancelled... + if (method_exists($this, 'batchCancelled')) { + if ($this->batchCancelled()) { + return; + } + } + (new LocalizeJob($this->sheetExport))->handle($this, function () use ($writer) { $writer = $writer->reopen($this->temporaryFile, $this->writerType); diff --git a/src/Jobs/AppendQueryToSheet.php b/src/Jobs/AppendQueryToSheet.php index 7ac4f0d01..2f5aa5be8 100644 --- a/src/Jobs/AppendQueryToSheet.php +++ b/src/Jobs/AppendQueryToSheet.php @@ -6,6 +6,7 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; +use Maatwebsite\Excel\Concerns\BatchableTrait; use Maatwebsite\Excel\Concerns\FromQuery; use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Events\AfterChunk; @@ -16,7 +17,7 @@ class AppendQueryToSheet implements ShouldQueue { - use Queueable, Dispatchable, ProxyFailures, InteractsWithQueue, HasEventBus; + use BatchableTrait, Queueable, Dispatchable, ProxyFailures, InteractsWithQueue, HasEventBus; /** * @var TemporaryFile @@ -90,6 +91,13 @@ public function middleware() */ public function handle(Writer $writer) { + // Determine if the batch has been cancelled... + if (method_exists($this, 'batchCancelled')) { + if ($this->batchCancelled()) { + return; + } + } + (new LocalizeJob($this->sheetExport))->handle($this, function () use ($writer) { if ($this->sheetExport instanceof WithEvents) { $this->registerListeners($this->sheetExport->registerEvents()); diff --git a/src/Jobs/AppendViewToSheet.php b/src/Jobs/AppendViewToSheet.php index a7d2c09e2..b05aff036 100644 --- a/src/Jobs/AppendViewToSheet.php +++ b/src/Jobs/AppendViewToSheet.php @@ -6,6 +6,7 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; +use Maatwebsite\Excel\Concerns\BatchableTrait; use Maatwebsite\Excel\Concerns\FromView; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\Jobs\Middleware\LocalizeJob; @@ -13,7 +14,7 @@ class AppendViewToSheet implements ShouldQueue { - use Queueable, Dispatchable, InteractsWithQueue; + use BatchableTrait, Queueable, Dispatchable, InteractsWithQueue; /** * @var TemporaryFile @@ -68,6 +69,13 @@ public function middleware() */ public function handle(Writer $writer) { + // Determine if the batch has been cancelled... + if (method_exists($this, 'batchCancelled')) { + if ($this->batchCancelled()) { + return; + } + } + (new LocalizeJob($this->sheetExport))->handle($this, function () use ($writer) { $writer = $writer->reopen($this->temporaryFile, $this->writerType); diff --git a/src/Jobs/CloseSheet.php b/src/Jobs/CloseSheet.php index 7225505ae..e245aac38 100644 --- a/src/Jobs/CloseSheet.php +++ b/src/Jobs/CloseSheet.php @@ -4,13 +4,16 @@ use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; +use Illuminate\Queue\InteractsWithQueue; +use Maatwebsite\Excel\Concerns\BatchableTrait; use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Files\TemporaryFile; use Maatwebsite\Excel\Writer; class CloseSheet implements ShouldQueue { - use Queueable, ProxyFailures; + use BatchableTrait, Queueable, Dispatchable, ProxyFailures, InteractsWithQueue; /** * @var object @@ -54,6 +57,13 @@ public function __construct($sheetExport, TemporaryFile $temporaryFile, string $ */ public function handle(Writer $writer) { + // Determine if the batch has been cancelled... + if (method_exists($this, 'batchCancelled')) { + if ($this->batchCancelled()) { + return; + } + } + $writer = $writer->reopen( $this->temporaryFile, $this->writerType diff --git a/src/Jobs/QueueExport.php b/src/Jobs/QueueExport.php index 768b7ae98..9716072c6 100644 --- a/src/Jobs/QueueExport.php +++ b/src/Jobs/QueueExport.php @@ -4,6 +4,8 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; +use Illuminate\Queue\InteractsWithQueue; +use Maatwebsite\Excel\Concerns\BatchableTrait; use Maatwebsite\Excel\Concerns\WithMultipleSheets; use Maatwebsite\Excel\Exceptions\NoSheetsFoundException; use Maatwebsite\Excel\Files\TemporaryFile; @@ -13,7 +15,7 @@ class QueueExport implements ShouldQueue { - use ExtendedQueueable, Dispatchable; + use BatchableTrait, ExtendedQueueable, Dispatchable, InteractsWithQueue; /** * @var object @@ -59,6 +61,13 @@ public function middleware() */ public function handle(Writer $writer) { + // Determine if the batch has been cancelled... + if (method_exists($this, 'batchCancelled')) { + if ($this->batchCancelled()) { + return; + } + } + (new LocalizeJob($this->export))->handle($this, function () use ($writer) { $writer->open($this->export); diff --git a/src/Jobs/ReadChunk.php b/src/Jobs/ReadChunk.php index ef73373d8..b15823e0c 100644 --- a/src/Jobs/ReadChunk.php +++ b/src/Jobs/ReadChunk.php @@ -6,6 +6,7 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Support\Facades\Cache; +use Maatwebsite\Excel\Concerns\BatchableTrait; use Maatwebsite\Excel\Concerns\WithChunkReading; use Maatwebsite\Excel\Concerns\WithCustomValueBinder; use Maatwebsite\Excel\Concerns\WithEvents; @@ -24,7 +25,7 @@ class ReadChunk implements ShouldQueue { - use Queueable, HasEventBus, InteractsWithQueue; + use BatchableTrait, Queueable, HasEventBus, InteractsWithQueue; /** * @var int @@ -165,6 +166,13 @@ public function retryUntil() */ public function handle(TransactionHandler $transaction) { + // Determine if the batch has been cancelled... + if (method_exists($this, 'batchCancelled')) { + if ($this->batchCancelled()) { + return; + } + } + if (method_exists($this->import, 'setChunkOffset')) { $this->import->setChunkOffset($this->startRow); } diff --git a/src/Jobs/StoreQueuedExport.php b/src/Jobs/StoreQueuedExport.php index 5469a927f..9ec917505 100644 --- a/src/Jobs/StoreQueuedExport.php +++ b/src/Jobs/StoreQueuedExport.php @@ -4,12 +4,15 @@ use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; +use Illuminate\Queue\InteractsWithQueue; +use Maatwebsite\Excel\Concerns\BatchableTrait; use Maatwebsite\Excel\Files\Filesystem; use Maatwebsite\Excel\Files\TemporaryFile; class StoreQueuedExport implements ShouldQueue { - use Queueable; + use BatchableTrait, Queueable, Dispatchable, InteractsWithQueue; /** * @var string @@ -25,6 +28,7 @@ class StoreQueuedExport implements ShouldQueue * @var TemporaryFile */ private $temporaryFile; + /** * @var array|string */ @@ -49,6 +53,13 @@ public function __construct(TemporaryFile $temporaryFile, string $filePath, stri */ public function handle(Filesystem $filesystem) { + // Determine if the batch has been cancelled... + if (method_exists($this, 'batchCancelled')) { + if ($this->batchCancelled()) { + return; + } + } + $filesystem->disk($this->disk, $this->diskOptions)->copy( $this->temporaryFile, $this->filePath diff --git a/src/QueuedWriter.php b/src/QueuedWriter.php index a8c6a6699..f06051881 100644 --- a/src/QueuedWriter.php +++ b/src/QueuedWriter.php @@ -2,7 +2,9 @@ namespace Maatwebsite\Excel; +use Maatwebsite\Excel\Concerns\ShouldBatch; use Illuminate\Foundation\Bus\PendingDispatch; +use Illuminate\Support\Facades\Bus; use Illuminate\Support\Collection; use Illuminate\Support\LazyCollection; use Maatwebsite\Excel\Concerns\FromCollection; @@ -56,7 +58,7 @@ public function __construct(Writer $writer, TemporaryFileFactory $temporaryFileF * @param string $disk * @param string|null $writerType * @param array|string $diskOptions - * @return \Illuminate\Foundation\Bus\PendingDispatch + * @return PendingDispatch|PendingBatch */ public function store($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = []) { @@ -65,6 +67,8 @@ public function store($export, string $filePath, string $disk = null, string $wr $jobs = $this->buildExportJobs($export, $temporaryFile, $writerType); + $queueExportJob = new QueueExport($export, $temporaryFile, $writerType); + $jobs->push(new StoreQueuedExport( $temporaryFile, $filePath, @@ -72,8 +76,16 @@ public function store($export, string $filePath, string $disk = null, string $wr $diskOptions )); + // Check if the export class is batchable + if ($export instanceof ShouldBatch) { + return Bus::batch([ + $jobs->prepend($queueExportJob) + ->toArray(), + ]); + } + return new PendingDispatch( - (new QueueExport($export, $temporaryFile, $writerType))->chain($jobs->toArray()) + $queueExportJob->chain($jobs->toArray()) ); } From 94930ccda08a3865fd83e7905fd05ed0738fc3e4 Mon Sep 17 00:00:00 2001 From: Dazza Date: Sat, 11 May 2024 19:08:24 -0500 Subject: [PATCH 2/9] Style CI --- src/ChunkReader.php | 7 ++++--- src/QueuedWriter.php | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ChunkReader.php b/src/ChunkReader.php index d3564dc9c..4c7832147 100644 --- a/src/ChunkReader.php +++ b/src/ChunkReader.php @@ -2,7 +2,7 @@ namespace Maatwebsite\Excel; -use Maatwebsite\Excel\Concerns\ShouldBatch; +use Illuminate\Bus\PendingBatch; use Illuminate\Bus\Queueable; use Illuminate\Container\Container; use Illuminate\Contracts\Queue\ShouldQueue; @@ -11,7 +11,7 @@ use Illuminate\Queue\Jobs\SyncJob; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Bus; -use Illuminate\Bus\PendingBatch; +use Maatwebsite\Excel\Concerns\ShouldBatch; use Maatwebsite\Excel\Concerns\ShouldQueueWithoutChain; use Maatwebsite\Excel\Concerns\WithChunkReading; use Maatwebsite\Excel\Concerns\WithEvents; @@ -144,7 +144,8 @@ protected function dispatchNow($command, $handler = null) { $uses = class_uses_recursive($command); - if (in_array(InteractsWithQueue::class, $uses) && + if ( + in_array(InteractsWithQueue::class, $uses) && in_array(Queueable::class, $uses) && !$command->job ) { $command->setJob(new SyncJob($this->container, json_encode([]), 'sync', 'sync')); diff --git a/src/QueuedWriter.php b/src/QueuedWriter.php index f06051881..88352678a 100644 --- a/src/QueuedWriter.php +++ b/src/QueuedWriter.php @@ -2,14 +2,14 @@ namespace Maatwebsite\Excel; -use Maatwebsite\Excel\Concerns\ShouldBatch; use Illuminate\Foundation\Bus\PendingDispatch; -use Illuminate\Support\Facades\Bus; use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Bus; use Illuminate\Support\LazyCollection; use Maatwebsite\Excel\Concerns\FromCollection; use Maatwebsite\Excel\Concerns\FromQuery; use Maatwebsite\Excel\Concerns\FromView; +use Maatwebsite\Excel\Concerns\ShouldBatch; use Maatwebsite\Excel\Concerns\WithCustomChunkSize; use Maatwebsite\Excel\Concerns\WithCustomQuerySize; use Maatwebsite\Excel\Concerns\WithMultipleSheets; From 40c3f8206fc2aee9c2e545392443fd0b3c3ccb46 Mon Sep 17 00:00:00 2001 From: Dazza Date: Sat, 11 May 2024 19:14:34 -0500 Subject: [PATCH 3/9] Making the BatchableTrait compatible with PHP < 8 --- src/Concerns/BatchableTrait.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Concerns/BatchableTrait.php b/src/Concerns/BatchableTrait.php index 90271104f..7c481808d 100644 --- a/src/Concerns/BatchableTrait.php +++ b/src/Concerns/BatchableTrait.php @@ -9,7 +9,9 @@ trait BatchableTrait public function batchCancelled() { - return $this->batch()?->cancelled(); + $batch = $this->batch(); + + return $batch !== null && method_exists($batch, 'cancelled') && $batch->cancelled(); } } } else { From ecdf8d8567d22e17e895c443440b682df1c6b344 Mon Sep 17 00:00:00 2001 From: Dazza Date: Sun, 12 May 2024 11:23:41 -0500 Subject: [PATCH 4/9] Illuminate\Bus\PendingBatch doesn't exist in Laravel < 8 --- src/ChunkReader.php | 3 +-- src/Excel.php | 3 +-- src/QueuedWriter.php | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/ChunkReader.php b/src/ChunkReader.php index 4c7832147..94719beb0 100644 --- a/src/ChunkReader.php +++ b/src/ChunkReader.php @@ -2,7 +2,6 @@ namespace Maatwebsite\Excel; -use Illuminate\Bus\PendingBatch; use Illuminate\Bus\Queueable; use Illuminate\Container\Container; use Illuminate\Contracts\Queue\ShouldQueue; @@ -40,7 +39,7 @@ public function __construct(Container $container) * @param WithChunkReading $import * @param Reader $reader * @param TemporaryFile $temporaryFile - * @return PendingDispatch|PendingBatch|Collection|null + * @return PendingDispatch|\Illuminate\Bus\PendingBatch|Collection|null */ public function read(WithChunkReading $import, Reader $reader, TemporaryFile $temporaryFile) { diff --git a/src/Excel.php b/src/Excel.php index 4216fd6da..1b5b6d120 100644 --- a/src/Excel.php +++ b/src/Excel.php @@ -2,7 +2,6 @@ namespace Maatwebsite\Excel; -use Illuminate\Bus\PendingBatch; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\PendingDispatch; use Illuminate\Support\Collection; @@ -154,7 +153,7 @@ public function import($import, $filePath, string $disk = null, string $readerTy $readerType = FileTypeDetector::detect($filePath, $readerType); $response = $this->reader->read($import, $filePath, $readerType, $disk); - if ($response instanceof PendingDispatch || $response instanceof PendingBatch) { + if ($response instanceof PendingDispatch || $response instanceof \Illuminate\Bus\PendingBatch) { return $response; } diff --git a/src/QueuedWriter.php b/src/QueuedWriter.php index 88352678a..cedef5ea3 100644 --- a/src/QueuedWriter.php +++ b/src/QueuedWriter.php @@ -58,7 +58,7 @@ public function __construct(Writer $writer, TemporaryFileFactory $temporaryFileF * @param string $disk * @param string|null $writerType * @param array|string $diskOptions - * @return PendingDispatch|PendingBatch + * @return PendingDispatch|Illuminate\Bus\PendingBatch */ public function store($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = []) { From 6826fa4142a705ee67ba17981a4b217a8c9cf360 Mon Sep 17 00:00:00 2001 From: Dazza Date: Wed, 5 Jun 2024 11:14:53 -0500 Subject: [PATCH 5/9] Added batchCancelled method to BatchableTrait to eliminate redundant checks for method existence. --- src/Concerns/BatchableTrait.php | 4 ++++ src/Jobs/AfterImportJob.php | 6 ++---- src/Jobs/AppendDataToSheet.php | 6 ++---- src/Jobs/AppendQueryToSheet.php | 6 ++---- src/Jobs/AppendViewToSheet.php | 6 ++---- src/Jobs/CloseSheet.php | 6 ++---- src/Jobs/QueueExport.php | 6 ++---- src/Jobs/ReadChunk.php | 6 ++---- src/Jobs/StoreQueuedExport.php | 6 ++---- 9 files changed, 20 insertions(+), 32 deletions(-) diff --git a/src/Concerns/BatchableTrait.php b/src/Concerns/BatchableTrait.php index 7c481808d..fe6fa5a30 100644 --- a/src/Concerns/BatchableTrait.php +++ b/src/Concerns/BatchableTrait.php @@ -17,5 +17,9 @@ public function batchCancelled() } else { trait BatchableTrait { + public function batchCancelled() + { + return false; + } } } diff --git a/src/Jobs/AfterImportJob.php b/src/Jobs/AfterImportJob.php index fb7326778..761e45581 100644 --- a/src/Jobs/AfterImportJob.php +++ b/src/Jobs/AfterImportJob.php @@ -60,10 +60,8 @@ public function setDependencies(Collection $jobs) public function handle() { // Determine if the batch has been cancelled... - if (method_exists($this, 'batchCancelled')) { - if ($this->batchCancelled()) { - return; - } + if ($this->batchCancelled()) { + return; } foreach ($this->dependencyIds as $id) { diff --git a/src/Jobs/AppendDataToSheet.php b/src/Jobs/AppendDataToSheet.php index 1cb90f709..d8d53a803 100644 --- a/src/Jobs/AppendDataToSheet.php +++ b/src/Jobs/AppendDataToSheet.php @@ -75,10 +75,8 @@ public function middleware() public function handle(Writer $writer) { // Determine if the batch has been cancelled... - if (method_exists($this, 'batchCancelled')) { - if ($this->batchCancelled()) { - return; - } + if ($this->batchCancelled()) { + return; } (new LocalizeJob($this->sheetExport))->handle($this, function () use ($writer) { diff --git a/src/Jobs/AppendQueryToSheet.php b/src/Jobs/AppendQueryToSheet.php index 2f5aa5be8..607765161 100644 --- a/src/Jobs/AppendQueryToSheet.php +++ b/src/Jobs/AppendQueryToSheet.php @@ -92,10 +92,8 @@ public function middleware() public function handle(Writer $writer) { // Determine if the batch has been cancelled... - if (method_exists($this, 'batchCancelled')) { - if ($this->batchCancelled()) { - return; - } + if ($this->batchCancelled()) { + return; } (new LocalizeJob($this->sheetExport))->handle($this, function () use ($writer) { diff --git a/src/Jobs/AppendViewToSheet.php b/src/Jobs/AppendViewToSheet.php index b05aff036..4b4a6f4ec 100644 --- a/src/Jobs/AppendViewToSheet.php +++ b/src/Jobs/AppendViewToSheet.php @@ -70,10 +70,8 @@ public function middleware() public function handle(Writer $writer) { // Determine if the batch has been cancelled... - if (method_exists($this, 'batchCancelled')) { - if ($this->batchCancelled()) { - return; - } + if ($this->batchCancelled()) { + return; } (new LocalizeJob($this->sheetExport))->handle($this, function () use ($writer) { diff --git a/src/Jobs/CloseSheet.php b/src/Jobs/CloseSheet.php index e245aac38..98f2eb702 100644 --- a/src/Jobs/CloseSheet.php +++ b/src/Jobs/CloseSheet.php @@ -58,10 +58,8 @@ public function __construct($sheetExport, TemporaryFile $temporaryFile, string $ public function handle(Writer $writer) { // Determine if the batch has been cancelled... - if (method_exists($this, 'batchCancelled')) { - if ($this->batchCancelled()) { - return; - } + if ($this->batchCancelled()) { + return; } $writer = $writer->reopen( diff --git a/src/Jobs/QueueExport.php b/src/Jobs/QueueExport.php index 9716072c6..ea97729a0 100644 --- a/src/Jobs/QueueExport.php +++ b/src/Jobs/QueueExport.php @@ -62,10 +62,8 @@ public function middleware() public function handle(Writer $writer) { // Determine if the batch has been cancelled... - if (method_exists($this, 'batchCancelled')) { - if ($this->batchCancelled()) { - return; - } + if ($this->batchCancelled()) { + return; } (new LocalizeJob($this->export))->handle($this, function () use ($writer) { diff --git a/src/Jobs/ReadChunk.php b/src/Jobs/ReadChunk.php index b15823e0c..4981d8f45 100644 --- a/src/Jobs/ReadChunk.php +++ b/src/Jobs/ReadChunk.php @@ -167,10 +167,8 @@ public function retryUntil() public function handle(TransactionHandler $transaction) { // Determine if the batch has been cancelled... - if (method_exists($this, 'batchCancelled')) { - if ($this->batchCancelled()) { - return; - } + if ($this->batchCancelled()) { + return; } if (method_exists($this->import, 'setChunkOffset')) { diff --git a/src/Jobs/StoreQueuedExport.php b/src/Jobs/StoreQueuedExport.php index 9ec917505..b39e055f3 100644 --- a/src/Jobs/StoreQueuedExport.php +++ b/src/Jobs/StoreQueuedExport.php @@ -54,10 +54,8 @@ public function __construct(TemporaryFile $temporaryFile, string $filePath, stri public function handle(Filesystem $filesystem) { // Determine if the batch has been cancelled... - if (method_exists($this, 'batchCancelled')) { - if ($this->batchCancelled()) { - return; - } + if ($this->batchCancelled()) { + return; } $filesystem->disk($this->disk, $this->diskOptions)->copy( From 7276ee741e2e14261c65c78b04f0a0e4aa4b231c Mon Sep 17 00:00:00 2001 From: Andres Daza Date: Wed, 4 Sep 2024 17:19:03 -0500 Subject: [PATCH 6/9] ShouldBatchExport Test --- tests/Data/Stubs/ShouldBatchExport.php | 24 ++++++++++++++++++++++++ tests/QueuedExportTest.php | 17 +++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 tests/Data/Stubs/ShouldBatchExport.php diff --git a/tests/Data/Stubs/ShouldBatchExport.php b/tests/Data/Stubs/ShouldBatchExport.php new file mode 100644 index 000000000..22e01324e --- /dev/null +++ b/tests/Data/Stubs/ShouldBatchExport.php @@ -0,0 +1,24 @@ +markTestSkipped('Batch jobs are not supported in this version of Laravel.'); + } + + $export = new ShouldBatchExport(); + + $batch = $export->queue('batch-export.xlsx', 'test')->name('batch-export-name'); + + $this->assertInstanceOf(PendingBatch::class, $batch); + $this->assertEquals('batch-export-name', $batch->name); + $this->assertCount(1, $batch->jobs); + } + public function test_can_queue_an_export_and_store_on_different_disk() { $export = new QueuedExport(); From 22adf92407c3ce709fdce74a4143935369304066 Mon Sep 17 00:00:00 2001 From: Andres Daza Date: Wed, 4 Sep 2024 17:24:39 -0500 Subject: [PATCH 7/9] Apply StyleCI fixes --- tests/Data/Stubs/ShouldBatchExport.php | 2 +- tests/QueuedExportTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Data/Stubs/ShouldBatchExport.php b/tests/Data/Stubs/ShouldBatchExport.php index 22e01324e..fe1ab66dd 100644 --- a/tests/Data/Stubs/ShouldBatchExport.php +++ b/tests/Data/Stubs/ShouldBatchExport.php @@ -2,8 +2,8 @@ namespace Maatwebsite\Excel\Tests\Data\Stubs; -use Maatwebsite\Excel\Concerns\ShouldBatch; use Maatwebsite\Excel\Concerns\Exportable; +use Maatwebsite\Excel\Concerns\ShouldBatch; use Maatwebsite\Excel\Concerns\WithMultipleSheets; class ShouldBatchExport implements WithMultipleSheets, ShouldBatch diff --git a/tests/QueuedExportTest.php b/tests/QueuedExportTest.php index 65e2dff70..8d2554628 100644 --- a/tests/QueuedExportTest.php +++ b/tests/QueuedExportTest.php @@ -16,8 +16,8 @@ use Maatwebsite\Excel\Tests\Data\Stubs\QueuedExportWithFailedEvents; use Maatwebsite\Excel\Tests\Data\Stubs\QueuedExportWithFailedHook; use Maatwebsite\Excel\Tests\Data\Stubs\QueuedExportWithLocalePreferences; -use Maatwebsite\Excel\Tests\Data\Stubs\ShouldQueueExport; use Maatwebsite\Excel\Tests\Data\Stubs\ShouldBatchExport; +use Maatwebsite\Excel\Tests\Data\Stubs\ShouldQueueExport; use Throwable; class QueuedExportTest extends TestCase From 506517159659355a5216b4936e92a8a29c0f7698 Mon Sep 17 00:00:00 2001 From: Andres Daza Date: Wed, 4 Sep 2024 17:46:25 -0500 Subject: [PATCH 8/9] ShouldBatchImport Test --- tests/Data/Stubs/ShouldBatchImport.php | 44 ++++++++++++++++++++++++++ tests/QueuedImportTest.php | 17 ++++++++++ 2 files changed, 61 insertions(+) create mode 100644 tests/Data/Stubs/ShouldBatchImport.php diff --git a/tests/Data/Stubs/ShouldBatchImport.php b/tests/Data/Stubs/ShouldBatchImport.php new file mode 100644 index 000000000..e4331561d --- /dev/null +++ b/tests/Data/Stubs/ShouldBatchImport.php @@ -0,0 +1,44 @@ + $row[0], + ]); + } + + /** + * @return int + */ + public function batchSize(): int + { + return 100; + } + + /** + * @return int + */ + public function chunkSize(): int + { + return 100; + } +} diff --git a/tests/QueuedImportTest.php b/tests/QueuedImportTest.php index 39271af8c..65c4a5662 100644 --- a/tests/QueuedImportTest.php +++ b/tests/QueuedImportTest.php @@ -2,6 +2,7 @@ namespace Maatwebsite\Excel\Tests; +use Illuminate\Bus\PendingBatch; use Illuminate\Foundation\Bus\PendingDispatch; use Illuminate\Queue\Events\JobExceptionOccurred; use Illuminate\Queue\Events\JobProcessed; @@ -19,6 +20,7 @@ use Maatwebsite\Excel\Tests\Data\Stubs\QueuedImportWithFailure; use Maatwebsite\Excel\Tests\Data\Stubs\QueuedImportWithMiddleware; use Maatwebsite\Excel\Tests\Data\Stubs\QueuedImportWithRetryUntil; +use Maatwebsite\Excel\Tests\Data\Stubs\ShouldBatchImport; use Throwable; class QueuedImportTest extends TestCase @@ -58,6 +60,21 @@ public function test_can_queue_an_import() $this->assertInstanceOf(PendingDispatch::class, $chain); } + public function test_can_batch_an_import() + { + if (!class_exists(\Illuminate\Bus\Batchable::class)) { + $this->markTestSkipped('Batch jobs are not supported in this version of Laravel.'); + } + + $import = new ShouldBatchImport(); + + $batch = $import->queue('import-batches.xlsx')->name('batch-import-name'); + + $this->assertInstanceOf(PendingBatch::class, $batch); + $this->assertEquals('batch-import-name', $batch->name); + $this->assertCount(1, $batch->jobs); + } + public function test_can_queue_an_import_with_batch_cache_and_file_store() { config()->set('queue.default', 'sync'); From 6ede72addf624a2cf77111bee354f10444c0686f Mon Sep 17 00:00:00 2001 From: Andres Daza Date: Wed, 11 Sep 2024 16:27:18 -0500 Subject: [PATCH 9/9] Add PendingBatch response handling in ExcelFake --- src/Fakes/ExcelFake.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Fakes/ExcelFake.php b/src/Fakes/ExcelFake.php index d8cb0aadd..a4ebae312 100644 --- a/src/Fakes/ExcelFake.php +++ b/src/Fakes/ExcelFake.php @@ -6,8 +6,10 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\PendingDispatch; use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Bus; use Illuminate\Support\Facades\Queue; use Illuminate\Support\Traits\Macroable; +use Maatwebsite\Excel\Concerns\ShouldBatch; use Maatwebsite\Excel\Exporter; use Maatwebsite\Excel\Importer; use Maatwebsite\Excel\Reader; @@ -102,6 +104,11 @@ public function handle() Queue::push($this->job); + // Check if the export class is batchable + if ($export instanceof ShouldBatch) { + return Bus::batch([$this->job]); + } + return new PendingDispatch($this->job); } @@ -122,7 +129,7 @@ public function raw($export, string $writerType) * @param string|UploadedFile $file * @param string|null $disk * @param string|null $readerType - * @return Reader|PendingDispatch + * @return Reader|PendingDispatch|\Illuminate\Bus\PendingBatch */ public function import($import, $file, string $disk = null, string $readerType = null) { @@ -174,7 +181,7 @@ public function toCollection($import, $file, string $disk = null, string $reader * @param string|UploadedFile $file * @param string|null $disk * @param string $readerType - * @return PendingDispatch + * @return PendingDispatch|\Illuminate\Bus\PendingBatch */ public function queueImport(ShouldQueue $import, $file, string $disk = null, string $readerType = null) { @@ -197,6 +204,11 @@ public function handle() Queue::push($this->job); + // Check if the import class is batchable + if ($import instanceof ShouldBatch) { + return Bus::batch([$this->job]); + } + return new PendingDispatch($this->job); }