Skip to content

Commit

Permalink
Raise Before and After import events + garbage collect after import i…
Browse files Browse the repository at this point in the history
…s finished (#1944)
  • Loading branch information
patrickbrouwers committed Apr 5, 2019
1 parent 8576af6 commit b26dcc6
Show file tree
Hide file tree
Showing 4 changed files with 275 additions and 149 deletions.
90 changes: 20 additions & 70 deletions src/ChunkReader.php
Expand Up @@ -3,6 +3,11 @@
namespace Maatwebsite\Excel;

use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterImport;
use Maatwebsite\Excel\Events\BeforeImport;
use Maatwebsite\Excel\Jobs\AfterImportJob;
use Maatwebsite\Excel\Jobs\BeforeImportJob;
use Maatwebsite\Excel\Jobs\ReadChunk;
use Maatwebsite\Excel\Jobs\QueueImport;
use Maatwebsite\Excel\Concerns\WithLimit;
Expand All @@ -17,18 +22,22 @@
class ChunkReader
{
/**
* @param WithChunkReading $import
* @param IReader $reader
* @param TemporaryFile $temporaryFile
* @param WithChunkReading $import
* @param Reader $reader
* @param TemporaryFile $temporaryFile
*
* @return \Illuminate\Foundation\Bus\PendingDispatch|null
*/
public function read(WithChunkReading $import, IReader $reader, TemporaryFile $temporaryFile)
public function read(WithChunkReading $import, Reader $reader, TemporaryFile $temporaryFile)
{
if ($import instanceof WithEvents && isset($import->registerEvents()[BeforeImport::class])) {
$reader->readSpreadsheet();
$reader->beforeImport($import);
}

$chunkSize = $import->chunkSize();
$file = $temporaryFile->getLocalPath();
$totalRows = $this->getTotalRows($reader, $file);
$worksheets = $this->getWorksheets($import, $reader, $file);
$totalRows = $reader->getTotalRows();
$worksheets = $reader->getWorksheets($import);

if ($import instanceof WithProgressBar) {
$import->getConsoleOutput()->progressStart(array_sum($totalRows));
Expand All @@ -41,7 +50,7 @@ public function read(WithChunkReading $import, IReader $reader, TemporaryFile $t

for ($currentRow = $startRow; $currentRow <= $totalRows[$name]; $currentRow += $chunkSize) {
$jobs->push(new ReadChunk(
$reader,
$reader->getPhpSpreadsheetReader(),
$temporaryFile,
$name,
$sheetImport,
Expand All @@ -51,11 +60,13 @@ public function read(WithChunkReading $import, IReader $reader, TemporaryFile $t
}
}

$jobs->push(new AfterImportJob($import, $reader));

if ($import instanceof ShouldQueue) {
return QueueImport::withChain($jobs->toArray())->dispatch();
}

$jobs->each(function (ReadChunk $job) {
$jobs->each(function ($job) {
dispatch_now($job);
});

Expand All @@ -67,65 +78,4 @@ public function read(WithChunkReading $import, IReader $reader, TemporaryFile $t

return null;
}

/**
* @param WithChunkReading $import
* @param IReader $reader
* @param string $file
*
* @return array
*/
private function getWorksheets(WithChunkReading $import, IReader $reader, string $file): array
{
// Csv doesn't have worksheets.
if (!method_exists($reader, 'listWorksheetNames')) {
return ['Worksheet' => $import];
}

$worksheets = [];
$worksheetNames = $reader->listWorksheetNames($file);
if ($import instanceof WithMultipleSheets) {
$sheetImports = $import->sheets();

// Load specific sheets.
if (method_exists($reader, 'setLoadSheetsOnly')) {
$reader->setLoadSheetsOnly(array_keys($sheetImports));
}

foreach ($sheetImports as $index => $sheetImport) {
// Translate index to name.
if (is_numeric($index)) {
$index = $worksheetNames[$index] ?? $index;
}

// Specify with worksheet name should have which import.
$worksheets[$index] = $sheetImport;
}
} else {
// Each worksheet the same import class.
foreach ($worksheetNames as $name) {
$worksheets[$name] = $import;
}
}

return $worksheets;
}

/**
* @param IReader $reader
* @param string $file
*
* @return array
*/
private function getTotalRows(IReader $reader, string $file): array
{
$info = $reader->listWorksheetInfo($file);

$totalRows = [];
foreach ($info as $sheet) {
$totalRows[$sheet['worksheetName']] = $sheet['totalRows'];
}

return $totalRows;
}
}
45 changes: 45 additions & 0 deletions src/Jobs/AfterImportJob.php
@@ -0,0 +1,45 @@
<?php

namespace Maatwebsite\Excel\Jobs;

use Maatwebsite\Excel\Reader;
use Illuminate\Bus\Queueable;
use Maatwebsite\Excel\Concerns\WithEvents;

class AfterImportJob
{
use Queueable;

/**
* @var WithEvents
*/
private $import;

/**
* @var Reader
*/
private $reader;

/**
* @param object $import
* @param Reader $reader
*/
public function __construct($import, Reader $reader)
{
$this->import = $import;
$this->reader = $reader;
}

public function handle()
{
if ($this->import instanceof WithEvents) {
if (null === $this->reader->getDelegate()) {
$this->reader->readSpreadsheet();
}

$this->reader->registerListeners($this->import->registerEvents());
}

$this->reader->afterImport($this->import);
}
}

0 comments on commit b26dcc6

Please sign in to comment.