updated-packages

This commit is contained in:
RafficMohammed
2023-01-08 00:13:22 +05:30
parent 3ff7df7487
commit da241bacb6
12659 changed files with 563377 additions and 510538 deletions

View File

@@ -0,0 +1,142 @@
<?php
namespace Maatwebsite\Excel\Cache;
use Psr\SimpleCache\CacheInterface;
class BatchCache implements CacheInterface
{
/**
* @var CacheInterface
*/
protected $cache;
/**
* @var MemoryCache
*/
protected $memory;
/**
* @param CacheInterface $cache
* @param MemoryCache $memory
*/
public function __construct(CacheInterface $cache, MemoryCache $memory)
{
$this->cache = $cache;
$this->memory = $memory;
}
/**
* {@inheritdoc}
*/
public function get($key, $default = null)
{
if ($this->memory->has($key)) {
return $this->memory->get($key);
}
return $this->cache->get($key, $default);
}
/**
* {@inheritdoc}
*/
public function set($key, $value, $ttl = null)
{
$this->memory->set($key, $value, $ttl);
if ($this->memory->reachedMemoryLimit()) {
return $this->cache->setMultiple($this->memory->flush(), $ttl);
}
return true;
}
/**
* {@inheritdoc}
*/
public function delete($key)
{
if ($this->memory->has($key)) {
return $this->memory->delete($key);
}
return $this->cache->delete($key);
}
/**
* {@inheritdoc}
*/
public function clear()
{
$this->memory->clear();
return $this->cache->clear();
}
/**
* {@inheritdoc}
*/
public function getMultiple($keys, $default = null)
{
// Check if all keys are still in memory
$memory = $this->memory->getMultiple($keys, $default);
$actualItemsInMemory = count(array_filter($memory));
if ($actualItemsInMemory === count($keys)) {
return $memory;
}
// Get all rows from cache if none is hold in memory.
if ($actualItemsInMemory === 0) {
return $this->cache->getMultiple($keys, $default);
}
// Add missing values from cache.
foreach ($this->cache->getMultiple($keys, $default) as $key => $value) {
if (null !== $value) {
$memory[$key] = $value;
}
}
return $memory;
}
/**
* {@inheritdoc}
*/
public function setMultiple($values, $ttl = null)
{
$this->memory->setMultiple($values, $ttl);
if ($this->memory->reachedMemoryLimit()) {
return $this->cache->setMultiple($this->memory->flush(), $ttl);
}
return true;
}
/**
* {@inheritdoc}
*/
public function deleteMultiple($keys)
{
$keys = is_array($keys) ? $keys : iterator_to_array($keys);
$this->memory->deleteMultiple($keys);
return $this->cache->deleteMultiple($keys);
}
/**
* {@inheritdoc}
*/
public function has($key)
{
if ($this->memory->has($key)) {
return true;
}
return $this->cache->has($key);
}
}

View File

@@ -0,0 +1,76 @@
<?php
namespace Maatwebsite\Excel\Cache;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Manager;
use Psr\SimpleCache\CacheInterface;
class CacheManager extends Manager
{
/**
* @const string
*/
public const DRIVER_BATCH = 'batch';
/**
* @const string
*/
public const DRIVER_MEMORY = 'memory';
/**
* @const string
*/
public const DRIVER_ILLUMINATE = 'illuminate';
/**
* Get the default driver name.
*
* @return string
*/
public function getDefaultDriver(): string
{
return config('excel.cache.driver', 'memory');
}
/**
* @return MemoryCache
*/
public function createMemoryDriver(): CacheInterface
{
return new MemoryCache(
config('excel.cache.batch.memory_limit', 60000)
);
}
/**
* @return BatchCache
*/
public function createBatchDriver(): CacheInterface
{
return new BatchCache(
$this->createIlluminateDriver(),
$this->createMemoryDriver()
);
}
/**
* @return CacheInterface
*/
public function createIlluminateDriver(): CacheInterface
{
return Cache::driver(
config('excel.cache.illuminate.store')
);
}
public function flush()
{
$this->driver()->clear();
}
public function isInMemory(): bool
{
return $this->getDefaultDriver() === self::DRIVER_MEMORY;
}
}

View File

@@ -0,0 +1,138 @@
<?php
namespace Maatwebsite\Excel\Cache;
use Psr\SimpleCache\CacheInterface;
class MemoryCache implements CacheInterface
{
/**
* @var int|null
*/
protected $memoryLimit;
/**
* @var array
*/
protected $cache = [];
/**
* @param int|null $memoryLimit
*/
public function __construct(int $memoryLimit = null)
{
$this->memoryLimit = $memoryLimit;
}
/**
* {@inheritdoc}
*/
public function clear()
{
$this->cache = [];
return true;
}
/**
* {@inheritdoc}
*/
public function delete($key)
{
unset($this->cache[$key]);
return true;
}
/**
* {@inheritdoc}
*/
public function deleteMultiple($keys)
{
foreach ($keys as $key) {
$this->delete($key);
}
return true;
}
/**
* {@inheritdoc}
*/
public function get($key, $default = null)
{
if ($this->has($key)) {
return $this->cache[$key];
}
return $default;
}
/**
* {@inheritdoc}
*/
public function getMultiple($keys, $default = null)
{
$results = [];
foreach ($keys as $key) {
$results[$key] = $this->get($key, $default);
}
return $results;
}
/**
* {@inheritdoc}
*/
public function has($key)
{
return isset($this->cache[$key]);
}
/**
* {@inheritdoc}
*/
public function set($key, $value, $ttl = null)
{
$this->cache[$key] = $value;
return true;
}
/**
* {@inheritdoc}
*/
public function setMultiple($values, $ttl = null)
{
foreach ($values as $key => $value) {
$this->set($key, $value);
}
return true;
}
/**
* @return bool
*/
public function reachedMemoryLimit(): bool
{
// When no limit is given, we'll never reach any limit.
if (null === $this->memoryLimit) {
return false;
}
return count($this->cache) >= $this->memoryLimit;
}
/**
* @return array
*/
public function flush(): array
{
$memory = $this->cache;
$this->clear();
return $memory;
}
}

82
vendor/maatwebsite/excel/src/Cell.php vendored Normal file
View File

@@ -0,0 +1,82 @@
<?php
namespace Maatwebsite\Excel;
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
use PhpOffice\PhpSpreadsheet\Cell\Cell as SpreadsheetCell;
use PhpOffice\PhpSpreadsheet\RichText\RichText;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
class Cell
{
use DelegatedMacroable;
/**
* @var SpreadsheetCell
*/
private $cell;
/**
* @param SpreadsheetCell $cell
*/
public function __construct(SpreadsheetCell $cell)
{
$this->cell = $cell;
}
/**
* @param Worksheet $worksheet
* @param string $coordinate
*
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @return Cell
*/
public static function make(Worksheet $worksheet, string $coordinate)
{
return new static($worksheet->getCell($coordinate));
}
/**
* @return SpreadsheetCell
*/
public function getDelegate(): SpreadsheetCell
{
return $this->cell;
}
/**
* @param null $nullValue
* @param bool $calculateFormulas
* @param bool $formatData
*
* @return mixed
*/
public function getValue($nullValue = null, $calculateFormulas = false, $formatData = true)
{
$value = $nullValue;
if ($this->cell->getValue() !== null) {
if ($this->cell->getValue() instanceof RichText) {
$value = $this->cell->getValue()->getPlainText();
} elseif ($calculateFormulas) {
try {
$value = $this->cell->getCalculatedValue();
} catch (Exception $e) {
$value = $this->cell->getOldCalculatedValue();
}
} else {
$value = $this->cell->getValue();
}
if ($formatData) {
$style = $this->cell->getWorksheet()->getParent()->getCellXfByIndex($this->cell->getXfIndex());
$value = NumberFormat::toFormattedString(
$value,
($style && $style->getNumberFormat()) ? $style->getNumberFormat()->getFormatCode() : NumberFormat::FORMAT_GENERAL
);
}
}
return $value;
}
}

View File

@@ -0,0 +1,108 @@
<?php
namespace Maatwebsite\Excel;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\PendingDispatch;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ShouldQueueWithoutChain;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\WithLimit;
use Maatwebsite\Excel\Concerns\WithProgressBar;
use Maatwebsite\Excel\Events\BeforeImport;
use Maatwebsite\Excel\Files\TemporaryFile;
use Maatwebsite\Excel\Imports\HeadingRowExtractor;
use Maatwebsite\Excel\Jobs\AfterImportJob;
use Maatwebsite\Excel\Jobs\QueueImport;
use Maatwebsite\Excel\Jobs\ReadChunk;
use Throwable;
class ChunkReader
{
/**
* @param WithChunkReading $import
* @param Reader $reader
* @param TemporaryFile $temporaryFile
*
* @return \Illuminate\Foundation\Bus\PendingDispatch|null
*/
public function read(WithChunkReading $import, Reader $reader, TemporaryFile $temporaryFile)
{
if ($import instanceof WithEvents && isset($import->registerEvents()[BeforeImport::class])) {
$reader->beforeImport($import);
}
$chunkSize = $import->chunkSize();
$totalRows = $reader->getTotalRows();
$worksheets = $reader->getWorksheets($import);
$queue = property_exists($import, 'queue') ? $import->queue : null;
$delayCleanup = property_exists($import, 'delayCleanup') ? $import->delayCleanup : 600;
if ($import instanceof WithProgressBar) {
$import->getConsoleOutput()->progressStart(array_sum($totalRows));
}
$jobs = new Collection();
foreach ($worksheets as $name => $sheetImport) {
$startRow = HeadingRowExtractor::determineStartRow($sheetImport);
if ($sheetImport instanceof WithLimit) {
$limit = $sheetImport->limit();
if ($limit <= $totalRows[$name]) {
$totalRows[$name] = $sheetImport->limit();
}
}
for ($currentRow = $startRow; $currentRow <= $totalRows[$name]; $currentRow += $chunkSize) {
$jobs->push(new ReadChunk(
$import,
$reader->getPhpSpreadsheetReader(),
$temporaryFile,
$name,
$sheetImport,
$currentRow,
$chunkSize
));
}
}
$afterImportJob = new AfterImportJob($import, $reader);
if ($import instanceof ShouldQueueWithoutChain) {
$jobs->push($afterImportJob->delay($delayCleanup));
return $jobs->each(function ($job) use ($queue) {
dispatch($job->onQueue($queue));
});
}
$jobs->push($afterImportJob);
if ($import instanceof ShouldQueue) {
return new PendingDispatch(
(new QueueImport($import))->chain($jobs->toArray())
);
}
$jobs->each(function ($job) {
try {
dispatch_now($job);
} catch (Throwable $e) {
if (method_exists($job, 'failed')) {
$job->failed($e);
}
throw $e;
}
});
if ($import instanceof WithProgressBar) {
$import->getConsoleOutput()->progressFinish();
}
unset($jobs);
return null;
}
}

View File

@@ -0,0 +1,117 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Illuminate\Foundation\Bus\PendingDispatch;
use Maatwebsite\Excel\Exceptions\NoFilenameGivenException;
use Maatwebsite\Excel\Exceptions\NoFilePathGivenException;
use Maatwebsite\Excel\Exporter;
trait Exportable
{
/**
* @param string $fileName
* @param string|null $writerType
* @param array $headers
*
* @throws NoFilenameGivenException
* @return \Illuminate\Http\Response|\Symfony\Component\HttpFoundation\BinaryFileResponse
*/
public function download(string $fileName = null, string $writerType = null, array $headers = null)
{
$headers = $headers ?? $this->headers ?? [];
$fileName = $fileName ?? $this->fileName ?? null;
$writerType = $writerType ?? $this->writerType ?? null;
if (null === $fileName) {
throw new NoFilenameGivenException();
}
return $this->getExporter()->download($this, $fileName, $writerType, $headers);
}
/**
* @param string $filePath
* @param string|null $disk
* @param string|null $writerType
* @param mixed $diskOptions
*
* @throws NoFilePathGivenException
* @return bool|PendingDispatch
*/
public function store(string $filePath = null, string $disk = null, string $writerType = null, $diskOptions = [])
{
$filePath = $filePath ?? $this->filePath ?? null;
if (null === $filePath) {
throw NoFilePathGivenException::export();
}
return $this->getExporter()->store(
$this,
$filePath,
$disk ?? $this->disk ?? null,
$writerType ?? $this->writerType ?? null,
$diskOptions ?? $this->diskOptions ?? []
);
}
/**
* @param string|null $filePath
* @param string|null $disk
* @param string|null $writerType
* @param mixed $diskOptions
*
* @throws NoFilePathGivenException
* @return PendingDispatch
*/
public function queue(string $filePath = null, string $disk = null, string $writerType = null, $diskOptions = [])
{
$filePath = $filePath ?? $this->filePath ?? null;
if (null === $filePath) {
throw NoFilePathGivenException::export();
}
return $this->getExporter()->queue(
$this,
$filePath,
$disk ?? $this->disk ?? null,
$writerType ?? $this->writerType ?? null,
$diskOptions ?? $this->diskOptions ?? []
);
}
/**
* @param string|null $writerType
*
* @return string
*/
public function raw($writerType = null)
{
$writerType = $writerType ?? $this->writerType ?? null;
return $this->getExporter()->raw($this, $writerType);
}
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
*
* @throws NoFilenameGivenException
* @return \Illuminate\Http\Response
*/
public function toResponse($request)
{
return $this->download();
}
/**
* @return Exporter
*/
private function getExporter(): Exporter
{
return app(Exporter::class);
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface FromArray
{
/**
* @return array
*/
public function array(): array;
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Illuminate\Support\Collection;
interface FromCollection
{
/**
* @return Collection
*/
public function collection();
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Generator;
interface FromGenerator
{
/**
* @return Generator
*/
public function generator(): Generator;
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Iterator;
interface FromIterator
{
/**
* @return Iterator
*/
public function iterator(): Iterator;
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Illuminate\Database\Query\Builder;
interface FromQuery
{
/**
* @return Builder
*/
public function query();
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Illuminate\Contracts\View\View;
interface FromView
{
/**
* @return View
*/
public function view(): View;
}

View File

@@ -0,0 +1,7 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface HasReferencesToOtherSheets
{
}

View File

@@ -0,0 +1,149 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Illuminate\Console\OutputStyle;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\PendingDispatch;
use Illuminate\Support\Collection;
use InvalidArgumentException;
use Maatwebsite\Excel\Exceptions\NoFilePathGivenException;
use Maatwebsite\Excel\Importer;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\HttpFoundation\File\UploadedFile;
trait Importable
{
/**
* @var OutputStyle|null
*/
protected $output;
/**
* @param string|UploadedFile|null $filePath
* @param string|null $disk
* @param string|null $readerType
*
* @throws NoFilePathGivenException
* @return Importer|PendingDispatch
*/
public function import($filePath = null, string $disk = null, string $readerType = null)
{
$filePath = $this->getFilePath($filePath);
return $this->getImporter()->import(
$this,
$filePath,
$disk ?? $this->disk ?? null,
$readerType ?? $this->readerType ?? null
);
}
/**
* @param string|UploadedFile|null $filePath
* @param string|null $disk
* @param string|null $readerType
*
* @throws NoFilePathGivenException
* @return array
*/
public function toArray($filePath = null, string $disk = null, string $readerType = null): array
{
$filePath = $this->getFilePath($filePath);
return $this->getImporter()->toArray(
$this,
$filePath,
$disk ?? $this->disk ?? null,
$readerType ?? $this->readerType ?? null
);
}
/**
* @param string|UploadedFile|null $filePath
* @param string|null $disk
* @param string|null $readerType
*
* @throws NoFilePathGivenException
* @return Collection
*/
public function toCollection($filePath = null, string $disk = null, string $readerType = null): Collection
{
$filePath = $this->getFilePath($filePath);
return $this->getImporter()->toCollection(
$this,
$filePath,
$disk ?? $this->disk ?? null,
$readerType ?? $this->readerType ?? null
);
}
/**
* @param string|UploadedFile|null $filePath
* @param string|null $disk
* @param string|null $readerType
*
* @throws NoFilePathGivenException
* @throws InvalidArgumentException
* @return PendingDispatch
*/
public function queue($filePath = null, string $disk = null, string $readerType = null)
{
if (!$this instanceof ShouldQueue) {
throw new InvalidArgumentException('Importable should implement ShouldQueue to be queued.');
}
return $this->import($filePath, $disk, $readerType);
}
/**
* @param OutputStyle $output
*
* @return $this
*/
public function withOutput(OutputStyle $output)
{
$this->output = $output;
return $this;
}
/**
* @return OutputStyle
*/
public function getConsoleOutput(): OutputStyle
{
if (!$this->output instanceof OutputStyle) {
$this->output = new OutputStyle(new StringInput(''), new NullOutput());
}
return $this->output;
}
/**
* @param UploadedFile|string|null $filePath
*
* @throws NoFilePathGivenException
* @return UploadedFile|string
*/
private function getFilePath($filePath = null)
{
$filePath = $filePath ?? $this->filePath ?? null;
if (null === $filePath) {
throw NoFilePathGivenException::import();
}
return $filePath;
}
/**
* @return Importer
*/
private function getImporter(): Importer
{
return app(Importer::class);
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Illuminate\Support\Arr;
trait MapsCsvSettings
{
/**
* @var string
*/
protected static $delimiter = ',';
/**
* @var string
*/
protected static $enclosure = '"';
/**
* @var string
*/
protected static $lineEnding = PHP_EOL;
/**
* @var bool
*/
protected static $useBom = false;
/**
* @var bool
*/
protected static $includeSeparatorLine = false;
/**
* @var bool
*/
protected static $excelCompatibility = false;
/**
* @var string
*/
protected static $escapeCharacter = '\\';
/**
* @var bool
*/
protected static $contiguous = false;
/**
* @var string
*/
protected static $inputEncoding = 'UTF-8';
/**
* @param array $config
*/
public static function applyCsvSettings(array $config)
{
static::$delimiter = Arr::get($config, 'delimiter', static::$delimiter);
static::$enclosure = Arr::get($config, 'enclosure', static::$enclosure);
static::$lineEnding = Arr::get($config, 'line_ending', static::$lineEnding);
static::$useBom = Arr::get($config, 'use_bom', static::$useBom);
static::$includeSeparatorLine = Arr::get($config, 'include_separator_line', static::$includeSeparatorLine);
static::$excelCompatibility = Arr::get($config, 'excel_compatibility', static::$excelCompatibility);
static::$escapeCharacter = Arr::get($config, 'escape_character', static::$escapeCharacter);
static::$contiguous = Arr::get($config, 'contiguous', static::$contiguous);
static::$inputEncoding = Arr::get($config, 'input_encoding', static::$inputEncoding);
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Maatwebsite\Excel\Row;
interface OnEachRow
{
/**
* @param Row $row
*/
public function onRow(Row $row);
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Maatwebsite\Excel\Events\AfterImport;
use Maatwebsite\Excel\Events\AfterSheet;
use Maatwebsite\Excel\Events\BeforeExport;
use Maatwebsite\Excel\Events\BeforeImport;
use Maatwebsite\Excel\Events\BeforeSheet;
use Maatwebsite\Excel\Events\BeforeWriting;
use Maatwebsite\Excel\Events\ImportFailed;
trait RegistersEventListeners
{
/**
* @return array
*/
public function registerEvents(): array
{
$listeners = [];
if (method_exists($this, 'beforeExport')) {
$listeners[BeforeExport::class] = [static::class, 'beforeExport'];
}
if (method_exists($this, 'beforeWriting')) {
$listeners[BeforeWriting::class] = [static::class, 'beforeWriting'];
}
if (method_exists($this, 'beforeImport')) {
$listeners[BeforeImport::class] = [static::class, 'beforeImport'];
}
if (method_exists($this, 'afterImport')) {
$listeners[AfterImport::class] = [static::class, 'afterImport'];
}
if (method_exists($this, 'importFailed')) {
$listeners[ImportFailed::class] = [static::class, 'importFailed'];
}
if (method_exists($this, 'beforeSheet')) {
$listeners[BeforeSheet::class] = [static::class, 'beforeSheet'];
}
if (method_exists($this, 'afterSheet')) {
$listeners[AfterSheet::class] = [static::class, 'afterSheet'];
}
return $listeners;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Maatwebsite\Excel\Concerns;
trait RemembersChunkOffset
{
/**
* @var int|null
*/
protected $chunkOffset;
/**
* @param int $chunkOffset
*/
public function setChunkOffset(int $chunkOffset)
{
$this->chunkOffset = $chunkOffset;
}
/**
* @return int|null
*/
public function getChunkOffset()
{
return $this->chunkOffset;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Maatwebsite\Excel\Concerns;
trait RemembersRowNumber
{
/**
* @var int
*/
protected $rowNumber;
/**
* @param int $rowNumber
*/
public function rememberRowNumber(int $rowNumber)
{
$this->rowNumber = $rowNumber;
}
/**
* @return int|null
*/
public function getRowNumber()
{
return $this->rowNumber;
}
}

View File

@@ -0,0 +1,7 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface ShouldAutoSize
{
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Illuminate\Contracts\Queue\ShouldQueue;
interface ShouldQueueWithoutChain extends ShouldQueue
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface SkipsEmptyRows
{
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Illuminate\Support\Collection;
use Throwable;
trait SkipsErrors
{
/**
* @var Throwable[]
*/
protected $errors = [];
/**
* @param Throwable $e
*/
public function onError(Throwable $e)
{
$this->errors[] = $e;
}
/**
* @return Throwable[]|Collection
*/
public function errors(): Collection
{
return new Collection($this->errors);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Validators\Failure;
trait SkipsFailures
{
/**
* @var Failure[]
*/
protected $failures = [];
/**
* @param Failure ...$failures
*/
public function onFailure(Failure ...$failures)
{
$this->failures = array_merge($this->failures, $failures);
}
/**
* @return Failure[]|Collection
*/
public function failures(): Collection
{
return new Collection($this->failures);
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Throwable;
interface SkipsOnError
{
/**
* @param Throwable $e
*/
public function onError(Throwable $e);
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Maatwebsite\Excel\Validators\Failure;
interface SkipsOnFailure
{
/**
* @param Failure[] $failures
*/
public function onFailure(Failure ...$failures);
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface SkipsUnknownSheets
{
/**
* @param string|int $sheetName
*/
public function onUnknownSheet($sheetName);
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface ToArray
{
/**
* @param array $array
*/
public function array(array $array);
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Illuminate\Support\Collection;
interface ToCollection
{
/**
* @param Collection $collection
*/
public function collection(Collection $collection);
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Illuminate\Database\Eloquent\Model;
interface ToModel
{
/**
* @param array $row
*
* @return Model|Model[]|null
*/
public function model(array $row);
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithBatchInserts
{
/**
* @return int
*/
public function batchSize(): int;
}

View File

@@ -0,0 +1,7 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithCalculatedFormulas
{
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use PhpOffice\PhpSpreadsheet\Chart\Chart;
interface WithCharts
{
/**
* @return Chart|Chart[]
*/
public function charts();
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithChunkReading
{
/**
* @return int
*/
public function chunkSize(): int;
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithColumnFormatting
{
/**
* @return array
*/
public function columnFormats(): array;
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithColumnLimit
{
public function endColumn(): string;
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithColumnWidths
{
public function columnWidths(): array;
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Maatwebsite\Excel\Concerns;
trait WithConditionalSheets
{
/**
* @var array
*/
protected $conditionallySelectedSheets = [];
/**
* @param string|array $sheets
*
* @return $this
*/
public function onlySheets($sheets)
{
$this->conditionallySelectedSheets = is_array($sheets) ? $sheets : func_get_args();
return $this;
}
/**
* @return array
*/
public function sheets(): array
{
return \array_filter($this->conditionalSheets(), function ($name) {
return \in_array($name, $this->conditionallySelectedSheets, false);
}, ARRAY_FILTER_USE_KEY);
}
/**
* @return array
*/
abstract public function conditionalSheets(): array;
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithCustomChunkSize
{
/**
* @return int
*/
public function chunkSize(): int;
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithCustomCsvSettings
{
/**
* @return array
*/
public function getCsvSettings(): array;
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithCustomQuerySize
{
/**
* Queued exportables are processed in chunks; each chunk being a job pushed to the queue by the QueuedWriter.
* In case of exportables that implement the FromQuery concern, the number of jobs is calculated by dividing the $query->count() by the chunk size.
* Depending on the implementation of the query() method (eg. When using a groupBy clause), this calculation might not be correct.
*
* When this is the case, you should use this method to provide a custom calculation of the query size.
*
* @return int
*/
public function querySize(): int;
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithCustomStartCell
{
/**
* @return string
*/
public function startCell(): string;
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use PhpOffice\PhpSpreadsheet\Cell\IValueBinder;
interface WithCustomValueBinder extends IValueBinder
{
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing;
interface WithDrawings
{
/**
* @return BaseDrawing|BaseDrawing[]
*/
public function drawings();
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithEvents
{
/**
* @return array
*/
public function registerEvents(): array;
}

View File

@@ -0,0 +1,7 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithFormatData
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithHeadingRow
{
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithHeadings
{
/**
* @return array
*/
public function headings(): array;
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithLimit
{
/**
* @return int
*/
public function limit(): int;
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithMappedCells
{
/**
* @return array
*/
public function mapping(): array;
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithMapping
{
/**
* @param mixed $row
*
* @return array
*/
public function map($row): array;
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithMultipleSheets
{
/**
* @return array
*/
public function sheets(): array;
}

View File

@@ -0,0 +1,7 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithPreCalculateFormulas
{
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use Illuminate\Console\OutputStyle;
interface WithProgressBar
{
/**
* @return OutputStyle
*/
public function getConsoleOutput(): OutputStyle;
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithProperties
{
public function properties(): array;
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use PhpOffice\PhpSpreadsheet\Reader\IReadFilter;
interface WithReadFilter
{
/**
* @return IReadFilter
*/
public function readFilter(): IReadFilter;
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithStartRow
{
/**
* @return int
*/
public function startRow(): int;
}

View File

@@ -0,0 +1,7 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithStrictNullComparison
{
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Maatwebsite\Excel\Concerns;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
interface WithStyles
{
public function styles(Worksheet $sheet);
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithTitle
{
/**
* @return string
*/
public function title(): string;
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithUpsertColumns
{
/**
* @return array
*/
public function upsertColumns();
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithUpserts
{
/**
* @return string|array
*/
public function uniqueBy();
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Maatwebsite\Excel\Concerns;
interface WithValidation
{
/**
* @return array
*/
public function rules(): array;
}

View File

@@ -0,0 +1,95 @@
<?php
namespace Maatwebsite\Excel\Console;
use Illuminate\Console\GeneratorCommand;
use Symfony\Component\Console\Input\InputOption;
class ExportMakeCommand extends GeneratorCommand
{
use WithModelStub;
/**
* The console command name.
*
* @var string
*/
protected $name = 'make:export';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new export class';
/**
* The type of class being generated.
*
* @var string
*/
protected $type = 'Export';
/**
* Get the stub file for the generator.
*
* @return string
*/
protected function getStub()
{
if ($this->option('model') && $this->option('query')) {
return $this->resolveStubPath('/stubs/export.query-model.stub');
} elseif ($this->option('model')) {
return $this->resolveStubPath('/stubs/export.model.stub');
} elseif ($this->option('query')) {
return $this->resolveStubPath('/stubs/export.query.stub');
}
return $this->resolveStubPath('/stubs/export.plain.stub');
}
/**
* Get the default namespace for the class.
*
* @param string $rootNamespace
*
* @return string
*/
protected function getDefaultNamespace($rootNamespace)
{
return $rootNamespace . '\Exports';
}
/**
* Build the class with the given name.
* Remove the base controller import if we are already in base namespace.
*
* @param string $name
*
* @return string
*/
protected function buildClass($name)
{
$replace = [];
if ($this->option('model')) {
$replace = $this->buildModelReplacements($replace);
}
return str_replace(
array_keys($replace), array_values($replace), parent::buildClass($name)
);
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['model', 'm', InputOption::VALUE_OPTIONAL, 'Generate an export for the given model.'],
['query', '', InputOption::VALUE_NONE, 'Generate an export for a query.'],
];
}
}

View File

@@ -0,0 +1,88 @@
<?php
namespace Maatwebsite\Excel\Console;
use Illuminate\Console\GeneratorCommand;
use Symfony\Component\Console\Input\InputOption;
class ImportMakeCommand extends GeneratorCommand
{
use WithModelStub;
/**
* The console command name.
*
* @var string
*/
protected $name = 'make:import';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new import class';
/**
* The type of class being generated.
*
* @var string
*/
protected $type = 'Import';
/**
* Get the stub file for the generator.
*
* @return string
*/
protected function getStub()
{
return $this->option('model')
? $this->resolveStubPath('/stubs/import.model.stub')
: $this->resolveStubPath('/stubs/import.collection.stub');
}
/**
* Get the default namespace for the class.
*
* @param string $rootNamespace
*
* @return string
*/
protected function getDefaultNamespace($rootNamespace)
{
return $rootNamespace . '\Imports';
}
/**
* Build the class with the given name.
* Remove the base controller import if we are already in base namespace.
*
* @param string $name
*
* @return string
*/
protected function buildClass($name)
{
$replace = [];
if ($this->option('model')) {
$replace = $this->buildModelReplacements($replace);
}
return str_replace(
array_keys($replace), array_values($replace), parent::buildClass($name)
);
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['model', 'm', InputOption::VALUE_OPTIONAL, 'Generate an import for the given model.'],
];
}
}

View File

@@ -0,0 +1,61 @@
<?php
namespace Maatwebsite\Excel\Console;
use Illuminate\Support\Str;
use InvalidArgumentException;
trait WithModelStub
{
/**
* Build the model replacement values.
*
* @param array $replace
*
* @return array
*/
protected function buildModelReplacements(array $replace): array
{
$modelClass = $this->parseModel($this->option('model'));
return array_merge($replace, [
'DummyFullModelClass' => $modelClass,
'DummyModelClass' => class_basename($modelClass),
]);
}
/**
* Get the fully-qualified model class name.
*
* @param string $model
*
* @return string
*/
protected function parseModel($model): string
{
if (preg_match('([^A-Za-z0-9_/\\\\])', $model)) {
throw new InvalidArgumentException('Model name contains invalid characters.');
}
$model = trim(str_replace('/', '\\', $model), '\\');
if (!Str::startsWith($model, $rootNamespace = $this->laravel->getNamespace())) {
$model = $rootNamespace . $model;
}
return $model;
}
/**
* Resolve the fully-qualified path to the stub.
*
* @param string $stub
* @return string
*/
protected function resolveStubPath($stub)
{
return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))
? $customPath
: __DIR__ . $stub;
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace DummyNamespace;
use DummyFullModelClass;
use Maatwebsite\Excel\Concerns\FromCollection;
class DummyClass implements FromCollection
{
/**
* @return \Illuminate\Support\Collection
*/
public function collection()
{
return DummyModelClass::all();
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace DummyNamespace;
use Maatwebsite\Excel\Concerns\FromCollection;
class DummyClass implements FromCollection
{
/**
* @return \Illuminate\Support\Collection
*/
public function collection()
{
//
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace DummyNamespace;
use DummyFullModelClass;
use Maatwebsite\Excel\Concerns\FromQuery;
class DummyClass implements FromQuery
{
/**
* @return \Illuminate\Database\Query\Builder
*/
public function query()
{
return DummyModelClass::query();
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace DummyNamespace;
use Maatwebsite\Excel\Concerns\FromQuery;
class DummyClass implements FromQuery
{
/**
* @return \Illuminate\Database\Query\Builder
*/
public function query()
{
//
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace DummyNamespace;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
class DummyClass implements ToCollection
{
/**
* @param Collection $collection
*/
public function collection(Collection $collection)
{
//
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace DummyNamespace;
use DummyFullModelClass;
use Maatwebsite\Excel\Concerns\ToModel;
class DummyClass implements ToModel
{
/**
* @param array $row
*
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function model(array $row)
{
return new DummyModelClass([
//
]);
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Maatwebsite\Excel;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder as PhpSpreadsheetDefaultValueBinder;
class DefaultValueBinder extends PhpSpreadsheetDefaultValueBinder
{
/**
* @param Cell $cell Cell to bind value to
* @param mixed $value Value to bind in cell
*
* @return bool
*/
public function bindValue(Cell $cell, $value)
{
if (is_array($value)) {
$value = \json_encode($value);
}
return parent::bindValue($cell, $value);
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Maatwebsite\Excel;
use Illuminate\Support\Traits\Macroable;
trait DelegatedMacroable
{
use Macroable {
__call as __callMacro;
}
/**
* Dynamically handle calls to the class.
*
* @param string $method
* @param array $parameters
*
* @return mixed
*/
public function __call($method, $parameters)
{
if (method_exists($this->getDelegate(), $method)) {
return call_user_func_array([$this->getDelegate(), $method], $parameters);
}
array_unshift($parameters, $this);
return $this->__callMacro($method, $parameters);
}
/**
* @return object
*/
abstract public function getDelegate();
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Maatwebsite\Excel\Events;
use Maatwebsite\Excel\Reader;
class AfterImport extends Event
{
/**
* @var Reader
*/
public $reader;
/**
* @var object
*/
private $importable;
/**
* @param Reader $reader
* @param object $importable
*/
public function __construct(Reader $reader, $importable)
{
$this->reader = $reader;
$this->importable = $importable;
}
/**
* @return Reader
*/
public function getReader(): Reader
{
return $this->reader;
}
/**
* @return object
*/
public function getConcernable()
{
return $this->importable;
}
/**
* @return mixed
*/
public function getDelegate()
{
return $this->reader;
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Maatwebsite\Excel\Events;
use Maatwebsite\Excel\Sheet;
class AfterSheet extends Event
{
/**
* @var Sheet
*/
public $sheet;
/**
* @var object
*/
private $exportable;
/**
* @param Sheet $sheet
* @param object $exportable
*/
public function __construct(Sheet $sheet, $exportable)
{
$this->sheet = $sheet;
$this->exportable = $exportable;
}
/**
* @return Sheet
*/
public function getSheet(): Sheet
{
return $this->sheet;
}
/**
* @return object
*/
public function getConcernable()
{
return $this->exportable;
}
/**
* @return mixed
*/
public function getDelegate()
{
return $this->sheet;
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Maatwebsite\Excel\Events;
use Maatwebsite\Excel\Writer;
class BeforeExport extends Event
{
/**
* @var Writer
*/
public $writer;
/**
* @var object
*/
private $exportable;
/**
* @param Writer $writer
* @param object $exportable
*/
public function __construct(Writer $writer, $exportable)
{
$this->writer = $writer;
$this->exportable = $exportable;
}
/**
* @return Writer
*/
public function getWriter(): Writer
{
return $this->writer;
}
/**
* @return object
*/
public function getConcernable()
{
return $this->exportable;
}
/**
* @return mixed
*/
public function getDelegate()
{
return $this->writer;
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Maatwebsite\Excel\Events;
use Maatwebsite\Excel\Reader;
class BeforeImport extends Event
{
/**
* @var Reader
*/
public $reader;
/**
* @var object
*/
private $importable;
/**
* @param Reader $reader
* @param object $importable
*/
public function __construct(Reader $reader, $importable)
{
$this->reader = $reader;
$this->importable = $importable;
}
/**
* @return Reader
*/
public function getReader(): Reader
{
return $this->reader;
}
/**
* @return object
*/
public function getConcernable()
{
return $this->importable;
}
/**
* @return mixed
*/
public function getDelegate()
{
return $this->reader;
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Maatwebsite\Excel\Events;
use Maatwebsite\Excel\Sheet;
class BeforeSheet extends Event
{
/**
* @var Sheet
*/
public $sheet;
/**
* @var object
*/
private $exportable;
/**
* @param Sheet $sheet
* @param object $exportable
*/
public function __construct(Sheet $sheet, $exportable)
{
$this->sheet = $sheet;
$this->exportable = $exportable;
}
/**
* @return Sheet
*/
public function getSheet(): Sheet
{
return $this->sheet;
}
/**
* @return object
*/
public function getConcernable()
{
return $this->exportable;
}
/**
* @return mixed
*/
public function getDelegate()
{
return $this->sheet;
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Maatwebsite\Excel\Events;
use Maatwebsite\Excel\Writer;
class BeforeWriting extends Event
{
/**
* @var Writer
*/
public $writer;
/**
* @var object
*/
private $exportable;
/**
* @param Writer $writer
* @param object $exportable
*/
public function __construct(Writer $writer, $exportable)
{
$this->writer = $writer;
$this->exportable = $exportable;
}
/**
* @return Writer
*/
public function getWriter(): Writer
{
return $this->writer;
}
/**
* @return object
*/
public function getConcernable()
{
return $this->exportable;
}
/**
* @return mixed
*/
public function getDelegate()
{
return $this->writer;
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Maatwebsite\Excel\Events;
abstract class Event
{
/**
* @return object
*/
abstract public function getConcernable();
/**
* @return mixed
*/
abstract public function getDelegate();
/**
* @param string $concern
*
* @return bool
*/
public function appliesToConcern(string $concern): bool
{
return $this->getConcernable() instanceof $concern;
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Maatwebsite\Excel\Events;
use Throwable;
class ImportFailed
{
/**
* @var Throwable
*/
public $e;
/**
* @param Throwable $e
*/
public function __construct(Throwable $e)
{
$this->e = $e;
}
/**
* @return Throwable
*/
public function getException(): Throwable
{
return $this->e;
}
}

197
vendor/maatwebsite/excel/src/Excel.php vendored Normal file
View File

@@ -0,0 +1,197 @@
<?php
namespace Maatwebsite\Excel;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\PendingDispatch;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Files\Filesystem;
use Maatwebsite\Excel\Files\TemporaryFile;
use Maatwebsite\Excel\Helpers\FileTypeDetector;
class Excel implements Exporter, Importer
{
use RegistersCustomConcerns;
const XLSX = 'Xlsx';
const CSV = 'Csv';
const TSV = 'Csv';
const ODS = 'Ods';
const XLS = 'Xls';
const SLK = 'Slk';
const XML = 'Xml';
const GNUMERIC = 'Gnumeric';
const HTML = 'Html';
const MPDF = 'Mpdf';
const DOMPDF = 'Dompdf';
const TCPDF = 'Tcpdf';
/**
* @var Writer
*/
protected $writer;
/**
* @var QueuedWriter
*/
protected $queuedWriter;
/**
* @var Filesystem
*/
protected $filesystem;
/**
* @var Reader
*/
private $reader;
/**
* @param Writer $writer
* @param QueuedWriter $queuedWriter
* @param Reader $reader
* @param Filesystem $filesystem
*/
public function __construct(
Writer $writer,
QueuedWriter $queuedWriter,
Reader $reader,
Filesystem $filesystem
) {
$this->writer = $writer;
$this->reader = $reader;
$this->filesystem = $filesystem;
$this->queuedWriter = $queuedWriter;
}
/**
* {@inheritdoc}
*/
public function download($export, string $fileName, string $writerType = null, array $headers = [])
{
return response()->download(
$this->export($export, $fileName, $writerType)->getLocalPath(),
$fileName,
$headers
)->deleteFileAfterSend(true);
}
/**
* {@inheritdoc}
*/
public function store($export, string $filePath, string $diskName = null, string $writerType = null, $diskOptions = [])
{
if ($export instanceof ShouldQueue) {
return $this->queue($export, $filePath, $diskName, $writerType, $diskOptions);
}
$temporaryFile = $this->export($export, $filePath, $writerType);
$exported = $this->filesystem->disk($diskName, $diskOptions)->copy(
$temporaryFile,
$filePath
);
$temporaryFile->delete();
return $exported;
}
/**
* {@inheritdoc}
*/
public function queue($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = [])
{
$writerType = FileTypeDetector::detectStrict($filePath, $writerType);
return $this->queuedWriter->store(
$export,
$filePath,
$disk,
$writerType,
$diskOptions
);
}
/**
* {@inheritdoc}
*/
public function raw($export, string $writerType)
{
$temporaryFile = $this->writer->export($export, $writerType);
$contents = $temporaryFile->contents();
$temporaryFile->delete();
return $contents;
}
/**
* {@inheritdoc}
*/
public function import($import, $filePath, string $disk = null, string $readerType = null)
{
$readerType = FileTypeDetector::detect($filePath, $readerType);
$response = $this->reader->read($import, $filePath, $readerType, $disk);
if ($response instanceof PendingDispatch) {
return $response;
}
return $this;
}
/**
* {@inheritdoc}
*/
public function toArray($import, $filePath, string $disk = null, string $readerType = null): array
{
$readerType = FileTypeDetector::detect($filePath, $readerType);
return $this->reader->toArray($import, $filePath, $readerType, $disk);
}
/**
* {@inheritdoc}
*/
public function toCollection($import, $filePath, string $disk = null, string $readerType = null): Collection
{
$readerType = FileTypeDetector::detect($filePath, $readerType);
return $this->reader->toCollection($import, $filePath, $readerType, $disk);
}
/**
* {@inheritdoc}
*/
public function queueImport(ShouldQueue $import, $filePath, string $disk = null, string $readerType = null)
{
return $this->import($import, $filePath, $disk, $readerType);
}
/**
* @param object $export
* @param string|null $fileName
* @param string $writerType
*
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @return TemporaryFile
*/
protected function export($export, string $fileName, string $writerType = null): TemporaryFile
{
$writerType = FileTypeDetector::detectStrict($fileName, $writerType);
return $this->writer->export($export, $writerType);
}
}

View File

@@ -0,0 +1,117 @@
<?php
namespace Maatwebsite\Excel;
use Illuminate\Support\Collection;
use Illuminate\Support\ServiceProvider;
use Laravel\Lumen\Application as LumenApplication;
use Maatwebsite\Excel\Cache\CacheManager;
use Maatwebsite\Excel\Console\ExportMakeCommand;
use Maatwebsite\Excel\Console\ImportMakeCommand;
use Maatwebsite\Excel\Files\Filesystem;
use Maatwebsite\Excel\Files\TemporaryFileFactory;
use Maatwebsite\Excel\Mixins\DownloadCollection;
use Maatwebsite\Excel\Mixins\StoreCollection;
use Maatwebsite\Excel\Transactions\TransactionHandler;
use Maatwebsite\Excel\Transactions\TransactionManager;
class ExcelServiceProvider extends ServiceProvider
{
/**
* {@inheritdoc}
*/
public function boot()
{
if ($this->app->runningInConsole()) {
$this->publishes([
__DIR__ . '/Console/stubs/export.model.stub' => base_path('stubs/export.model.stub'),
__DIR__ . '/Console/stubs/export.plain.stub' => base_path('stubs/export.plain.stub'),
__DIR__ . '/Console/stubs/export.query.stub' => base_path('stubs/export.query.stub'),
__DIR__ . '/Console/stubs/export.query-model.stub' => base_path('stubs/export.query-model.stub'),
__DIR__ . '/Console/stubs/import.collection.stub' => base_path('stubs/import.collection.stub'),
__DIR__ . '/Console/stubs/import.model.stub' => base_path('stubs/import.model.stub'),
], 'stubs');
if ($this->app instanceof LumenApplication) {
$this->app->configure('excel');
} else {
$this->publishes([
$this->getConfigFile() => config_path('excel.php'),
], 'config');
}
}
if ($this->app instanceof \Illuminate\Foundation\Application) {
// Laravel
$this->app->booted(function ($app) {
$app->make(SettingsProvider::class)->provide();
});
} else {
// Lumen
$this->app->make(SettingsProvider::class)->provide();
}
}
/**
* {@inheritdoc}
*/
public function register()
{
$this->mergeConfigFrom(
$this->getConfigFile(),
'excel'
);
$this->app->bind(CacheManager::class, function ($app) {
return new CacheManager($app);
});
$this->app->bind(TransactionManager::class, function ($app) {
return new TransactionManager($app);
});
$this->app->bind(TransactionHandler::class, function ($app) {
return $app->make(TransactionManager::class)->driver();
});
$this->app->bind(TemporaryFileFactory::class, function () {
return new TemporaryFileFactory(
config('excel.temporary_files.local_path', config('excel.exports.temp_path', storage_path('framework/laravel-excel'))),
config('excel.temporary_files.remote_disk')
);
});
$this->app->bind(Filesystem::class, function ($app) {
return new Filesystem($app->make('filesystem'));
});
$this->app->bind('excel', function ($app) {
return new Excel(
$app->make(Writer::class),
$app->make(QueuedWriter::class),
$app->make(Reader::class),
$app->make(Filesystem::class)
);
});
$this->app->alias('excel', Excel::class);
$this->app->alias('excel', Exporter::class);
$this->app->alias('excel', Importer::class);
Collection::mixin(new DownloadCollection);
Collection::mixin(new StoreCollection);
$this->commands([
ExportMakeCommand::class,
ImportMakeCommand::class,
]);
}
/**
* @return string
*/
protected function getConfigFile(): string
{
return __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'excel.php';
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Maatwebsite\Excel\Exceptions;
use LogicException;
class ConcernConflictException extends LogicException implements LaravelExcelException
{
/**
* @return ConcernConflictException
*/
public static function queryOrCollectionAndView()
{
return new static('Cannot use FromQuery, FromArray or FromCollection and FromView on the same sheet.');
}
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Maatwebsite\Excel\Exceptions;
use Throwable;
interface LaravelExcelException extends Throwable
{
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Maatwebsite\Excel\Exceptions;
use InvalidArgumentException;
use Throwable;
class NoFilePathGivenException extends InvalidArgumentException implements LaravelExcelException
{
/**
* @param string $message
* @param int $code
* @param Throwable|null $previous
*/
public function __construct(
$message = 'A filepath needs to be passed.',
$code = 0,
Throwable $previous = null
) {
parent::__construct($message, $code, $previous);
}
/**
* @return NoFilePathGivenException
*/
public static function import()
{
return new static('A filepath or UploadedFile needs to be passed to start the import.');
}
/**
* @return NoFilePathGivenException
*/
public static function export()
{
return new static('A filepath needs to be passed in order to store the export.');
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Maatwebsite\Excel\Exceptions;
use InvalidArgumentException;
use Throwable;
class NoFilenameGivenException extends InvalidArgumentException implements LaravelExcelException
{
/**
* @param string $message
* @param int $code
* @param Throwable|null $previous
*/
public function __construct(
$message = 'A filename needs to be passed in order to download the export',
$code = 0,
Throwable $previous = null
) {
parent::__construct($message, $code, $previous);
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Maatwebsite\Excel\Exceptions;
use Exception;
use Throwable;
class NoTypeDetectedException extends Exception implements LaravelExcelException
{
/**
* @param string $message
* @param int $code
* @param Throwable|null $previous
*/
public function __construct(
$message = 'No ReaderType or WriterType could be detected. Make sure you either pass a valid extension to the filename or pass an explicit type.',
$code = 0,
Throwable $previous = null
) {
parent::__construct($message, $code, $previous);
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Maatwebsite\Excel\Exceptions;
use Exception;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Validators\Failure;
class RowSkippedException extends Exception
{
/**
* @var Failure[]
*/
private $failures;
/**
* @param Failure ...$failures
*/
public function __construct(Failure ...$failures)
{
$this->failures = $failures;
parent::__construct();
}
/**
* @return Failure[]|Collection
*/
public function failures(): Collection
{
return new Collection($this->failures);
}
/**
* @return int[]
*/
public function skippedRows(): array
{
return $this->failures()->map->row()->all();
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Maatwebsite\Excel\Exceptions;
class SheetNotFoundException extends \Exception implements LaravelExcelException
{
/**
* @param string $name
*
* @return SheetNotFoundException
*/
public static function byName(string $name): SheetNotFoundException
{
return new static("Your requested sheet name [{$name}] is out of bounds.");
}
/**
* @param int $index
* @param int $sheetCount
*
* @return SheetNotFoundException
*/
public static function byIndex(int $index, int $sheetCount): SheetNotFoundException
{
return new static("Your requested sheet index: {$index} is out of bounds. The actual number of sheets is {$sheetCount}.");
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Maatwebsite\Excel\Exceptions;
use Exception;
use Throwable;
class UnreadableFileException extends Exception implements LaravelExcelException
{
/**
* @param string $message
* @param int $code
* @param Throwable|null $previous
*/
public function __construct(
$message = 'File could not be read',
$code = 0,
Throwable $previous = null
) {
parent::__construct($message, $code, $previous);
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace Maatwebsite\Excel;
interface Exporter
{
/**
* @param object $export
* @param string|null $fileName
* @param string $writerType
* @param array $headers
*
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
*/
public function download($export, string $fileName, string $writerType = null, array $headers = []);
/**
* @param object $export
* @param string $filePath
* @param string|null $disk
* @param string $writerType
* @param mixed $diskOptions
*
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
* @return bool
*/
public function store($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = []);
/**
* @param object $export
* @param string $filePath
* @param string|null $disk
* @param string $writerType
* @param mixed $diskOptions
*
* @return \Illuminate\Foundation\Bus\PendingDispatch
*/
public function queue($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = []);
/**
* @param object $export
* @param string $writerType
*
* @return string
*/
public function raw($export, string $writerType);
}

View File

@@ -0,0 +1,50 @@
<?php
namespace Maatwebsite\Excel\Facades;
use Illuminate\Foundation\Bus\PendingDispatch;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Facade;
use Maatwebsite\Excel\Excel as BaseExcel;
use Maatwebsite\Excel\Fakes\ExcelFake;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
/**
* @method static BinaryFileResponse download(object $export, string $fileName, string $writerType = null, array $headers = [])
* @method static bool store(object $export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = [])
* @method static PendingDispatch queue(object $export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = [])
* @method static BaseExcel import(object $import, string|UploadedFile $filePath, string $disk = null, string $readerType = null)
* @method static array toArray(object $import, string|UploadedFile $filePath, string $disk = null, string $readerType = null)
* @method static Collection toCollection(object $import, string|UploadedFile $filePath, string $disk = null, string $readerType = null)
* @method static PendingDispatch queueImport(object $import, string|UploadedFile $filePath, string $disk = null, string $readerType = null)
* @method static void matchByRegex()
* @method static void doNotMatchByRegex()
* @method static void assertDownloaded(string $fileName, callable $callback = null)
* @method static void assertStored(string $filePath, string|callable $disk = null, callable $callback = null)
* @method static void assertQueued(string $filePath, string|callable $disk = null, callable $callback = null)
* @method static void assertQueuedWithChain(array $chain)
* @method static void assertImported(string $filePath, string|callable $disk = null, callable $callback = null)
*/
class Excel extends Facade
{
/**
* Replace the bound instance with a fake.
*
* @return void
*/
public static function fake()
{
static::swap(new ExcelFake());
}
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor()
{
return 'excel';
}
}

View File

@@ -0,0 +1,84 @@
<?php
namespace Maatwebsite\Excel\Factories;
use Maatwebsite\Excel\Concerns\MapsCsvSettings;
use Maatwebsite\Excel\Concerns\WithCustomCsvSettings;
use Maatwebsite\Excel\Concerns\WithLimit;
use Maatwebsite\Excel\Concerns\WithReadFilter;
use Maatwebsite\Excel\Concerns\WithStartRow;
use Maatwebsite\Excel\Exceptions\NoTypeDetectedException;
use Maatwebsite\Excel\Files\TemporaryFile;
use Maatwebsite\Excel\Filters\LimitFilter;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Reader\Csv;
use PhpOffice\PhpSpreadsheet\Reader\Exception;
use PhpOffice\PhpSpreadsheet\Reader\IReader;
class ReaderFactory
{
use MapsCsvSettings;
/**
* @param object $import
* @param TemporaryFile $file
* @param string $readerType
*
* @throws Exception
* @return IReader
*/
public static function make($import, TemporaryFile $file, string $readerType = null): IReader
{
$reader = IOFactory::createReader(
$readerType ?: static::identify($file)
);
if (method_exists($reader, 'setReadDataOnly')) {
$reader->setReadDataOnly(config('excel.imports.read_only', true));
}
if (method_exists($reader, 'setReadEmptyCells')) {
$reader->setReadEmptyCells(!config('excel.imports.ignore_empty', false));
}
if ($reader instanceof Csv) {
static::applyCsvSettings(config('excel.imports.csv', []));
if ($import instanceof WithCustomCsvSettings) {
static::applyCsvSettings($import->getCsvSettings());
}
$reader->setDelimiter(static::$delimiter);
$reader->setEnclosure(static::$enclosure);
$reader->setEscapeCharacter(static::$escapeCharacter);
$reader->setContiguous(static::$contiguous);
$reader->setInputEncoding(static::$inputEncoding);
}
if ($import instanceof WithReadFilter) {
$reader->setReadFilter($import->readFilter());
} elseif ($import instanceof WithLimit) {
$reader->setReadFilter(new LimitFilter(
$import instanceof WithStartRow ? $import->startRow() : 1,
$import->limit()
));
}
return $reader;
}
/**
* @param TemporaryFile $temporaryFile
*
* @throws NoTypeDetectedException
* @return string
*/
private static function identify(TemporaryFile $temporaryFile): string
{
try {
return IOFactory::identify($temporaryFile->getLocalPath());
} catch (Exception $e) {
throw new NoTypeDetectedException(null, null, $e);
}
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace Maatwebsite\Excel\Factories;
use Maatwebsite\Excel\Cache\CacheManager;
use Maatwebsite\Excel\Concerns\MapsCsvSettings;
use Maatwebsite\Excel\Concerns\WithCharts;
use Maatwebsite\Excel\Concerns\WithCustomCsvSettings;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
use Maatwebsite\Excel\Concerns\WithPreCalculateFormulas;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Csv;
use PhpOffice\PhpSpreadsheet\Writer\Html;
use PhpOffice\PhpSpreadsheet\Writer\IWriter;
class WriterFactory
{
use MapsCsvSettings;
/**
* @param string $writerType
* @param Spreadsheet $spreadsheet
* @param object $export
*
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
* @return IWriter
*/
public static function make(string $writerType, Spreadsheet $spreadsheet, $export): IWriter
{
$writer = IOFactory::createWriter($spreadsheet, $writerType);
$writer->setUseDiskCaching(
config('excel.cache.driver', CacheManager::DRIVER_MEMORY) !== CacheManager::DRIVER_MEMORY
);
if (static::includesCharts($export)) {
$writer->setIncludeCharts(true);
}
if ($writer instanceof Html && $export instanceof WithMultipleSheets) {
$writer->writeAllSheets();
}
if ($writer instanceof Csv) {
static::applyCsvSettings(config('excel.exports.csv', []));
if ($export instanceof WithCustomCsvSettings) {
static::applyCsvSettings($export->getCsvSettings());
}
$writer->setDelimiter(static::$delimiter);
$writer->setEnclosure(static::$enclosure);
$writer->setEnclosureRequired((bool) static::$enclosure);
$writer->setLineEnding(static::$lineEnding);
$writer->setUseBOM(static::$useBom);
$writer->setIncludeSeparatorLine(static::$includeSeparatorLine);
$writer->setExcelCompatibility(static::$excelCompatibility);
}
// Calculation settings
$writer->setPreCalculateFormulas(
$export instanceof WithPreCalculateFormulas
? true
: config('excel.exports.pre_calculate_formulas', false)
);
return $writer;
}
/**
* @param $export
*
* @return bool
*/
private static function includesCharts($export): bool
{
if ($export instanceof WithCharts) {
return true;
}
if ($export instanceof WithMultipleSheets) {
foreach ($export->sheets() as $sheet) {
if ($sheet instanceof WithCharts) {
return true;
}
}
}
return false;
}
}

View File

@@ -0,0 +1,358 @@
<?php
namespace Maatwebsite\Excel\Fakes;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\PendingDispatch;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Queue;
use Maatwebsite\Excel\Exporter;
use Maatwebsite\Excel\Importer;
use Maatwebsite\Excel\Reader;
use PHPUnit\Framework\Assert;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class ExcelFake implements Exporter, Importer
{
/**
* @var array
*/
protected $downloads = [];
/**
* @var array
*/
protected $stored = [];
/**
* @var array
*/
protected $queued = [];
/**
* @var array
*/
protected $imported = [];
/**
* @var bool
*/
protected $matchByRegex = false;
/**
* @var object|null
*/
protected $job;
/**
* {@inheritdoc}
*/
public function download($export, string $fileName, string $writerType = null, array $headers = [])
{
$this->downloads[$fileName] = $export;
return new BinaryFileResponse(__DIR__ . '/fake_file');
}
/**
* {@inheritdoc}
*/
public function store($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = [])
{
if ($export instanceof ShouldQueue) {
return $this->queue($export, $filePath, $disk, $writerType);
}
$this->stored[$disk ?? 'default'][$filePath] = $export;
return true;
}
/**
* {@inheritdoc}
*/
public function queue($export, string $filePath, string $disk = null, string $writerType = null, $diskOptions = [])
{
Queue::fake();
$this->stored[$disk ?? 'default'][$filePath] = $export;
$this->queued[$disk ?? 'default'][$filePath] = $export;
$this->job = new class
{
use Queueable;
public function handle()
{
//
}
};
Queue::push($this->job);
return new PendingDispatch($this->job);
}
/**
* @param object $export
* @param string $writerType
*
* @return string
*/
public function raw($export, string $writerType)
{
return 'RAW-CONTENTS';
}
/**
* @param object $import
* @param string|UploadedFile $file
* @param string|null $disk
* @param string|null $readerType
*
* @return Reader|PendingDispatch
*/
public function import($import, $file, string $disk = null, string $readerType = null)
{
if ($import instanceof ShouldQueue) {
return $this->queueImport($import, $file, $disk, $readerType);
}
$filePath = ($file instanceof UploadedFile) ? $file->getClientOriginalName() : $file;
$this->imported[$disk ?? 'default'][$filePath] = $import;
return $this;
}
/**
* @param object $import
* @param string|UploadedFile $file
* @param string|null $disk
* @param string|null $readerType
*
* @return array
*/
public function toArray($import, $file, string $disk = null, string $readerType = null): array
{
$filePath = ($file instanceof UploadedFile) ? $file->getFilename() : $file;
$this->imported[$disk ?? 'default'][$filePath] = $import;
return [];
}
/**
* @param object $import
* @param string|UploadedFile $file
* @param string|null $disk
* @param string|null $readerType
*
* @return Collection
*/
public function toCollection($import, $file, string $disk = null, string $readerType = null): Collection
{
$filePath = ($file instanceof UploadedFile) ? $file->getFilename() : $file;
$this->imported[$disk ?? 'default'][$filePath] = $import;
return new Collection();
}
/**
* @param ShouldQueue $import
* @param string|UploadedFile $file
* @param string|null $disk
* @param string $readerType
*
* @return PendingDispatch
*/
public function queueImport(ShouldQueue $import, $file, string $disk = null, string $readerType = null)
{
Queue::fake();
$filePath = ($file instanceof UploadedFile) ? $file->getFilename() : $file;
$this->queued[$disk ?? 'default'][$filePath] = $import;
$this->imported[$disk ?? 'default'][$filePath] = $import;
return new PendingDispatch(new class
{
use Queueable;
public function handle()
{
//
}
});
}
/**
* When asserting downloaded, stored, queued or imported, use regular expression
* to look for a matching file path.
*
* @return void
*/
public function matchByRegex()
{
$this->matchByRegex = true;
}
/**
* When asserting downloaded, stored, queued or imported, use regular string
* comparison for matching file path.
*
* @return void
*/
public function doNotMatchByRegex()
{
$this->matchByRegex = false;
}
/**
* @param string $fileName
* @param callable|null $callback
*/
public function assertDownloaded(string $fileName, $callback = null)
{
$fileName = $this->assertArrayHasKey($fileName, $this->downloads, sprintf('%s is not downloaded', $fileName));
$callback = $callback ?: function () {
return true;
};
Assert::assertTrue(
$callback($this->downloads[$fileName]),
"The file [{$fileName}] was not downloaded with the expected data."
);
}
/**
* @param string $filePath
* @param string|callable|null $disk
* @param callable|null $callback
*/
public function assertStored(string $filePath, $disk = null, $callback = null)
{
if (is_callable($disk)) {
$callback = $disk;
$disk = null;
}
$disk = $disk ?? 'default';
$storedOnDisk = $this->stored[$disk] ?? [];
$filePath = $this->assertArrayHasKey(
$filePath,
$storedOnDisk,
sprintf('%s is not stored on disk %s', $filePath, $disk)
);
$callback = $callback ?: function () {
return true;
};
Assert::assertTrue(
$callback($storedOnDisk[$filePath]),
"The file [{$filePath}] was not stored with the expected data."
);
}
/**
* @param string $filePath
* @param string|callable|null $disk
* @param callable|null $callback
*/
public function assertQueued(string $filePath, $disk = null, $callback = null)
{
if (is_callable($disk)) {
$callback = $disk;
$disk = null;
}
$disk = $disk ?? 'default';
$queuedForDisk = $this->queued[$disk] ?? [];
$filePath = $this->assertArrayHasKey(
$filePath,
$queuedForDisk,
sprintf('%s is not queued for export on disk %s', $filePath, $disk)
);
$callback = $callback ?: function () {
return true;
};
Assert::assertTrue(
$callback($queuedForDisk[$filePath]),
"The file [{$filePath}] was not stored with the expected data."
);
}
public function assertQueuedWithChain($chain): void
{
Queue::assertPushedWithChain(get_class($this->job), $chain);
}
/**
* @param string $filePath
* @param string|callable|null $disk
* @param callable|null $callback
*/
public function assertImported(string $filePath, $disk = null, $callback = null)
{
if (is_callable($disk)) {
$callback = $disk;
$disk = null;
}
$disk = $disk ?? 'default';
$importedOnDisk = $this->imported[$disk] ?? [];
$filePath = $this->assertArrayHasKey(
$filePath,
$importedOnDisk,
sprintf('%s is not stored on disk %s', $filePath, $disk)
);
$callback = $callback ?: function () {
return true;
};
Assert::assertTrue(
$callback($importedOnDisk[$filePath]),
"The file [{$filePath}] was not imported with the expected data."
);
}
/**
* Asserts that an array has a specified key and returns the key if successful.
* @see matchByRegex for more information about file path matching
*
* @param string $key
* @param array $array
* @param string $message
*
* @return string
*
* @throws ExpectationFailedException
* @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
* @throws Exception
*/
protected function assertArrayHasKey(string $key, array $disk, string $message = ''): string
{
if ($this->matchByRegex) {
$files = array_keys($disk);
$results = preg_grep($key, $files);
Assert::assertGreaterThan(0, count($results), $message);
Assert::assertEquals(1, count($results), "More than one result matches the file name expression '$key'.");
return $results[0];
}
Assert::assertArrayHasKey($key, $disk, $message);
return $key;
}
}

View File

View File

@@ -0,0 +1,99 @@
<?php
namespace Maatwebsite\Excel\Files;
use Illuminate\Contracts\Filesystem\Filesystem as IlluminateFilesystem;
/**
* @method bool get(string $filename)
* @method resource readStream(string $filename)
* @method bool delete(string $filename)
* @method bool exists(string $filename)
*/
class Disk
{
/**
* @var IlluminateFilesystem
*/
protected $disk;
/**
* @var string|null
*/
protected $name;
/**
* @var array
*/
protected $diskOptions;
/**
* @param IlluminateFilesystem $disk
* @param string|null $name
* @param array $diskOptions
*/
public function __construct(IlluminateFilesystem $disk, string $name = null, array $diskOptions = [])
{
$this->disk = $disk;
$this->name = $name;
$this->diskOptions = $diskOptions;
}
/**
* @param string $name
* @param array $arguments
*
* @return mixed
*/
public function __call($name, $arguments)
{
return $this->disk->{$name}(...$arguments);
}
/**
* @param string $destination
* @param string|resource $contents
*
* @return bool
*/
public function put(string $destination, $contents): bool
{
return $this->disk->put($destination, $contents, $this->diskOptions);
}
/**
* @param TemporaryFile $source
* @param string $destination
*
* @return bool
*/
public function copy(TemporaryFile $source, string $destination): bool
{
$readStream = $source->readStream();
if (realpath($destination)) {
$tempStream = fopen($destination, 'rb+');
$success = stream_copy_to_stream($readStream, $tempStream) !== false;
if (is_resource($tempStream)) {
fclose($tempStream);
}
} else {
$success = $this->put($destination, $readStream);
}
if (is_resource($readStream)) {
fclose($readStream);
}
return $success;
}
/**
* @param string $filename
*/
public function touch(string $filename)
{
$this->disk->put($filename, '', $this->diskOptions);
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Maatwebsite\Excel\Files;
use Illuminate\Contracts\Filesystem\Factory;
class Filesystem
{
/**
* @var Factory
*/
private $filesystem;
/**
* @param Factory $filesystem
*/
public function __construct(Factory $filesystem)
{
$this->filesystem = $filesystem;
}
/**
* @param string|null $disk
* @param array $diskOptions
*
* @return Disk
*/
public function disk(string $disk = null, array $diskOptions = []): Disk
{
return new Disk(
$this->filesystem->disk($disk),
$disk,
$diskOptions
);
}
}

Some files were not shown because too many files have changed in this diff Show More