new appraoch
This commit is contained in:
20
pancake/system/vendor/league/csv/LICENSE
vendored
Executable file
20
pancake/system/vendor/league/csv/LICENSE
vendored
Executable file
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2017 ignace nyamagana butera
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
18
pancake/system/vendor/league/csv/autoload.php
vendored
Executable file
18
pancake/system/vendor/league/csv/autoload.php
vendored
Executable file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
require __DIR__.'/src/functions_include.php';
|
||||
|
||||
spl_autoload_register(function ($class) {
|
||||
|
||||
$prefix = 'League\Csv\\';
|
||||
if (0 !== strpos($class, $prefix)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$file = __DIR__.'/src/'.str_replace('\\', '/', substr($class, strlen($prefix))).'.php';
|
||||
if (!is_readable($file)) {
|
||||
return;
|
||||
}
|
||||
|
||||
require $file;
|
||||
});
|
||||
82
pancake/system/vendor/league/csv/composer.json
vendored
Executable file
82
pancake/system/vendor/league/csv/composer.json
vendored
Executable file
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"name": "league/csv",
|
||||
"type": "library",
|
||||
"description" : "CSV data manipulation made easy in PHP",
|
||||
"keywords": ["csv", "import", "export", "read", "write", "filter", "convert", "transform"],
|
||||
"license": "MIT",
|
||||
"homepage" : "https://csv.thephpleague.com",
|
||||
"authors": [
|
||||
{
|
||||
"name" : "Ignace Nyamagana Butera",
|
||||
"email" : "nyamsprod@gmail.com",
|
||||
"homepage" : "https://github.com/nyamsprod/",
|
||||
"role" : "Developer"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://csv.thephpleague.com",
|
||||
"issues": "https://github.com/thephpleague/csv/issues",
|
||||
"rss": "https://github.com/thephpleague/csv/releases.atom",
|
||||
"source": "https://github.com/thephpleague/csv"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/nyamsprod"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php" : "^7.4 || ^8.0",
|
||||
"ext-json" : "*",
|
||||
"ext-mbstring" : "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-curl" : "*",
|
||||
"ext-dom": "*",
|
||||
"friendsofphp/php-cs-fixer": "^v3.4.0",
|
||||
"phpunit/phpunit" : "^9.5.11",
|
||||
"phpstan/phpstan": "^1.3.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.1.0",
|
||||
"phpstan/phpstan-phpunit": "^1.0.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Csv\\": "src"
|
||||
},
|
||||
"files": ["src/functions_include.php"]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"LeagueTest\\Csv\\": "tests"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"phpcs": "php-cs-fixer fix -vvv --diff --dry-run --allow-risky=yes --ansi",
|
||||
"phpcs:fix": "php-cs-fixer fix -vvv --allow-risky=yes --ansi",
|
||||
"phpstan": "phpstan analyse -l max -c phpstan.neon src --ansi --memory-limit=192M",
|
||||
"phpunit": "phpunit --coverage-text",
|
||||
"test": [
|
||||
"@phpunit",
|
||||
"@phpstan",
|
||||
"@phpcs"
|
||||
]
|
||||
},
|
||||
"scripts-descriptions": {
|
||||
"phpcs": "Runs coding style test suite",
|
||||
"phpstan": "Runs complete codebase static analysis",
|
||||
"phpunit": "Runs unit and functional testing",
|
||||
"test": "Runs full test suite"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-iconv" : "Needed to ease transcoding CSV using iconv stream filters",
|
||||
"ext-dom" : "Required to use the XMLConverter and or the HTMLConverter classes"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "9.x-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
492
pancake/system/vendor/league/csv/src/AbstractCsv.php
vendored
Executable file
492
pancake/system/vendor/league/csv/src/AbstractCsv.php
vendored
Executable file
@@ -0,0 +1,492 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use Generator;
|
||||
use SplFileObject;
|
||||
use function filter_var;
|
||||
use function get_class;
|
||||
use function mb_strlen;
|
||||
use function rawurlencode;
|
||||
use function sprintf;
|
||||
use function str_replace;
|
||||
use function str_split;
|
||||
use function strcspn;
|
||||
use function strlen;
|
||||
use const FILTER_FLAG_STRIP_HIGH;
|
||||
use const FILTER_FLAG_STRIP_LOW;
|
||||
use const FILTER_UNSAFE_RAW;
|
||||
|
||||
/**
|
||||
* An abstract class to enable CSV document loading.
|
||||
*/
|
||||
abstract class AbstractCsv implements ByteSequence
|
||||
{
|
||||
protected const STREAM_FILTER_MODE = STREAM_FILTER_READ;
|
||||
|
||||
/** @var SplFileObject|Stream The CSV document. */
|
||||
protected $document;
|
||||
/** @var array<string, bool> collection of stream filters. */
|
||||
protected array $stream_filters = [];
|
||||
protected ?string $input_bom = null;
|
||||
protected string $output_bom = '';
|
||||
protected string $delimiter = ',';
|
||||
protected string $enclosure = '"';
|
||||
protected string $escape = '\\';
|
||||
protected bool $is_input_bom_included = false;
|
||||
|
||||
/**
|
||||
* @final This method should not be overwritten in child classes
|
||||
*
|
||||
* @param SplFileObject|Stream $document The CSV Object instance
|
||||
*/
|
||||
protected function __construct($document)
|
||||
{
|
||||
$this->document = $document;
|
||||
[$this->delimiter, $this->enclosure, $this->escape] = $this->document->getCsvControl();
|
||||
$this->resetProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset dynamic object properties to improve performance.
|
||||
*/
|
||||
abstract protected function resetProperties(): void;
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
unset($this->document);
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
throw UnavailableStream::dueToForbiddenCloning(static::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new instance from a SplFileObject.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function createFromFileObject(SplFileObject $file)
|
||||
{
|
||||
return new static($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new instance from a PHP resource stream.
|
||||
*
|
||||
* @param resource $stream
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function createFromStream($stream)
|
||||
{
|
||||
return new static(new Stream($stream));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new instance from a string.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function createFromString(string $content = '')
|
||||
{
|
||||
return new static(Stream::createFromString($content));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new instance from a file path.
|
||||
*
|
||||
* @param resource|null $context the resource context
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function createFromPath(string $path, string $open_mode = 'r+', $context = null)
|
||||
{
|
||||
return new static(Stream::createFromPath($path, $open_mode, $context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current field delimiter.
|
||||
*/
|
||||
public function getDelimiter(): string
|
||||
{
|
||||
return $this->delimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current field enclosure.
|
||||
*/
|
||||
public function getEnclosure(): string
|
||||
{
|
||||
return $this->enclosure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pathname of the underlying document.
|
||||
*/
|
||||
public function getPathname(): string
|
||||
{
|
||||
return $this->document->getPathname();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current field escape character.
|
||||
*/
|
||||
public function getEscape(): string
|
||||
{
|
||||
return $this->escape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the BOM sequence in use on Output methods.
|
||||
*/
|
||||
public function getOutputBOM(): string
|
||||
{
|
||||
return $this->output_bom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the BOM sequence of the given CSV.
|
||||
*/
|
||||
public function getInputBOM(): string
|
||||
{
|
||||
if (null !== $this->input_bom) {
|
||||
return $this->input_bom;
|
||||
}
|
||||
|
||||
$this->document->setFlags(SplFileObject::READ_CSV);
|
||||
$this->document->rewind();
|
||||
$this->input_bom = Info::fetchBOMSequence((string) $this->document->fread(4)) ?? '';
|
||||
|
||||
return $this->input_bom;
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATION WARNING! This method will be removed in the next major point release.
|
||||
*
|
||||
* @deprecated since version 9.7.0
|
||||
* @see AbstractCsv::supportsStreamFilterOnRead
|
||||
* @see AbstractCsv::supportsStreamFilterOnWrite
|
||||
*
|
||||
* Returns the stream filter mode.
|
||||
*/
|
||||
public function getStreamFilterMode(): int
|
||||
{
|
||||
return static::STREAM_FILTER_MODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATION WARNING! This method will be removed in the next major point release.
|
||||
*
|
||||
* @deprecated since version 9.7.0
|
||||
* @see AbstractCsv::supportsStreamFilterOnRead
|
||||
* @see AbstractCsv::supportsStreamFilterOnWrite
|
||||
*
|
||||
* Tells whether the stream filter capabilities can be used.
|
||||
*/
|
||||
public function supportsStreamFilter(): bool
|
||||
{
|
||||
return $this->document instanceof Stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether the stream filter read capabilities can be used.
|
||||
*/
|
||||
public function supportsStreamFilterOnRead(): bool
|
||||
{
|
||||
return $this->document instanceof Stream
|
||||
&& (static::STREAM_FILTER_MODE & STREAM_FILTER_READ) === STREAM_FILTER_READ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether the stream filter write capabilities can be used.
|
||||
*/
|
||||
public function supportsStreamFilterOnWrite(): bool
|
||||
{
|
||||
return $this->document instanceof Stream
|
||||
&& (static::STREAM_FILTER_MODE & STREAM_FILTER_WRITE) === STREAM_FILTER_WRITE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether the specify stream filter is attach to the current stream.
|
||||
*/
|
||||
public function hasStreamFilter(string $filtername): bool
|
||||
{
|
||||
return $this->stream_filters[$filtername] ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether the BOM can be stripped if presents.
|
||||
*/
|
||||
public function isInputBOMIncluded(): bool
|
||||
{
|
||||
return $this->is_input_bom_included;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CSV document as a Generator of string chunk.
|
||||
*
|
||||
* @param int $length number of bytes read
|
||||
*
|
||||
* @throws Exception if the number of bytes is lesser than 1
|
||||
*/
|
||||
public function chunk(int $length): Generator
|
||||
{
|
||||
if ($length < 1) {
|
||||
throw InvalidArgument::dueToInvalidChunkSize($length, __METHOD__);
|
||||
}
|
||||
|
||||
$input_bom = $this->getInputBOM();
|
||||
$this->document->rewind();
|
||||
$this->document->setFlags(0);
|
||||
$this->document->fseek(strlen($input_bom));
|
||||
/** @var array<int, string> $chunks */
|
||||
$chunks = str_split($this->output_bom.$this->document->fread($length), $length);
|
||||
foreach ($chunks as $chunk) {
|
||||
yield $chunk;
|
||||
}
|
||||
|
||||
while ($this->document->valid()) {
|
||||
yield $this->document->fread($length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATION WARNING! This method will be removed in the next major point release.
|
||||
*
|
||||
* @deprecated since version 9.1.0
|
||||
* @see AbstractCsv::toString
|
||||
*
|
||||
* Retrieves the CSV content
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the CSV content.
|
||||
*
|
||||
* DEPRECATION WARNING! This method will be removed in the next major point release
|
||||
*
|
||||
* @deprecated since version 9.7.0
|
||||
* @see AbstractCsv::toString
|
||||
*/
|
||||
public function getContent(): string
|
||||
{
|
||||
return $this->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the CSV content.
|
||||
*
|
||||
* @throws Exception If the string representation can not be returned
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
$raw = '';
|
||||
foreach ($this->chunk(8192) as $chunk) {
|
||||
$raw .= $chunk;
|
||||
}
|
||||
|
||||
return $raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs all data on the CSV file.
|
||||
*
|
||||
* @return int Returns the number of characters read from the handle
|
||||
* and passed through to the output.
|
||||
*/
|
||||
public function output(string $filename = null): int
|
||||
{
|
||||
if (null !== $filename) {
|
||||
$this->sendHeaders($filename);
|
||||
}
|
||||
|
||||
$this->document->rewind();
|
||||
if (!$this->is_input_bom_included) {
|
||||
$this->document->fseek(strlen($this->getInputBOM()));
|
||||
}
|
||||
|
||||
echo $this->output_bom;
|
||||
|
||||
return strlen($this->output_bom) + (int) $this->document->fpassthru();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the CSV headers.
|
||||
*
|
||||
* Adapted from Symfony\Component\HttpFoundation\ResponseHeaderBag::makeDisposition
|
||||
*
|
||||
* @throws Exception if the submitted header is invalid according to RFC 6266
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc6266#section-4.3
|
||||
*/
|
||||
protected function sendHeaders(string $filename): void
|
||||
{
|
||||
if (strlen($filename) != strcspn($filename, '\\/')) {
|
||||
throw InvalidArgument::dueToInvalidHeaderFilename($filename);
|
||||
}
|
||||
|
||||
$flag = FILTER_FLAG_STRIP_LOW;
|
||||
if (strlen($filename) !== mb_strlen($filename)) {
|
||||
$flag |= FILTER_FLAG_STRIP_HIGH;
|
||||
}
|
||||
|
||||
/** @var string $filtered_name */
|
||||
$filtered_name = filter_var($filename, FILTER_UNSAFE_RAW, $flag);
|
||||
$filename_fallback = str_replace('%', '', $filtered_name);
|
||||
|
||||
$disposition = sprintf('attachment; filename="%s"', str_replace('"', '\\"', $filename_fallback));
|
||||
if ($filename !== $filename_fallback) {
|
||||
$disposition .= sprintf("; filename*=utf-8''%s", rawurlencode($filename));
|
||||
}
|
||||
|
||||
header('Content-Type: text/csv');
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-Disposition: '.$disposition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the field delimiter.
|
||||
*
|
||||
* @throws InvalidArgument If the Csv control character is not one character only.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function setDelimiter(string $delimiter): self
|
||||
{
|
||||
if ($delimiter === $this->delimiter) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (1 !== strlen($delimiter)) {
|
||||
throw InvalidArgument::dueToInvalidDelimiterCharacter($delimiter, __METHOD__);
|
||||
}
|
||||
|
||||
$this->delimiter = $delimiter;
|
||||
$this->resetProperties();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the field enclosure.
|
||||
*
|
||||
* @throws InvalidArgument If the Csv control character is not one character only.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function setEnclosure(string $enclosure): self
|
||||
{
|
||||
if ($enclosure === $this->enclosure) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (1 !== strlen($enclosure)) {
|
||||
throw InvalidArgument::dueToInvalidEnclosureCharacter($enclosure, __METHOD__);
|
||||
}
|
||||
|
||||
$this->enclosure = $enclosure;
|
||||
$this->resetProperties();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the field escape character.
|
||||
*
|
||||
* @throws InvalidArgument If the Csv control character is not one character only.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function setEscape(string $escape): self
|
||||
{
|
||||
if ($escape === $this->escape) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ('' !== $escape && 1 !== strlen($escape)) {
|
||||
throw InvalidArgument::dueToInvalidEscapeCharacter($escape, __METHOD__);
|
||||
}
|
||||
|
||||
$this->escape = $escape;
|
||||
$this->resetProperties();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables BOM Stripping.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function skipInputBOM(): self
|
||||
{
|
||||
$this->is_input_bom_included = false;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables skipping Input BOM.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function includeInputBOM(): self
|
||||
{
|
||||
$this->is_input_bom_included = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the BOM sequence to prepend the CSV on output.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function setOutputBOM(string $str): self
|
||||
{
|
||||
$this->output_bom = $str;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* append a stream filter.
|
||||
*
|
||||
* @param null|array $params
|
||||
*
|
||||
* @throws InvalidArgument If the stream filter API can not be appended
|
||||
* @throws UnavailableFeature If the stream filter API can not be used
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function addStreamFilter(string $filtername, $params = null): self
|
||||
{
|
||||
if (!$this->document instanceof Stream) {
|
||||
throw UnavailableFeature::dueToUnsupportedStreamFilterApi(get_class($this->document));
|
||||
}
|
||||
|
||||
$this->document->appendFilter($filtername, static::STREAM_FILTER_MODE, $params);
|
||||
$this->stream_filters[$filtername] = true;
|
||||
$this->resetProperties();
|
||||
$this->input_bom = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
24
pancake/system/vendor/league/csv/src/ByteSequence.php
vendored
Executable file
24
pancake/system/vendor/league/csv/src/ByteSequence.php
vendored
Executable file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
/**
|
||||
* Defines constants for common BOM sequences.
|
||||
*/
|
||||
interface ByteSequence
|
||||
{
|
||||
const BOM_UTF8 = "\xEF\xBB\xBF";
|
||||
const BOM_UTF16_BE = "\xFE\xFF";
|
||||
const BOM_UTF16_LE = "\xFF\xFE";
|
||||
const BOM_UTF32_BE = "\x00\x00\xFE\xFF";
|
||||
const BOM_UTF32_LE = "\xFF\xFE\x00\x00";
|
||||
}
|
||||
66
pancake/system/vendor/league/csv/src/CannotInsertRecord.php
vendored
Executable file
66
pancake/system/vendor/league/csv/src/CannotInsertRecord.php
vendored
Executable file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
/**
|
||||
* Thrown when a data is not added to the Csv Document.
|
||||
*/
|
||||
class CannotInsertRecord extends Exception
|
||||
{
|
||||
/** The record submitted for insertion. */
|
||||
protected array $record;
|
||||
/** Validator which did not validated the data. */
|
||||
protected string $name = '';
|
||||
|
||||
/**
|
||||
* Create an Exception from a record insertion into a stream.
|
||||
*/
|
||||
public static function triggerOnInsertion(array $record): self
|
||||
{
|
||||
$exception = new self('Unable to write record to the CSV document');
|
||||
$exception->record = $record;
|
||||
|
||||
return $exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an Exception from a Record Validation.
|
||||
*/
|
||||
public static function triggerOnValidation(string $name, array $record): self
|
||||
{
|
||||
$exception = new self('Record validation failed');
|
||||
$exception->name = $name;
|
||||
$exception->record = $record;
|
||||
|
||||
return $exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the validator name.
|
||||
*
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the invalid data submitted.
|
||||
*
|
||||
*/
|
||||
public function getRecord(): array
|
||||
{
|
||||
return $this->record;
|
||||
}
|
||||
}
|
||||
220
pancake/system/vendor/league/csv/src/CharsetConverter.php
vendored
Executable file
220
pancake/system/vendor/league/csv/src/CharsetConverter.php
vendored
Executable file
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use OutOfRangeException;
|
||||
use php_user_filter;
|
||||
use Traversable;
|
||||
use function array_combine;
|
||||
use function array_map;
|
||||
use function in_array;
|
||||
use function is_numeric;
|
||||
use function mb_convert_encoding;
|
||||
use function mb_list_encodings;
|
||||
use function preg_match;
|
||||
use function sprintf;
|
||||
use function stream_bucket_append;
|
||||
use function stream_bucket_make_writeable;
|
||||
use function stream_filter_register;
|
||||
use function stream_get_filters;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
|
||||
/**
|
||||
* Converts resource stream or tabular data content charset.
|
||||
*/
|
||||
class CharsetConverter extends php_user_filter
|
||||
{
|
||||
const FILTERNAME = 'convert.league.csv';
|
||||
|
||||
protected string $input_encoding = 'UTF-8';
|
||||
protected string $output_encoding = 'UTF-8';
|
||||
|
||||
/**
|
||||
* Static method to add the stream filter to a {@link AbstractCsv} object.
|
||||
*/
|
||||
public static function addTo(AbstractCsv $csv, string $input_encoding, string $output_encoding): AbstractCsv
|
||||
{
|
||||
self::register();
|
||||
|
||||
return $csv->addStreamFilter(self::getFiltername($input_encoding, $output_encoding));
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method to register the class as a stream filter.
|
||||
*/
|
||||
public static function register(): void
|
||||
{
|
||||
$filter_name = self::FILTERNAME.'.*';
|
||||
if (!in_array($filter_name, stream_get_filters(), true)) {
|
||||
stream_filter_register($filter_name, self::class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method to return the stream filter filtername.
|
||||
*/
|
||||
public static function getFiltername(string $input_encoding, string $output_encoding): string
|
||||
{
|
||||
return sprintf(
|
||||
'%s.%s/%s',
|
||||
self::FILTERNAME,
|
||||
self::filterEncoding($input_encoding),
|
||||
self::filterEncoding($output_encoding)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter encoding charset.
|
||||
*
|
||||
* @throws OutOfRangeException if the charset is malformed or unsupported
|
||||
*/
|
||||
protected static function filterEncoding(string $encoding): string
|
||||
{
|
||||
static $encoding_list;
|
||||
if (null === $encoding_list) {
|
||||
$list = mb_list_encodings();
|
||||
$encoding_list = array_combine(array_map('strtolower', $list), $list);
|
||||
}
|
||||
|
||||
$key = strtolower($encoding);
|
||||
if (isset($encoding_list[$key])) {
|
||||
return $encoding_list[$key];
|
||||
}
|
||||
|
||||
throw new OutOfRangeException('The submitted charset '.$encoding.' is not supported by the mbstring extension.');
|
||||
}
|
||||
|
||||
public function onCreate(): bool
|
||||
{
|
||||
$prefix = self::FILTERNAME.'.';
|
||||
if (0 !== strpos($this->filtername, $prefix)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$encodings = substr($this->filtername, strlen($prefix));
|
||||
if (1 !== preg_match(',^(?<input>[-\w]+)\/(?<output>[-\w]+)$,', $encodings, $matches)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->input_encoding = self::filterEncoding($matches['input']);
|
||||
$this->output_encoding = self::filterEncoding($matches['output']);
|
||||
} catch (OutOfRangeException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $in
|
||||
* @param resource $out
|
||||
* @param int $consumed
|
||||
* @param bool $closing
|
||||
*/
|
||||
public function filter($in, $out, &$consumed, $closing): int
|
||||
{
|
||||
while (null !== ($bucket = stream_bucket_make_writeable($in))) {
|
||||
$bucket->data = @mb_convert_encoding($bucket->data, $this->output_encoding, $this->input_encoding);
|
||||
$consumed += $bucket->datalen;
|
||||
stream_bucket_append($out, $bucket);
|
||||
}
|
||||
|
||||
return PSFS_PASS_ON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Csv records collection into UTF-8.
|
||||
*/
|
||||
public function convert(iterable $records): iterable
|
||||
{
|
||||
if ($this->output_encoding === $this->input_encoding) {
|
||||
return $records;
|
||||
}
|
||||
|
||||
if (is_array($records)) {
|
||||
return array_map($this, $records);
|
||||
}
|
||||
|
||||
/* @var Traversable $records */
|
||||
return new MapIterator($records, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable using the class as a formatter for the {@link Writer}.
|
||||
*/
|
||||
public function __invoke(array $record): array
|
||||
{
|
||||
$outputRecord = [];
|
||||
foreach ($record as $offset => $value) {
|
||||
[$newOffset, $newValue] = $this->encodeField($value, $offset);
|
||||
$outputRecord[$newOffset] = $newValue;
|
||||
}
|
||||
|
||||
return $outputRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Walker method to convert the offset and the value of a CSV record field.
|
||||
*
|
||||
* @param int|float|string|null $value can be a scalar type or null
|
||||
* @param int|string $offset can be a string or an int
|
||||
*/
|
||||
protected function encodeField($value, $offset): array
|
||||
{
|
||||
if (null !== $value && !is_numeric($value)) {
|
||||
$value = mb_convert_encoding($value, $this->output_encoding, $this->input_encoding);
|
||||
}
|
||||
|
||||
if (!is_numeric($offset)) {
|
||||
$offset = mb_convert_encoding($offset, $this->output_encoding, $this->input_encoding);
|
||||
}
|
||||
|
||||
return [$offset, $value];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the records input encoding charset.
|
||||
*/
|
||||
public function inputEncoding(string $encoding): self
|
||||
{
|
||||
$encoding = self::filterEncoding($encoding);
|
||||
if ($encoding === $this->input_encoding) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$clone = clone $this;
|
||||
$clone->input_encoding = $encoding;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the records output encoding charset.
|
||||
*/
|
||||
public function outputEncoding(string $encoding): self
|
||||
{
|
||||
$encoding = self::filterEncoding($encoding);
|
||||
if ($encoding === $this->output_encoding) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$clone = clone $this;
|
||||
$clone->output_encoding = $encoding;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
}
|
||||
59
pancake/system/vendor/league/csv/src/ColumnConsistency.php
vendored
Executable file
59
pancake/system/vendor/league/csv/src/ColumnConsistency.php
vendored
Executable file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use function count;
|
||||
|
||||
/**
|
||||
* Validates column consistency when inserting records into a CSV document.
|
||||
*/
|
||||
class ColumnConsistency
|
||||
{
|
||||
protected int $columns_count;
|
||||
|
||||
/**
|
||||
* @throws InvalidArgument if the column count is lesser than -1
|
||||
*/
|
||||
public function __construct(int $columns_count = -1)
|
||||
{
|
||||
if ($columns_count < -1) {
|
||||
throw InvalidArgument::dueToInvalidColumnCount($columns_count, __METHOD__);
|
||||
}
|
||||
|
||||
$this->columns_count = $columns_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the column count.
|
||||
*/
|
||||
public function getColumnCount(): int
|
||||
{
|
||||
return $this->columns_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether the submitted record is valid.
|
||||
*/
|
||||
public function __invoke(array $record): bool
|
||||
{
|
||||
$count = count($record);
|
||||
if (-1 === $this->columns_count) {
|
||||
$this->columns_count = $count;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return $count === $this->columns_count;
|
||||
}
|
||||
}
|
||||
112
pancake/system/vendor/league/csv/src/EncloseField.php
vendored
Executable file
112
pancake/system/vendor/league/csv/src/EncloseField.php
vendored
Executable file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use php_user_filter;
|
||||
use function array_map;
|
||||
use function in_array;
|
||||
use function str_replace;
|
||||
use function strcspn;
|
||||
use function stream_bucket_append;
|
||||
use function stream_bucket_make_writeable;
|
||||
use function stream_filter_register;
|
||||
use function stream_get_filters;
|
||||
use function strlen;
|
||||
|
||||
/**
|
||||
* A stream filter to improve enclosure character usage.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc4180#section-2
|
||||
* @see https://bugs.php.net/bug.php?id=38301
|
||||
*/
|
||||
class EncloseField extends php_user_filter
|
||||
{
|
||||
const FILTERNAME = 'convert.league.csv.enclosure';
|
||||
|
||||
/** Default sequence. */
|
||||
protected string $sequence;
|
||||
/** Characters that triggers enclosure in PHP. */
|
||||
protected static string $force_enclosure = "\n\r\t ";
|
||||
|
||||
/**
|
||||
* Static method to return the stream filter filtername.
|
||||
*/
|
||||
public static function getFiltername(): string
|
||||
{
|
||||
return self::FILTERNAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method to register the class as a stream filter.
|
||||
*/
|
||||
public static function register(): void
|
||||
{
|
||||
if (!in_array(self::FILTERNAME, stream_get_filters(), true)) {
|
||||
stream_filter_register(self::FILTERNAME, self::class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method to add the stream filter to a {@link Writer} object.
|
||||
*
|
||||
* @throws InvalidArgumentException if the sequence is malformed
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function addTo(Writer $csv, string $sequence): Writer
|
||||
{
|
||||
self::register();
|
||||
|
||||
if (!self::isValidSequence($sequence)) {
|
||||
throw new InvalidArgumentException('The sequence must contain at least one character to force enclosure');
|
||||
}
|
||||
|
||||
return $csv
|
||||
->addFormatter(fn (array $record): array => array_map(fn (?string $value): string => $sequence.$value, $record))
|
||||
->addStreamFilter(self::FILTERNAME, ['sequence' => $sequence]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter type and sequence parameters.
|
||||
*
|
||||
* The sequence to force enclosure MUST contains one of the following character ("\n\r\t ")
|
||||
*/
|
||||
protected static function isValidSequence(string $sequence): bool
|
||||
{
|
||||
return strlen($sequence) != strcspn($sequence, self::$force_enclosure);
|
||||
}
|
||||
|
||||
public function onCreate(): bool
|
||||
{
|
||||
return isset($this->params['sequence'])
|
||||
&& self::isValidSequence($this->params['sequence']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $in
|
||||
* @param resource $out
|
||||
* @param int $consumed
|
||||
* @param bool $closing
|
||||
*/
|
||||
public function filter($in, $out, &$consumed, $closing): int
|
||||
{
|
||||
while (null !== ($bucket = stream_bucket_make_writeable($in))) {
|
||||
$bucket->data = str_replace($this->params['sequence'], '', $bucket->data);
|
||||
$consumed += $bucket->datalen;
|
||||
stream_bucket_append($out, $bucket);
|
||||
}
|
||||
|
||||
return PSFS_PASS_ON;
|
||||
}
|
||||
}
|
||||
146
pancake/system/vendor/league/csv/src/EscapeFormula.php
vendored
Executable file
146
pancake/system/vendor/league/csv/src/EscapeFormula.php
vendored
Executable file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use function array_fill_keys;
|
||||
use function array_keys;
|
||||
use function array_map;
|
||||
use function array_merge;
|
||||
use function array_unique;
|
||||
use function is_object;
|
||||
use function is_string;
|
||||
use function method_exists;
|
||||
|
||||
/**
|
||||
* A Formatter to tackle CSV Formula Injection.
|
||||
*
|
||||
* @see http://georgemauer.net/2017/10/07/csv-injection.html
|
||||
*/
|
||||
class EscapeFormula
|
||||
{
|
||||
/** Spreadsheet formula starting character. */
|
||||
const FORMULA_STARTING_CHARS = ['=', '-', '+', '@', "\t", "\r"];
|
||||
|
||||
/** Effective Spreadsheet formula starting characters. */
|
||||
protected array $special_chars = [];
|
||||
/** Escape character to escape each CSV formula field. */
|
||||
protected string $escape;
|
||||
|
||||
/**
|
||||
* @param string $escape escape character to escape each CSV formula field
|
||||
* @param string[] $special_chars additional spreadsheet formula starting characters
|
||||
*/
|
||||
public function __construct(string $escape = "'", array $special_chars = [])
|
||||
{
|
||||
$this->escape = $escape;
|
||||
if ([] !== $special_chars) {
|
||||
$special_chars = $this->filterSpecialCharacters(...$special_chars);
|
||||
}
|
||||
|
||||
$chars = array_unique(array_merge(self::FORMULA_STARTING_CHARS, $special_chars));
|
||||
$this->special_chars = array_fill_keys($chars, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter submitted special characters.
|
||||
*
|
||||
* @param string ...$characters
|
||||
*
|
||||
* @throws InvalidArgumentException if the string is not a single character
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
protected function filterSpecialCharacters(string ...$characters): array
|
||||
{
|
||||
foreach ($characters as $str) {
|
||||
if (1 != strlen($str)) {
|
||||
throw new InvalidArgumentException('The submitted string '.$str.' must be a single character');
|
||||
}
|
||||
}
|
||||
|
||||
return $characters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of character the instance will escape.
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
public function getSpecialCharacters(): array
|
||||
{
|
||||
return array_keys($this->special_chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the escape character.
|
||||
*/
|
||||
public function getEscape(): string
|
||||
{
|
||||
return $this->escape;
|
||||
}
|
||||
|
||||
/**
|
||||
* League CSV formatter hook.
|
||||
*
|
||||
* @see escapeRecord
|
||||
*/
|
||||
public function __invoke(array $record): array
|
||||
{
|
||||
return $this->escapeRecord($record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape a CSV record.
|
||||
*/
|
||||
public function escapeRecord(array $record): array
|
||||
{
|
||||
return array_map([$this, 'escapeField'], $record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape a CSV cell if its content is stringable.
|
||||
*
|
||||
* @param int|float|string|object|resource|array $cell the content of the cell
|
||||
*
|
||||
* @return mixed the escaped content
|
||||
*/
|
||||
protected function escapeField($cell)
|
||||
{
|
||||
if (!is_string($cell) && (!is_object($cell) || !method_exists($cell, '__toString'))) {
|
||||
return $cell;
|
||||
}
|
||||
|
||||
$str_cell = (string) $cell;
|
||||
if (isset($str_cell[0], $this->special_chars[$str_cell[0]])) {
|
||||
return $this->escape.$str_cell;
|
||||
}
|
||||
|
||||
return $cell;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 9.7.2 will be removed in the next major release
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Tells whether the submitted value is stringable.
|
||||
*
|
||||
* @param mixed $value value to check if it is stringable
|
||||
*/
|
||||
protected function isStringable($value): bool
|
||||
{
|
||||
return is_string($value)
|
||||
|| (is_object($value) && method_exists($value, '__toString'));
|
||||
}
|
||||
}
|
||||
23
pancake/system/vendor/league/csv/src/Exception.php
vendored
Executable file
23
pancake/system/vendor/league/csv/src/Exception.php
vendored
Executable file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use Exception as PhpException;
|
||||
|
||||
/**
|
||||
* League Csv Base Exception.
|
||||
*/
|
||||
class Exception extends PhpException implements UnableToProcessCsv
|
||||
{
|
||||
}
|
||||
161
pancake/system/vendor/league/csv/src/HTMLConverter.php
vendored
Executable file
161
pancake/system/vendor/league/csv/src/HTMLConverter.php
vendored
Executable file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMElement;
|
||||
use DOMException;
|
||||
use function preg_match;
|
||||
|
||||
/**
|
||||
* Converts tabular data into an HTML Table string.
|
||||
*/
|
||||
class HTMLConverter
|
||||
{
|
||||
/** table class attribute value. */
|
||||
protected string $class_name = 'table-csv-data';
|
||||
/** table id attribute value. */
|
||||
protected string $id_value = '';
|
||||
protected XMLConverter $xml_converter;
|
||||
|
||||
public static function create(): self
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATION WARNING! This method will be removed in the next major point release.
|
||||
*
|
||||
* @deprecated since version 9.7.0
|
||||
* @see HTMLConverterTest::create()
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->xml_converter = XMLConverter::create()
|
||||
->rootElement('table')
|
||||
->recordElement('tr')
|
||||
->fieldElement('td')
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a tabular data collection into a HTML table string.
|
||||
*
|
||||
* @param string[] $header_record An optional array of headers outputted using the`<thead>` section
|
||||
* @param string[] $footer_record An optional array of footers to output to the table using `<tfoot>` and `<th>` elements
|
||||
*/
|
||||
public function convert(iterable $records, array $header_record = [], array $footer_record = []): string
|
||||
{
|
||||
$doc = new DOMDocument('1.0');
|
||||
if ([] === $header_record && [] === $footer_record) {
|
||||
$table = $this->xml_converter->import($records, $doc);
|
||||
$this->addHTMLAttributes($table);
|
||||
$doc->appendChild($table);
|
||||
|
||||
/** @var string $content */
|
||||
$content = $doc->saveHTML();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
$table = $doc->createElement('table');
|
||||
|
||||
$this->addHTMLAttributes($table);
|
||||
$this->appendHeaderSection('thead', $header_record, $table);
|
||||
$this->appendHeaderSection('tfoot', $footer_record, $table);
|
||||
|
||||
$table->appendChild($this->xml_converter->rootElement('tbody')->import($records, $doc));
|
||||
|
||||
$doc->appendChild($table);
|
||||
|
||||
/** @var string $content */
|
||||
$content = $doc->saveHTML();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DOMElement representing a HTML table heading section.
|
||||
*/
|
||||
protected function appendHeaderSection(string $node_name, array $record, DOMElement $table): void
|
||||
{
|
||||
if ([] === $record) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var DOMDocument $ownerDocument */
|
||||
$ownerDocument = $table->ownerDocument;
|
||||
$node = $this->xml_converter
|
||||
->rootElement($node_name)
|
||||
->recordElement('tr')
|
||||
->fieldElement('th')
|
||||
->import([$record], $ownerDocument)
|
||||
;
|
||||
|
||||
/** @var DOMElement $element */
|
||||
foreach ($node->getElementsByTagName('th') as $element) {
|
||||
$element->setAttribute('scope', 'col');
|
||||
}
|
||||
|
||||
$table->appendChild($node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds class and id attributes to an HTML tag.
|
||||
*/
|
||||
protected function addHTMLAttributes(DOMElement $node): void
|
||||
{
|
||||
$node->setAttribute('class', $this->class_name);
|
||||
$node->setAttribute('id', $this->id_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML table class name setter.
|
||||
*
|
||||
* @throws DOMException if the id_value contains any type of whitespace
|
||||
*/
|
||||
public function table(string $class_name, string $id_value = ''): self
|
||||
{
|
||||
if (1 === preg_match(",\s,", $id_value)) {
|
||||
throw new DOMException("the id attribute's value must not contain whitespace (spaces, tabs etc.)");
|
||||
}
|
||||
$clone = clone $this;
|
||||
$clone->class_name = $class_name;
|
||||
$clone->id_value = $id_value;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML tr record offset attribute setter.
|
||||
*/
|
||||
public function tr(string $record_offset_attribute_name): self
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->xml_converter = $this->xml_converter->recordElement('tr', $record_offset_attribute_name);
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML td field name attribute setter.
|
||||
*/
|
||||
public function td(string $fieldname_attribute_name): self
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->xml_converter = $this->xml_converter->fieldElement('td', $fieldname_attribute_name);
|
||||
|
||||
return $clone;
|
||||
}
|
||||
}
|
||||
99
pancake/system/vendor/league/csv/src/Info.php
vendored
Executable file
99
pancake/system/vendor/league/csv/src/Info.php
vendored
Executable file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use function array_fill_keys;
|
||||
use function array_filter;
|
||||
use function array_reduce;
|
||||
use function array_unique;
|
||||
use function count;
|
||||
use function iterator_to_array;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use const COUNT_RECURSIVE;
|
||||
|
||||
final class Info implements ByteSequence
|
||||
{
|
||||
private const BOM_SEQUENCE_LIST = [
|
||||
self::BOM_UTF32_BE,
|
||||
self::BOM_UTF32_LE,
|
||||
self::BOM_UTF16_BE,
|
||||
self::BOM_UTF16_LE,
|
||||
self::BOM_UTF8,
|
||||
];
|
||||
|
||||
/**
|
||||
* Returns the BOM sequence found at the start of the string.
|
||||
*
|
||||
* If no valid BOM sequence is found an empty string is returned
|
||||
*/
|
||||
public static function fetchBOMSequence(string $str): ?string
|
||||
{
|
||||
foreach (self::BOM_SEQUENCE_LIST as $sequence) {
|
||||
if (0 === strpos($str, $sequence)) {
|
||||
return $sequence;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect Delimiters usage in a {@link Reader} object.
|
||||
*
|
||||
* Returns a associative array where each key represents
|
||||
* a submitted delimiter and each value the number CSV fields found
|
||||
* when processing at most $limit CSV records with the given delimiter
|
||||
*
|
||||
* @param string[] $delimiters
|
||||
*
|
||||
* @return array<string, int>
|
||||
*/
|
||||
public static function getDelimiterStats(Reader $csv, array $delimiters, int $limit = 1): array
|
||||
{
|
||||
$delimiterFilter = static fn (string $value): bool => 1 === strlen($value);
|
||||
|
||||
$recordFilter = static fn (array $record): bool => 1 < count($record);
|
||||
|
||||
$stmt = Statement::create()->offset(0)->limit($limit);
|
||||
|
||||
$delimiterStats = static function (array $stats, string $delimiter) use ($csv, $stmt, $recordFilter): array {
|
||||
$csv->setDelimiter($delimiter);
|
||||
$foundRecords = array_filter(
|
||||
iterator_to_array($stmt->process($csv)->getRecords(), false),
|
||||
$recordFilter
|
||||
);
|
||||
|
||||
$stats[$delimiter] = count($foundRecords, COUNT_RECURSIVE);
|
||||
|
||||
return $stats;
|
||||
};
|
||||
|
||||
$currentDelimiter = $csv->getDelimiter();
|
||||
$currentHeaderOffset = $csv->getHeaderOffset();
|
||||
|
||||
$csv->setHeaderOffset(null);
|
||||
|
||||
$stats = array_reduce(
|
||||
array_unique(array_filter($delimiters, $delimiterFilter)),
|
||||
$delimiterStats,
|
||||
array_fill_keys($delimiters, 0)
|
||||
);
|
||||
|
||||
$csv->setHeaderOffset($currentHeaderOffset);
|
||||
$csv->setDelimiter($currentDelimiter);
|
||||
|
||||
return $stats;
|
||||
}
|
||||
}
|
||||
100
pancake/system/vendor/league/csv/src/InvalidArgument.php
vendored
Executable file
100
pancake/system/vendor/league/csv/src/InvalidArgument.php
vendored
Executable file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* InvalidArgument Exception.
|
||||
*/
|
||||
class InvalidArgument extends Exception
|
||||
{
|
||||
/**
|
||||
* DEPRECATION WARNING! This class will be removed in the next major point release.
|
||||
*
|
||||
* @deprecated since version 9.7.0
|
||||
*/
|
||||
public function __construct(string $message = '', int $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
public static function dueToInvalidChunkSize(int $length, string $method): self
|
||||
{
|
||||
return new self($method.'() expects the length to be a positive integer '.$length.' given.');
|
||||
}
|
||||
|
||||
public static function dueToInvalidHeaderFilename(string $filename): self
|
||||
{
|
||||
return new self('The filename `'.$filename.'` cannot contain the "/" and "\\" characters.');
|
||||
}
|
||||
|
||||
public static function dueToInvalidDelimiterCharacter(string $delimiter, string $method): self
|
||||
{
|
||||
return new self($method.'() expects delimiter to be a single character; `'.$delimiter.'` given.');
|
||||
}
|
||||
|
||||
public static function dueToInvalidEnclosureCharacter(string $enclosure, string $method): self
|
||||
{
|
||||
return new self($method.'() expects enclosure to be a single character; `'.$enclosure.'` given.');
|
||||
}
|
||||
|
||||
public static function dueToInvalidEscapeCharacter(string $escape, string $method): self
|
||||
{
|
||||
return new self($method.'() expects escape to be a single character or the empty string; `'.$escape.'` given.');
|
||||
}
|
||||
|
||||
public static function dueToInvalidColumnCount(int $columns_count, string $method): self
|
||||
{
|
||||
return new self($method.'() expects the column count to be greater or equal to -1 '.$columns_count.' given.');
|
||||
}
|
||||
|
||||
public static function dueToInvalidHeaderOffset(int $offset, string $method): self
|
||||
{
|
||||
return new self($method.'() expects header offset to be greater or equal to 0; `'.$offset.'` given.');
|
||||
}
|
||||
|
||||
public static function dueToInvalidRecordOffset(int $offset, string $method): self
|
||||
{
|
||||
return new self($method.'() expects the submitted offset to be a positive integer or 0, '.$offset.' given');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|int $index
|
||||
*/
|
||||
public static function dueToInvalidColumnIndex($index, string $type, string $method): self
|
||||
{
|
||||
return new self($method.'() expects the '.$type.' index to be a valid string or integer, `'.$index.'` given');
|
||||
}
|
||||
|
||||
public static function dueToInvalidLimit(int $limit, string $method): self
|
||||
{
|
||||
return new self($method.'() expects the limit to be greater or equal to -1, '.$limit.' given.');
|
||||
}
|
||||
|
||||
public static function dueToInvalidSeekingPosition(int $position, string $method): self
|
||||
{
|
||||
return new self($method.'() can\'t seek stream to negative line '.$position);
|
||||
}
|
||||
|
||||
public static function dueToStreamFilterNotFound(string $filtername): self
|
||||
{
|
||||
return new self('unable to locate filter `'.$filtername.'`');
|
||||
}
|
||||
|
||||
public static function dueToInvalidThreshold(int $threshold, string $method): self
|
||||
{
|
||||
return new self($method.'() expects threshold to be null or a valid integer greater or equal to 1');
|
||||
}
|
||||
}
|
||||
44
pancake/system/vendor/league/csv/src/MapIterator.php
vendored
Executable file
44
pancake/system/vendor/league/csv/src/MapIterator.php
vendored
Executable file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use IteratorIterator;
|
||||
use ReturnTypeWillChange;
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
* Map value from an iterator before yielding.
|
||||
*
|
||||
* @internal used internally to modify CSV content
|
||||
*/
|
||||
final class MapIterator extends IteratorIterator
|
||||
{
|
||||
/** @var callable The callback to apply on all InnerIterator current value. */
|
||||
private $callable;
|
||||
|
||||
public function __construct(Traversable $iterator, callable $callable)
|
||||
{
|
||||
parent::__construct($iterator);
|
||||
$this->callable = $callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed The value of the current element.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function current()
|
||||
{
|
||||
return ($this->callable)(parent::current(), parent::key());
|
||||
}
|
||||
}
|
||||
182
pancake/system/vendor/league/csv/src/RFC4180Field.php
vendored
Executable file
182
pancake/system/vendor/league/csv/src/RFC4180Field.php
vendored
Executable file
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use php_user_filter;
|
||||
use function array_map;
|
||||
use function in_array;
|
||||
use function is_string;
|
||||
use function str_replace;
|
||||
use function strcspn;
|
||||
use function stream_bucket_append;
|
||||
use function stream_bucket_make_writeable;
|
||||
use function stream_filter_register;
|
||||
use function stream_get_filters;
|
||||
use function strlen;
|
||||
use const STREAM_FILTER_READ;
|
||||
use const STREAM_FILTER_WRITE;
|
||||
|
||||
/**
|
||||
* A stream filter to conform the CSV field to RFC4180.
|
||||
*
|
||||
* DEPRECATION WARNING! This class will be removed in the next major point release
|
||||
*
|
||||
* @deprecated since version 9.2.0
|
||||
* @see AbstractCsv::setEscape
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc4180#section-2
|
||||
*/
|
||||
class RFC4180Field extends php_user_filter
|
||||
{
|
||||
public const FILTERNAME = 'convert.league.csv.rfc4180';
|
||||
|
||||
/**
|
||||
* The value being search for.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected array $search;
|
||||
|
||||
/**
|
||||
* The replacement value that replace found $search values.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected array $replace;
|
||||
|
||||
/**
|
||||
* Characters that triggers enclosure with PHP fputcsv.
|
||||
*
|
||||
*/
|
||||
protected static string $force_enclosure = "\n\r\t ";
|
||||
|
||||
/**
|
||||
* Static method to add the stream filter to a {@link AbstractCsv} object.
|
||||
*/
|
||||
public static function addTo(AbstractCsv $csv, string $whitespace_replace = ''): AbstractCsv
|
||||
{
|
||||
self::register();
|
||||
|
||||
$params = [
|
||||
'enclosure' => $csv->getEnclosure(),
|
||||
'escape' => $csv->getEscape(),
|
||||
'mode' => $csv->getStreamFilterMode(),
|
||||
];
|
||||
|
||||
if ($csv instanceof Writer && '' != $whitespace_replace) {
|
||||
self::addFormatterTo($csv, $whitespace_replace);
|
||||
$params['whitespace_replace'] = $whitespace_replace;
|
||||
}
|
||||
|
||||
return $csv->addStreamFilter(self::FILTERNAME, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a formatter to the {@link Writer} object to format the record
|
||||
* field to avoid enclosure around a field with an empty space.
|
||||
*/
|
||||
public static function addFormatterTo(Writer $csv, string $whitespace_replace): Writer
|
||||
{
|
||||
if ('' == $whitespace_replace || strlen($whitespace_replace) != strcspn($whitespace_replace, self::$force_enclosure)) {
|
||||
throw new InvalidArgumentException('The sequence contains a character that enforces enclosure or is a CSV control character or is the empty string.');
|
||||
}
|
||||
|
||||
$mapper = fn ($value) => is_string($value)
|
||||
? str_replace(' ', $whitespace_replace, $value)
|
||||
: $value;
|
||||
|
||||
return $csv->addFormatter(fn (array $record): array => array_map($mapper, $record));
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method to register the class as a stream filter.
|
||||
*/
|
||||
public static function register(): void
|
||||
{
|
||||
if (!in_array(self::FILTERNAME, stream_get_filters(), true)) {
|
||||
stream_filter_register(self::FILTERNAME, self::class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method to return the stream filter filtername.
|
||||
*/
|
||||
public static function getFiltername(): string
|
||||
{
|
||||
return self::FILTERNAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $in
|
||||
* @param resource $out
|
||||
* @param int $consumed
|
||||
* @param bool $closing
|
||||
*/
|
||||
public function filter($in, $out, &$consumed, $closing): int
|
||||
{
|
||||
while (null !== ($bucket = stream_bucket_make_writeable($in))) {
|
||||
$bucket->data = str_replace($this->search, $this->replace, $bucket->data);
|
||||
$consumed += $bucket->datalen;
|
||||
stream_bucket_append($out, $bucket);
|
||||
}
|
||||
|
||||
return PSFS_PASS_ON;
|
||||
}
|
||||
|
||||
public function onCreate(): bool
|
||||
{
|
||||
if (!$this->isValidParams($this->params)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->search = [$this->params['escape'].$this->params['enclosure']];
|
||||
$this->replace = [$this->params['enclosure'].$this->params['enclosure']];
|
||||
if (STREAM_FILTER_WRITE != $this->params['mode']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->search = [$this->params['escape'].$this->params['enclosure']];
|
||||
$this->replace = [$this->params['escape'].$this->params['enclosure'].$this->params['enclosure']];
|
||||
if ($this->isValidSequence($this->params)) {
|
||||
$this->search[] = $this->params['whitespace_replace'];
|
||||
$this->replace[] = ' ';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate params property.
|
||||
*/
|
||||
protected function isValidParams(array $params): bool
|
||||
{
|
||||
static $mode_list = [STREAM_FILTER_READ => 1, STREAM_FILTER_WRITE => 1];
|
||||
|
||||
return isset($params['enclosure'], $params['escape'], $params['mode'], $mode_list[$params['mode']])
|
||||
&& 1 == strlen($params['enclosure'])
|
||||
&& 1 == strlen($params['escape']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Valid White space replaced sequence.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isValidSequence(array $params)
|
||||
{
|
||||
return isset($params['whitespace_replace'])
|
||||
&& strlen($params['whitespace_replace']) == strcspn($params['whitespace_replace'], self::$force_enclosure);
|
||||
}
|
||||
}
|
||||
365
pancake/system/vendor/league/csv/src/Reader.php
vendored
Executable file
365
pancake/system/vendor/league/csv/src/Reader.php
vendored
Executable file
@@ -0,0 +1,365 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use CallbackFilterIterator;
|
||||
use Iterator;
|
||||
use JsonSerializable;
|
||||
use SplFileObject;
|
||||
use function array_combine;
|
||||
use function array_filter;
|
||||
use function array_pad;
|
||||
use function array_slice;
|
||||
use function array_unique;
|
||||
use function count;
|
||||
use function is_array;
|
||||
use function iterator_count;
|
||||
use function iterator_to_array;
|
||||
use function mb_strlen;
|
||||
use function mb_substr;
|
||||
use function strlen;
|
||||
use function substr;
|
||||
use const STREAM_FILTER_READ;
|
||||
|
||||
/**
|
||||
* A class to parse and read records from a CSV document.
|
||||
*/
|
||||
class Reader extends AbstractCsv implements TabularDataReader, JsonSerializable
|
||||
{
|
||||
protected const STREAM_FILTER_MODE = STREAM_FILTER_READ;
|
||||
|
||||
protected ?int $header_offset = null;
|
||||
protected int $nb_records = -1;
|
||||
protected bool $is_empty_records_included = false;
|
||||
/** @var array<string> header record. */
|
||||
protected array $header = [];
|
||||
|
||||
public static function createFromPath(string $path, string $open_mode = 'r', $context = null)
|
||||
{
|
||||
return parent::createFromPath($path, $open_mode, $context);
|
||||
}
|
||||
|
||||
protected function resetProperties(): void
|
||||
{
|
||||
$this->nb_records = -1;
|
||||
$this->header = [];
|
||||
}
|
||||
|
||||
/** Returns the header offset. */
|
||||
public function getHeaderOffset(): ?int
|
||||
{
|
||||
return $this->header_offset;
|
||||
}
|
||||
|
||||
public function getHeader(): array
|
||||
{
|
||||
if (null === $this->header_offset) {
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
if ([] !== $this->header) {
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
$this->header = $this->setHeader($this->header_offset);
|
||||
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the CSV record header.
|
||||
*
|
||||
* @throws Exception If the header offset is set and no record is found or is the empty array
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
protected function setHeader(int $offset): array
|
||||
{
|
||||
$header = $this->seekRow($offset);
|
||||
if (in_array($header, [[], [null]], true)) {
|
||||
throw SyntaxError::dueToHeaderNotFound($offset);
|
||||
}
|
||||
|
||||
if (0 !== $offset) {
|
||||
return $header;
|
||||
}
|
||||
|
||||
$header = $this->removeBOM($header, mb_strlen($this->getInputBOM()), $this->enclosure);
|
||||
if ([''] === $header) {
|
||||
throw SyntaxError::dueToHeaderNotFound($offset);
|
||||
}
|
||||
|
||||
return $header;
|
||||
}
|
||||
|
||||
/** Returns the row at a given offset. */
|
||||
protected function seekRow(int $offset): array
|
||||
{
|
||||
foreach ($this->getDocument() as $index => $record) {
|
||||
if ($offset === $index) {
|
||||
return $record;
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the document as an Iterator.
|
||||
*/
|
||||
protected function getDocument(): Iterator
|
||||
{
|
||||
$this->document->setFlags(SplFileObject::READ_CSV | SplFileObject::READ_AHEAD);
|
||||
$this->document->setCsvControl($this->delimiter, $this->enclosure, $this->escape);
|
||||
$this->document->rewind();
|
||||
|
||||
return $this->document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip the BOM sequence from a record.
|
||||
*
|
||||
* @param string[] $record
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
protected function removeBOM(array $record, int $bom_length, string $enclosure): array
|
||||
{
|
||||
if (0 === $bom_length) {
|
||||
return $record;
|
||||
}
|
||||
|
||||
$record[0] = mb_substr($record[0], $bom_length);
|
||||
if ($enclosure.$enclosure != substr($record[0].$record[0], strlen($record[0]) - 1, 2)) {
|
||||
return $record;
|
||||
}
|
||||
|
||||
$record[0] = substr($record[0], 1, -1);
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
public function fetchColumnByName(string $name): Iterator
|
||||
{
|
||||
return ResultSet::createFromTabularDataReader($this)->fetchColumnByName($name);
|
||||
}
|
||||
|
||||
public function fetchColumnByOffset(int $offset = 0): Iterator
|
||||
{
|
||||
return ResultSet::createFromTabularDataReader($this)->fetchColumnByOffset($offset);
|
||||
}
|
||||
|
||||
public function fetchColumn($index = 0): Iterator
|
||||
{
|
||||
return ResultSet::createFromTabularDataReader($this)->fetchColumn($index);
|
||||
}
|
||||
|
||||
public function fetchOne(int $nth_record = 0): array
|
||||
{
|
||||
return ResultSet::createFromTabularDataReader($this)->fetchOne($nth_record);
|
||||
}
|
||||
|
||||
public function fetchPairs($offset_index = 0, $value_index = 1): Iterator
|
||||
{
|
||||
return ResultSet::createFromTabularDataReader($this)->fetchPairs($offset_index, $value_index);
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
if (-1 === $this->nb_records) {
|
||||
$this->nb_records = iterator_count($this->getRecords());
|
||||
}
|
||||
|
||||
return $this->nb_records;
|
||||
}
|
||||
|
||||
public function getIterator(): Iterator
|
||||
{
|
||||
return $this->getRecords();
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return iterator_to_array($this->getRecords(), false);
|
||||
}
|
||||
|
||||
public function getRecords(array $header = []): Iterator
|
||||
{
|
||||
$header = $this->computeHeader($header);
|
||||
$normalized = fn ($record): bool => is_array($record) && ($this->is_empty_records_included || $record != [null]);
|
||||
|
||||
$bom = '';
|
||||
if (!$this->is_input_bom_included) {
|
||||
$bom = $this->getInputBOM();
|
||||
}
|
||||
|
||||
$document = $this->getDocument();
|
||||
$records = $this->stripBOM(new CallbackFilterIterator($document, $normalized), $bom);
|
||||
if (null !== $this->header_offset) {
|
||||
$records = new CallbackFilterIterator($records, fn (array $record, int $offset): bool => $offset !== $this->header_offset);
|
||||
}
|
||||
|
||||
if ($this->is_empty_records_included) {
|
||||
return $this->combineHeader(new MapIterator(
|
||||
$records,
|
||||
fn (array $record): array => ([null] === $record) ? [] : $record
|
||||
), $header);
|
||||
}
|
||||
|
||||
return $this->combineHeader($records, $header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the header to be used for iteration.
|
||||
*
|
||||
* @param string[] $header
|
||||
*
|
||||
* @throws Exception If the header contains non unique column name
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
protected function computeHeader(array $header)
|
||||
{
|
||||
if ([] === $header) {
|
||||
$header = $this->getHeader();
|
||||
}
|
||||
|
||||
if ($header !== ($filtered_header = array_filter($header, 'is_string'))) {
|
||||
throw SyntaxError::dueToInvalidHeaderColumnNames();
|
||||
}
|
||||
|
||||
if ($header !== array_unique($filtered_header)) {
|
||||
throw SyntaxError::dueToDuplicateHeaderColumnNames($header);
|
||||
}
|
||||
|
||||
return $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine the CSV header to each record if present.
|
||||
*
|
||||
* @param string[] $header
|
||||
*/
|
||||
protected function combineHeader(Iterator $iterator, array $header): Iterator
|
||||
{
|
||||
if ([] === $header) {
|
||||
return $iterator;
|
||||
}
|
||||
|
||||
$field_count = count($header);
|
||||
$mapper = static function (array $record) use ($header, $field_count): array {
|
||||
if (count($record) != $field_count) {
|
||||
$record = array_slice(array_pad($record, $field_count, null), 0, $field_count);
|
||||
}
|
||||
|
||||
/** @var array<string|null> $assocRecord */
|
||||
$assocRecord = array_combine($header, $record);
|
||||
|
||||
return $assocRecord;
|
||||
};
|
||||
|
||||
return new MapIterator($iterator, $mapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip the BOM sequence from the returned records if necessary.
|
||||
*/
|
||||
protected function stripBOM(Iterator $iterator, string $bom): Iterator
|
||||
{
|
||||
if ('' === $bom) {
|
||||
return $iterator;
|
||||
}
|
||||
|
||||
$bom_length = mb_strlen($bom);
|
||||
$mapper = function (array $record, int $index) use ($bom_length): array {
|
||||
if (0 !== $index) {
|
||||
return $record;
|
||||
}
|
||||
|
||||
$record = $this->removeBOM($record, $bom_length, $this->enclosure);
|
||||
if ([''] === $record) {
|
||||
return [null];
|
||||
}
|
||||
|
||||
return $record;
|
||||
};
|
||||
|
||||
return new CallbackFilterIterator(
|
||||
new MapIterator($iterator, $mapper),
|
||||
fn (array $record): bool => $this->is_empty_records_included || $record != [null]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the record to be used as the CSV header.
|
||||
*
|
||||
* Because the header is represented as an array, to be valid
|
||||
* a header MUST contain only unique string value.
|
||||
*
|
||||
* @param int|null $offset the header record offset
|
||||
*
|
||||
* @throws Exception if the offset is a negative integer
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function setHeaderOffset(?int $offset): self
|
||||
{
|
||||
if ($offset === $this->header_offset) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (null !== $offset && 0 > $offset) {
|
||||
throw InvalidArgument::dueToInvalidHeaderOffset($offset, __METHOD__);
|
||||
}
|
||||
|
||||
$this->header_offset = $offset;
|
||||
$this->resetProperties();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable skipping empty records.
|
||||
*/
|
||||
public function skipEmptyRecords(): self
|
||||
{
|
||||
if ($this->is_empty_records_included) {
|
||||
$this->is_empty_records_included = false;
|
||||
$this->nb_records = -1;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable skipping empty records.
|
||||
*/
|
||||
public function includeEmptyRecords(): self
|
||||
{
|
||||
if (!$this->is_empty_records_included) {
|
||||
$this->is_empty_records_included = true;
|
||||
$this->nb_records = -1;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether empty records are skipped by the instance.
|
||||
*/
|
||||
public function isEmptyRecordsIncluded(): bool
|
||||
{
|
||||
return $this->is_empty_records_included;
|
||||
}
|
||||
}
|
||||
261
pancake/system/vendor/league/csv/src/ResultSet.php
vendored
Executable file
261
pancake/system/vendor/league/csv/src/ResultSet.php
vendored
Executable file
@@ -0,0 +1,261 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use CallbackFilterIterator;
|
||||
use Generator;
|
||||
use Iterator;
|
||||
use JsonSerializable;
|
||||
use LimitIterator;
|
||||
use function array_flip;
|
||||
use function array_search;
|
||||
use function is_string;
|
||||
use function iterator_count;
|
||||
use function iterator_to_array;
|
||||
|
||||
/**
|
||||
* Represents the result set of a {@link Reader} processed by a {@link Statement}.
|
||||
*/
|
||||
class ResultSet implements TabularDataReader, JsonSerializable
|
||||
{
|
||||
/** The CSV records collection. */
|
||||
protected Iterator $records;
|
||||
/** @var array<string> The CSV records collection header. */
|
||||
protected array $header = [];
|
||||
|
||||
public function __construct(Iterator $records, array $header)
|
||||
{
|
||||
$this->validateHeader($header);
|
||||
|
||||
$this->records = $records;
|
||||
$this->header = $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SyntaxError if the header syntax is invalid
|
||||
*/
|
||||
protected function validateHeader(array $header): void
|
||||
{
|
||||
if ($header !== ($filtered_header = array_filter($header, 'is_string'))) {
|
||||
throw SyntaxError::dueToInvalidHeaderColumnNames();
|
||||
}
|
||||
|
||||
if ($header !== array_unique($filtered_header)) {
|
||||
throw SyntaxError::dueToDuplicateHeaderColumnNames($header);
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
unset($this->records);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new instance from an object implementing the TabularDataReader interface.
|
||||
*/
|
||||
public static function createFromTabularDataReader(TabularDataReader $reader): self
|
||||
{
|
||||
return new self($reader->getRecords(), $reader->getHeader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the header associated with the result set.
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
public function getHeader(): array
|
||||
{
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
public function getIterator(): Iterator
|
||||
{
|
||||
return $this->getRecords();
|
||||
}
|
||||
|
||||
public function getRecords(array $header = []): Iterator
|
||||
{
|
||||
$this->validateHeader($header);
|
||||
$records = $this->combineHeader($header);
|
||||
foreach ($records as $offset => $value) {
|
||||
yield $offset => $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine the header to each record if present.
|
||||
*/
|
||||
protected function combineHeader(array $header): Iterator
|
||||
{
|
||||
if ($header === $this->header || [] === $header) {
|
||||
return $this->records;
|
||||
}
|
||||
|
||||
$field_count = count($header);
|
||||
$mapper = static function (array $record) use ($header, $field_count): array {
|
||||
if (count($record) != $field_count) {
|
||||
$record = array_slice(array_pad($record, $field_count, null), 0, $field_count);
|
||||
}
|
||||
|
||||
/** @var array<string|null> $assocRecord */
|
||||
$assocRecord = array_combine($header, $record);
|
||||
|
||||
return $assocRecord;
|
||||
};
|
||||
|
||||
return new MapIterator($this->records, $mapper);
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return iterator_count($this->records);
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return iterator_to_array($this->records, false);
|
||||
}
|
||||
|
||||
public function fetchOne(int $nth_record = 0): array
|
||||
{
|
||||
if ($nth_record < 0) {
|
||||
throw InvalidArgument::dueToInvalidRecordOffset($nth_record, __METHOD__);
|
||||
}
|
||||
|
||||
$iterator = new LimitIterator($this->records, $nth_record, 1);
|
||||
$iterator->rewind();
|
||||
|
||||
$result = $iterator->current();
|
||||
if (!is_array($result)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function fetchColumnByName(string $name): Iterator
|
||||
{
|
||||
return $this->yieldColumn(
|
||||
$this->getColumnIndexByValue($name, 'name', __METHOD__)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function fetchColumnByOffset(int $offset): Iterator
|
||||
{
|
||||
return $this->yieldColumn(
|
||||
$this->getColumnIndexByKey($offset, 'offset', __METHOD__)
|
||||
);
|
||||
}
|
||||
|
||||
public function fetchColumn($index = 0): Iterator
|
||||
{
|
||||
return $this->yieldColumn(
|
||||
$this->getColumnIndex($index, 'offset', __METHOD__)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|int $offset
|
||||
*/
|
||||
protected function yieldColumn($offset): Generator
|
||||
{
|
||||
$iterator = new MapIterator(
|
||||
new CallbackFilterIterator($this->records, fn (array $record): bool => isset($record[$offset])),
|
||||
fn (array $record): string => $record[$offset]
|
||||
);
|
||||
|
||||
foreach ($iterator as $key => $value) {
|
||||
yield $key => $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter a column name against the header if any.
|
||||
*
|
||||
* @param string|int $field the field name or the field index
|
||||
*
|
||||
* @throws InvalidArgument if the field is invalid or not found
|
||||
*
|
||||
* @return string|int
|
||||
*/
|
||||
protected function getColumnIndex($field, string $type, string $method)
|
||||
{
|
||||
if (is_string($field)) {
|
||||
return $this->getColumnIndexByValue($field, $type, $method);
|
||||
}
|
||||
|
||||
return $this->getColumnIndexByKey($field, $type, $method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the selected column name.
|
||||
*
|
||||
* @throws InvalidArgument if the column is not found
|
||||
*/
|
||||
protected function getColumnIndexByValue(string $value, string $type, string $method): string
|
||||
{
|
||||
if (false === array_search($value, $this->header, true)) {
|
||||
throw InvalidArgument::dueToInvalidColumnIndex($value, $type, $method);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the selected column name according to its offset.
|
||||
*
|
||||
* @throws InvalidArgument if the field is invalid or not found
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
protected function getColumnIndexByKey(int $index, string $type, string $method)
|
||||
{
|
||||
if ($index < 0) {
|
||||
throw InvalidArgument::dueToInvalidColumnIndex($index, $type, $method);
|
||||
}
|
||||
|
||||
if ([] === $this->header) {
|
||||
return $index;
|
||||
}
|
||||
|
||||
$value = array_search($index, array_flip($this->header), true);
|
||||
if (false === $value) {
|
||||
throw InvalidArgument::dueToInvalidColumnIndex($index, $type, $method);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function fetchPairs($offset_index = 0, $value_index = 1): Iterator
|
||||
{
|
||||
$offset = $this->getColumnIndex($offset_index, 'offset', __METHOD__);
|
||||
$value = $this->getColumnIndex($value_index, 'value', __METHOD__);
|
||||
|
||||
$iterator = new MapIterator(
|
||||
new CallbackFilterIterator($this->records, fn (array $record): bool => isset($record[$offset])),
|
||||
fn (array $record): array => [$record[$offset], $record[$value] ?? null]
|
||||
);
|
||||
|
||||
/** @var array{0:int|string, 1:string|null} $pair */
|
||||
foreach ($iterator as $pair) {
|
||||
yield $pair[0] => $pair[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
166
pancake/system/vendor/league/csv/src/Statement.php
vendored
Executable file
166
pancake/system/vendor/league/csv/src/Statement.php
vendored
Executable file
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use ArrayIterator;
|
||||
use CallbackFilterIterator;
|
||||
use Iterator;
|
||||
use LimitIterator;
|
||||
use function array_reduce;
|
||||
|
||||
/**
|
||||
* Criteria to filter a {@link Reader} object.
|
||||
*/
|
||||
class Statement
|
||||
{
|
||||
/** @var array<callable> Callables to filter the iterator. */
|
||||
protected array $where = [];
|
||||
/** @var array<callable> Callables to sort the iterator. */
|
||||
protected array $order_by = [];
|
||||
/** iterator Offset. */
|
||||
protected int $offset = 0;
|
||||
/** iterator maximum length. */
|
||||
protected int $limit = -1;
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function create(callable $where = null, int $offset = 0, int $limit = -1): self
|
||||
{
|
||||
$stmt = new self();
|
||||
if (null !== $where) {
|
||||
$stmt = $stmt->where($where);
|
||||
}
|
||||
|
||||
return $stmt->offset($offset)->limit($limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Iterator filter method.
|
||||
*/
|
||||
public function where(callable $where): self
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->where[] = $where;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an Iterator sorting callable function.
|
||||
*/
|
||||
public function orderBy(callable $order_by): self
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->order_by[] = $order_by;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set LimitIterator Offset.
|
||||
*
|
||||
* @throws Exception if the offset is lesser than 0
|
||||
*/
|
||||
public function offset(int $offset): self
|
||||
{
|
||||
if (0 > $offset) {
|
||||
throw InvalidArgument::dueToInvalidRecordOffset($offset, __METHOD__);
|
||||
}
|
||||
|
||||
if ($offset === $this->offset) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$clone = clone $this;
|
||||
$clone->offset = $offset;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set LimitIterator Count.
|
||||
*
|
||||
* @throws Exception if the limit is lesser than -1
|
||||
*/
|
||||
public function limit(int $limit): self
|
||||
{
|
||||
if (-1 > $limit) {
|
||||
throw InvalidArgument::dueToInvalidLimit($limit, __METHOD__);
|
||||
}
|
||||
|
||||
if ($limit === $this->limit) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$clone = clone $this;
|
||||
$clone->limit = $limit;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the prepared Statement on the {@link Reader} object.
|
||||
*
|
||||
* @param array<string> $header an optional header to use instead of the CSV document header
|
||||
*/
|
||||
public function process(TabularDataReader $tabular_data, array $header = []): TabularDataReader
|
||||
{
|
||||
if ([] === $header) {
|
||||
$header = $tabular_data->getHeader();
|
||||
}
|
||||
|
||||
$iterator = $tabular_data->getRecords($header);
|
||||
$iterator = array_reduce($this->where, [$this, 'filter'], $iterator);
|
||||
$iterator = $this->buildOrderBy($iterator);
|
||||
|
||||
return new ResultSet(new LimitIterator($iterator, $this->offset, $this->limit), $header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters elements of an Iterator using a callback function.
|
||||
*/
|
||||
protected function filter(Iterator $iterator, callable $callable): CallbackFilterIterator
|
||||
{
|
||||
return new CallbackFilterIterator($iterator, $callable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the Iterator.
|
||||
*/
|
||||
protected function buildOrderBy(Iterator $iterator): Iterator
|
||||
{
|
||||
if ([] === $this->order_by) {
|
||||
return $iterator;
|
||||
}
|
||||
|
||||
$compare = function (array $record_a, array $record_b): int {
|
||||
foreach ($this->order_by as $callable) {
|
||||
if (0 !== ($cmp = $callable($record_a, $record_b))) {
|
||||
return $cmp;
|
||||
}
|
||||
}
|
||||
|
||||
return $cmp ?? 0;
|
||||
};
|
||||
|
||||
$it = new ArrayIterator();
|
||||
foreach ($iterator as $offset => $value) {
|
||||
$it[$offset] = $value;
|
||||
}
|
||||
$it->uasort($compare);
|
||||
|
||||
return $it;
|
||||
}
|
||||
}
|
||||
447
pancake/system/vendor/league/csv/src/Stream.php
vendored
Executable file
447
pancake/system/vendor/league/csv/src/Stream.php
vendored
Executable file
@@ -0,0 +1,447 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use ReturnTypeWillChange;
|
||||
use SeekableIterator;
|
||||
use SplFileObject;
|
||||
use TypeError;
|
||||
use function array_keys;
|
||||
use function array_walk_recursive;
|
||||
use function fclose;
|
||||
use function feof;
|
||||
use function fflush;
|
||||
use function fgetcsv;
|
||||
use function fgets;
|
||||
use function fopen;
|
||||
use function fpassthru;
|
||||
use function fputcsv;
|
||||
use function fread;
|
||||
use function fseek;
|
||||
use function fwrite;
|
||||
use function get_resource_type;
|
||||
use function gettype;
|
||||
use function is_array;
|
||||
use function is_resource;
|
||||
use function rewind;
|
||||
use function stream_filter_append;
|
||||
use function stream_filter_remove;
|
||||
use function stream_get_meta_data;
|
||||
use function strlen;
|
||||
use const PHP_VERSION_ID;
|
||||
use const SEEK_SET;
|
||||
|
||||
/**
|
||||
* An object oriented API to handle a PHP stream resource.
|
||||
*
|
||||
* @internal used internally to iterate over a stream resource
|
||||
*/
|
||||
final class Stream implements SeekableIterator
|
||||
{
|
||||
/** @var array<string, array<resource>> Attached filters. */
|
||||
private array $filters = [];
|
||||
/** @var resource */
|
||||
private $stream;
|
||||
private bool $should_close_stream = false;
|
||||
/** @var mixed can be a null false or a scalar type value. Current iterator value. */
|
||||
private $value;
|
||||
/** Current iterator key. */
|
||||
private int $offset;
|
||||
/** Flags for the Document.*/
|
||||
private int $flags = 0;
|
||||
private string $delimiter = ',';
|
||||
private string $enclosure = '"';
|
||||
private string $escape = '\\';
|
||||
private bool $is_seekable = false;
|
||||
|
||||
/**
|
||||
* @param mixed $stream stream type resource
|
||||
*/
|
||||
public function __construct($stream)
|
||||
{
|
||||
if (!is_resource($stream)) {
|
||||
throw new TypeError('Argument passed must be a stream resource, '.gettype($stream).' given.');
|
||||
}
|
||||
|
||||
if ('stream' !== ($type = get_resource_type($stream))) {
|
||||
throw new TypeError('Argument passed must be a stream resource, '.$type.' resource given');
|
||||
}
|
||||
|
||||
$this->is_seekable = stream_get_meta_data($stream)['seekable'];
|
||||
$this->stream = $stream;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
array_walk_recursive($this->filters, fn ($filter): bool => @stream_filter_remove($filter));
|
||||
|
||||
if ($this->should_close_stream && is_resource($this->stream)) {
|
||||
fclose($this->stream);
|
||||
}
|
||||
|
||||
unset($this->stream);
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
throw UnavailableStream::dueToForbiddenCloning(self::class);
|
||||
}
|
||||
|
||||
public function __debugInfo(): array
|
||||
{
|
||||
return stream_get_meta_data($this->stream) + [
|
||||
'delimiter' => $this->delimiter,
|
||||
'enclosure' => $this->enclosure,
|
||||
'escape' => $this->escape,
|
||||
'stream_filters' => array_keys($this->filters),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new instance from a file path.
|
||||
*
|
||||
* @param resource|null $context
|
||||
*
|
||||
* @throws Exception if the stream resource can not be created
|
||||
*/
|
||||
public static function createFromPath(string $path, string $open_mode = 'r', $context = null): self
|
||||
{
|
||||
$args = [$path, $open_mode];
|
||||
if (null !== $context) {
|
||||
$args[] = false;
|
||||
$args[] = $context;
|
||||
}
|
||||
|
||||
$resource = @fopen(...$args);
|
||||
if (!is_resource($resource)) {
|
||||
throw UnavailableStream::dueToPathNotFound($path);
|
||||
}
|
||||
|
||||
$instance = new self($resource);
|
||||
$instance->should_close_stream = true;
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new instance from a string.
|
||||
*/
|
||||
public static function createFromString(string $content = ''): self
|
||||
{
|
||||
/** @var resource $resource */
|
||||
$resource = fopen('php://temp', 'r+');
|
||||
fwrite($resource, $content);
|
||||
|
||||
$instance = new self($resource);
|
||||
$instance->should_close_stream = true;
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the URI of the underlying stream.
|
||||
*
|
||||
* @see https://www.php.net/manual/en/splfileinfo.getpathname.php
|
||||
*/
|
||||
public function getPathname(): string
|
||||
{
|
||||
return stream_get_meta_data($this->stream)['uri'];
|
||||
}
|
||||
|
||||
/**
|
||||
* append a filter.
|
||||
*
|
||||
* @see http://php.net/manual/en/function.stream-filter-append.php
|
||||
*
|
||||
* @throws InvalidArgument if the filter can not be appended
|
||||
*/
|
||||
public function appendFilter(string $filtername, int $read_write, array $params = null): void
|
||||
{
|
||||
$res = @stream_filter_append($this->stream, $filtername, $read_write, $params ?? []);
|
||||
if (!is_resource($res)) {
|
||||
throw InvalidArgument::dueToStreamFilterNotFound($filtername);
|
||||
}
|
||||
|
||||
$this->filters[$filtername][] = $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set CSV control.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.setcsvcontrol.php
|
||||
*/
|
||||
public function setCsvControl(string $delimiter = ',', string $enclosure = '"', string $escape = '\\'): void
|
||||
{
|
||||
[$this->delimiter, $this->enclosure, $this->escape] = $this->filterControl($delimiter, $enclosure, $escape, __METHOD__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter Csv control characters.
|
||||
*
|
||||
* @throws InvalidArgument If the Csv control character is not one character only.
|
||||
*/
|
||||
private function filterControl(string $delimiter, string $enclosure, string $escape, string $caller): array
|
||||
{
|
||||
if (1 !== strlen($delimiter)) {
|
||||
throw InvalidArgument::dueToInvalidDelimiterCharacter($delimiter, $caller);
|
||||
}
|
||||
|
||||
if (1 !== strlen($enclosure)) {
|
||||
throw InvalidArgument::dueToInvalidEnclosureCharacter($enclosure, $caller);
|
||||
}
|
||||
|
||||
if (1 === strlen($escape) || ('' === $escape && 70400 <= PHP_VERSION_ID)) {
|
||||
return [$delimiter, $enclosure, $escape];
|
||||
}
|
||||
|
||||
throw InvalidArgument::dueToInvalidEscapeCharacter($escape, $caller);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set CSV control.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.getcsvcontrol.php
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
public function getCsvControl(): array
|
||||
{
|
||||
return [$this->delimiter, $this->enclosure, $this->escape];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set CSV stream flags.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.setflags.php
|
||||
*/
|
||||
public function setFlags(int $flags): void
|
||||
{
|
||||
$this->flags = $flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a field array as a CSV line.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.fputcsv.php
|
||||
*
|
||||
* @return int|false
|
||||
*/
|
||||
public function fputcsv(array $fields, string $delimiter = ',', string $enclosure = '"', string $escape = '\\', string $eol = "\n")
|
||||
{
|
||||
$controls = $this->filterControl($delimiter, $enclosure, $escape, __METHOD__);
|
||||
if (80100 <= PHP_VERSION_ID) {
|
||||
$controls[] = $eol;
|
||||
}
|
||||
|
||||
return fputcsv($this->stream, $fields, ...$controls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get line number.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.key.php
|
||||
*/
|
||||
public function key(): int
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read next line.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.next.php
|
||||
*/
|
||||
public function next(): void
|
||||
{
|
||||
$this->value = false;
|
||||
$this->offset++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewind the file to the first line.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.rewind.php
|
||||
*
|
||||
* @throws Exception if the stream resource is not seekable
|
||||
*/
|
||||
public function rewind(): void
|
||||
{
|
||||
if (!$this->is_seekable) {
|
||||
throw UnavailableFeature::dueToMissingStreamSeekability();
|
||||
}
|
||||
|
||||
rewind($this->stream);
|
||||
$this->offset = 0;
|
||||
$this->value = false;
|
||||
if (0 !== ($this->flags & SplFileObject::READ_AHEAD)) {
|
||||
$this->current();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Not at EOF.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.valid.php
|
||||
*/
|
||||
public function valid(): bool
|
||||
{
|
||||
if (0 !== ($this->flags & SplFileObject::READ_AHEAD)) {
|
||||
return $this->current() !== false;
|
||||
}
|
||||
|
||||
return !feof($this->stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current line of the file.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.current.php
|
||||
*
|
||||
* @return mixed The value of the current element.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function current()
|
||||
{
|
||||
if (false !== $this->value) {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
$this->value = $this->getCurrentRecord();
|
||||
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current line as a CSV Record.
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
private function getCurrentRecord()
|
||||
{
|
||||
$flag = 0 !== ($this->flags & SplFileObject::SKIP_EMPTY);
|
||||
do {
|
||||
$ret = fgetcsv($this->stream, 0, $this->delimiter, $this->enclosure, $this->escape);
|
||||
} while ($flag && is_array($ret) && null === $ret[0]);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Seek to specified line.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.seek.php
|
||||
*
|
||||
* @param int $position
|
||||
* @throws Exception if the position is negative
|
||||
*/
|
||||
public function seek($position): void
|
||||
{
|
||||
if ($position < 0) {
|
||||
throw InvalidArgument::dueToInvalidSeekingPosition($position, __METHOD__);
|
||||
}
|
||||
|
||||
$this->rewind();
|
||||
while ($this->key() !== $position && $this->valid()) {
|
||||
$this->current();
|
||||
$this->next();
|
||||
}
|
||||
|
||||
if (0 !== $position) {
|
||||
$this->offset--;
|
||||
}
|
||||
|
||||
$this->current();
|
||||
}
|
||||
|
||||
/**
|
||||
* Output all remaining data on a file pointer.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.fpatssthru.php
|
||||
*
|
||||
* @return int|false
|
||||
*/
|
||||
public function fpassthru()
|
||||
{
|
||||
return fpassthru($this->stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from file.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.fread.php
|
||||
*
|
||||
* @param int<0, max> $length The number of bytes to read
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
public function fread(int $length)
|
||||
{
|
||||
return fread($this->stream, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a line from file.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.fgets.php
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
public function fgets()
|
||||
{
|
||||
return fgets($this->stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Seek to a position.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.fseek.php
|
||||
*
|
||||
* @throws Exception if the stream resource is not seekable
|
||||
*/
|
||||
public function fseek(int $offset, int $whence = SEEK_SET): int
|
||||
{
|
||||
if (!$this->is_seekable) {
|
||||
throw UnavailableFeature::dueToMissingStreamSeekability();
|
||||
}
|
||||
|
||||
return fseek($this->stream, $offset, $whence);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to stream.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.fwrite.php
|
||||
*
|
||||
* @return int|false
|
||||
*/
|
||||
public function fwrite(string $str, int $length = null)
|
||||
{
|
||||
$args = [$this->stream, $str];
|
||||
if (null !== $length) {
|
||||
$args[] = $length;
|
||||
}
|
||||
|
||||
return fwrite(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the output to a file.
|
||||
*
|
||||
* @see http://php.net/manual/en/SplFileObject.fwrite.php
|
||||
*/
|
||||
public function fflush(): bool
|
||||
{
|
||||
return fflush($this->stream);
|
||||
}
|
||||
}
|
||||
60
pancake/system/vendor/league/csv/src/SyntaxError.php
vendored
Executable file
60
pancake/system/vendor/league/csv/src/SyntaxError.php
vendored
Executable file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* SyntaxError Exception.
|
||||
*/
|
||||
class SyntaxError extends Exception
|
||||
{
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected array $duplicateColumnNames = [];
|
||||
|
||||
/**
|
||||
* DEPRECATION WARNING! This class will be removed in the next major point release.
|
||||
*
|
||||
* @deprecated since version 9.7.0
|
||||
*/
|
||||
public function __construct(string $message = '', int $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
public static function dueToHeaderNotFound(int $offset): self
|
||||
{
|
||||
return new self('The header record does not exist or is empty at offset: `'.$offset.'`');
|
||||
}
|
||||
|
||||
public static function dueToInvalidHeaderColumnNames(): self
|
||||
{
|
||||
return new self('The header record contains non string colum names.');
|
||||
}
|
||||
|
||||
public static function dueToDuplicateHeaderColumnNames(array $header): self
|
||||
{
|
||||
$instance = new self('The header record contains duplicate column names.');
|
||||
$instance->duplicateColumnNames = array_keys(array_filter(array_count_values($header), fn (int $value): bool => $value > 1));
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
public function duplicateColumnNames(): array
|
||||
{
|
||||
return $this->duplicateColumnNames;
|
||||
}
|
||||
}
|
||||
117
pancake/system/vendor/league/csv/src/TabularDataReader.php
vendored
Executable file
117
pancake/system/vendor/league/csv/src/TabularDataReader.php
vendored
Executable file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use Countable;
|
||||
use Iterator;
|
||||
use IteratorAggregate;
|
||||
|
||||
/**
|
||||
* Represents a Tabular data.
|
||||
*
|
||||
* @method Iterator fetchColumnByName(string $name) returns a column from its name
|
||||
* @method Iterator fetchColumnByOffset(int $offset) returns a column from its offset
|
||||
*/
|
||||
interface TabularDataReader extends Countable, IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* Returns the number of records contained in the tabular data structure
|
||||
* excluding the header record.
|
||||
*/
|
||||
public function count(): int;
|
||||
|
||||
/**
|
||||
* Returns the tabular data records as an iterator object.
|
||||
*
|
||||
* Each record is represented as a simple array containing strings or null values.
|
||||
*
|
||||
* If the CSV document has a header record then each record is combined
|
||||
* to the header record and the header record is removed from the iterator.
|
||||
*
|
||||
* If the CSV document is inconsistent. Missing record fields are
|
||||
* filled with null values while extra record fields are strip from
|
||||
* the returned object.
|
||||
*/
|
||||
public function getIterator(): Iterator;
|
||||
|
||||
/**
|
||||
* Returns the header associated with the tabular data.
|
||||
*
|
||||
* The header must contains unique string or is an empty array
|
||||
* if no header was specified.
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
public function getHeader(): array;
|
||||
|
||||
/**
|
||||
* Returns the tabular data records as an iterator object.
|
||||
*
|
||||
* Each record is represented as a simple array containing strings or null values.
|
||||
*
|
||||
* If the tabular data has a header record then each record is combined
|
||||
* to the header record and the header record is removed from the iterator.
|
||||
*
|
||||
* If the tabular data is inconsistent. Missing record fields are
|
||||
* filled with null values while extra record fields are strip from
|
||||
* the returned object.
|
||||
*
|
||||
* @param array<string> $header an optional header to use instead of the CSV document header
|
||||
*/
|
||||
public function getRecords(array $header = []): Iterator;
|
||||
|
||||
/**
|
||||
* Returns the nth record from the tabular data.
|
||||
*
|
||||
* By default if no index is provided the first record of the tabular data is returned
|
||||
*
|
||||
* @param int $nth_record the tabular data record offset
|
||||
*
|
||||
* @throws UnableToProcessCsv if argument is lesser than 0
|
||||
*/
|
||||
public function fetchOne(int $nth_record = 0): array;
|
||||
|
||||
/**
|
||||
* DEPRECATION WARNING! This class will be removed in the next major point release.
|
||||
*
|
||||
* @deprecated since version 9.8.0
|
||||
*
|
||||
* @see ::fetchColumnByName
|
||||
* @see ::fetchColumnByOffset
|
||||
*
|
||||
* Returns a single column from the next record of the tabular data.
|
||||
*
|
||||
* By default if no value is supplied the first column is fetch
|
||||
*
|
||||
* @param string|int $index CSV column index
|
||||
*
|
||||
* @throws UnableToProcessCsv if the column index is invalid or not found
|
||||
*/
|
||||
public function fetchColumn($index = 0): Iterator;
|
||||
|
||||
/**
|
||||
* Returns the next key-value pairs from the tabular data (first
|
||||
* column is the key, second column is the value).
|
||||
*
|
||||
* By default if no column index is provided:
|
||||
* - the first column is used to provide the keys
|
||||
* - the second column is used to provide the value
|
||||
*
|
||||
* @param string|int $offset_index The column index to serve as offset
|
||||
* @param string|int $value_index The column index to serve as value
|
||||
*
|
||||
* @throws UnableToProcessCsv if the column index is invalid or not found
|
||||
*/
|
||||
public function fetchPairs($offset_index = 0, $value_index = 1): Iterator;
|
||||
}
|
||||
20
pancake/system/vendor/league/csv/src/UnableToProcessCsv.php
vendored
Executable file
20
pancake/system/vendor/league/csv/src/UnableToProcessCsv.php
vendored
Executable file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use Throwable;
|
||||
|
||||
interface UnableToProcessCsv extends Throwable
|
||||
{
|
||||
}
|
||||
42
pancake/system/vendor/league/csv/src/UnavailableFeature.php
vendored
Executable file
42
pancake/system/vendor/league/csv/src/UnavailableFeature.php
vendored
Executable file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* StreamFilterSupportMissing Exception.
|
||||
*/
|
||||
class UnavailableFeature extends Exception
|
||||
{
|
||||
/**
|
||||
* DEPRECATION WARNING! This class will be removed in the next major point release.
|
||||
*
|
||||
* @deprecated since version 9.7.0
|
||||
*/
|
||||
public function __construct(string $message = '', int $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
public static function dueToUnsupportedStreamFilterApi(string $className): self
|
||||
{
|
||||
return new self('The stream filter API can not be used with a '.$className.' instance.');
|
||||
}
|
||||
|
||||
public static function dueToMissingStreamSeekability(): self
|
||||
{
|
||||
return new self('stream does not support seeking');
|
||||
}
|
||||
}
|
||||
32
pancake/system/vendor/league/csv/src/UnavailableStream.php
vendored
Executable file
32
pancake/system/vendor/league/csv/src/UnavailableStream.php
vendored
Executable file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
final class UnavailableStream extends Exception
|
||||
{
|
||||
private function __construct(string $message)
|
||||
{
|
||||
parent::__construct($message);
|
||||
}
|
||||
|
||||
public static function dueToPathNotFound(string $path): self
|
||||
{
|
||||
return new self('`'.$path.'`: failed to open stream: No such file or directory.');
|
||||
}
|
||||
|
||||
public static function dueToForbiddenCloning(string $class_name): self
|
||||
{
|
||||
return new self('An object of class '.$class_name.' cannot be cloned.');
|
||||
}
|
||||
}
|
||||
222
pancake/system/vendor/league/csv/src/Writer.php
vendored
Executable file
222
pancake/system/vendor/league/csv/src/Writer.php
vendored
Executable file
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use function array_reduce;
|
||||
use function strlen;
|
||||
use const PHP_VERSION_ID;
|
||||
use const SEEK_CUR;
|
||||
use const STREAM_FILTER_WRITE;
|
||||
|
||||
/**
|
||||
* A class to insert records into a CSV Document.
|
||||
*/
|
||||
class Writer extends AbstractCsv
|
||||
{
|
||||
protected const STREAM_FILTER_MODE = STREAM_FILTER_WRITE;
|
||||
|
||||
/** @var array<callable> callable collection to format the record before insertion. */
|
||||
protected array $formatters = [];
|
||||
/** @var array<callable> callable collection to validate the record before insertion. */
|
||||
protected array $validators = [];
|
||||
protected string $newline = "\n";
|
||||
protected int $flush_counter = 0;
|
||||
protected ?int $flush_threshold = null;
|
||||
|
||||
protected function resetProperties(): void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current newline sequence characters.
|
||||
*/
|
||||
public function getNewline(): string
|
||||
{
|
||||
return $this->newline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the flush threshold.
|
||||
*/
|
||||
public function getFlushThreshold(): ?int
|
||||
{
|
||||
return $this->flush_threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds multiple records to the CSV document.
|
||||
*
|
||||
* @see Writer::insertOne
|
||||
*/
|
||||
public function insertAll(iterable $records): int
|
||||
{
|
||||
$bytes = 0;
|
||||
foreach ($records as $record) {
|
||||
$bytes += $this->insertOne($record);
|
||||
}
|
||||
|
||||
$this->flush_counter = 0;
|
||||
$this->document->fflush();
|
||||
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a single record to a CSV document.
|
||||
*
|
||||
* A record is an array that can contains scalar types values, NULL values
|
||||
* or objects implementing the __toString method.
|
||||
*
|
||||
* @throws CannotInsertRecord If the record can not be inserted
|
||||
*/
|
||||
public function insertOne(array $record): int
|
||||
{
|
||||
$record = array_reduce($this->formatters, fn (array $record, callable $formatter): array => $formatter($record), $record);
|
||||
$this->validateRecord($record);
|
||||
$bytes = $this->addRecord($record);
|
||||
if (false === $bytes || 0 >= $bytes) {
|
||||
throw CannotInsertRecord::triggerOnInsertion($record);
|
||||
}
|
||||
|
||||
return $bytes + $this->consolidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a single record to a CSV Document using PHP algorithm.
|
||||
*
|
||||
* @see https://php.net/manual/en/function.fputcsv.php
|
||||
*
|
||||
* @return int|false
|
||||
*/
|
||||
protected function addRecord(array $record)
|
||||
{
|
||||
if (PHP_VERSION_ID < 80100) {
|
||||
return $this->document->fputcsv($record, $this->delimiter, $this->enclosure, $this->escape);
|
||||
}
|
||||
|
||||
return $this->document->fputcsv($record, $this->delimiter, $this->enclosure, $this->escape, $this->newline);
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATION WARNING! This method will be removed in the next major point release.
|
||||
*
|
||||
* @deprecated since version 9.8.0
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Format a record.
|
||||
*
|
||||
* The returned array must contain
|
||||
* - scalar types values,
|
||||
* - NULL values,
|
||||
* - or objects implementing the __toString() method.
|
||||
*/
|
||||
protected function formatRecord(array $record, callable $formatter): array
|
||||
{
|
||||
return $formatter($record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a record.
|
||||
*
|
||||
* @throws CannotInsertRecord If the validation failed
|
||||
*/
|
||||
protected function validateRecord(array $record): void
|
||||
{
|
||||
foreach ($this->validators as $name => $validator) {
|
||||
if (true !== $validator($record)) {
|
||||
throw CannotInsertRecord::triggerOnValidation($name, $record);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply post insertion actions.
|
||||
*/
|
||||
protected function consolidate(): int
|
||||
{
|
||||
$bytes = 0;
|
||||
if (80100 > PHP_VERSION_ID && "\n" !== $this->newline) {
|
||||
$this->document->fseek(-1, SEEK_CUR);
|
||||
/** @var int $newlineBytes */
|
||||
$newlineBytes = $this->document->fwrite($this->newline, strlen($this->newline));
|
||||
$bytes = $newlineBytes - 1;
|
||||
}
|
||||
|
||||
if (null === $this->flush_threshold) {
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
++$this->flush_counter;
|
||||
if (0 === $this->flush_counter % $this->flush_threshold) {
|
||||
$this->flush_counter = 0;
|
||||
$this->document->fflush();
|
||||
}
|
||||
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a record formatter.
|
||||
*/
|
||||
public function addFormatter(callable $formatter): self
|
||||
{
|
||||
$this->formatters[] = $formatter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a record validator.
|
||||
*/
|
||||
public function addValidator(callable $validator, string $validator_name): self
|
||||
{
|
||||
$this->validators[$validator_name] = $validator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the newline sequence.
|
||||
*/
|
||||
public function setNewline(string $newline): self
|
||||
{
|
||||
$this->newline = $newline;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the flush threshold.
|
||||
*
|
||||
* @param ?int $threshold
|
||||
*
|
||||
* @throws InvalidArgument if the threshold is a integer lesser than 1
|
||||
*/
|
||||
public function setFlushThreshold(?int $threshold): self
|
||||
{
|
||||
if ($threshold === $this->flush_threshold) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (null !== $threshold && 1 > $threshold) {
|
||||
throw InvalidArgument::dueToInvalidThreshold($threshold, __METHOD__);
|
||||
}
|
||||
|
||||
$this->flush_threshold = $threshold;
|
||||
$this->flush_counter = 0;
|
||||
$this->document->fflush();
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
193
pancake/system/vendor/league/csv/src/XMLConverter.php
vendored
Executable file
193
pancake/system/vendor/league/csv/src/XMLConverter.php
vendored
Executable file
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
use DOMAttr;
|
||||
use DOMDocument;
|
||||
use DOMElement;
|
||||
use DOMException;
|
||||
|
||||
/**
|
||||
* Converts tabular data into a DOMDocument object.
|
||||
*/
|
||||
class XMLConverter
|
||||
{
|
||||
/**
|
||||
* XML Root name.
|
||||
*/
|
||||
protected string $root_name = 'csv';
|
||||
|
||||
/**
|
||||
* XML Node name.
|
||||
*/
|
||||
protected string $record_name = 'row';
|
||||
|
||||
/**
|
||||
* XML Item name.
|
||||
*/
|
||||
protected string $field_name = 'cell';
|
||||
|
||||
/**
|
||||
* XML column attribute name.
|
||||
*/
|
||||
protected string $column_attr = '';
|
||||
|
||||
/**
|
||||
* XML offset attribute name.
|
||||
*/
|
||||
protected string $offset_attr = '';
|
||||
|
||||
public static function create(): self
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATION WARNING! This method will be removed in the next major point release.
|
||||
*
|
||||
* @deprecated since version 9.7.0
|
||||
* @see XMLConverter::create()
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a Record collection into a DOMDocument.
|
||||
*/
|
||||
public function convert(iterable $records): DOMDocument
|
||||
{
|
||||
$doc = new DOMDocument('1.0');
|
||||
$node = $this->import($records, $doc);
|
||||
$doc->appendChild($node);
|
||||
|
||||
return $doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new DOMElement related to the given DOMDocument.
|
||||
*
|
||||
* **DOES NOT** attach to the DOMDocument
|
||||
*/
|
||||
public function import(iterable $records, DOMDocument $doc): DOMElement
|
||||
{
|
||||
$root = $doc->createElement($this->root_name);
|
||||
foreach ($records as $offset => $record) {
|
||||
$node = $this->recordToElement($doc, $record, $offset);
|
||||
$root->appendChild($node);
|
||||
}
|
||||
|
||||
return $root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CSV record into a DOMElement and
|
||||
* adds its offset as DOMElement attribute.
|
||||
*/
|
||||
protected function recordToElement(DOMDocument $doc, array $record, int $offset): DOMElement
|
||||
{
|
||||
$node = $doc->createElement($this->record_name);
|
||||
foreach ($record as $node_name => $value) {
|
||||
$item = $this->fieldToElement($doc, (string) $value, $node_name);
|
||||
$node->appendChild($item);
|
||||
}
|
||||
|
||||
if ('' !== $this->offset_attr) {
|
||||
$node->setAttribute($this->offset_attr, (string) $offset);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Cell to Item.
|
||||
*
|
||||
* Convert the CSV item into a DOMElement and adds the item offset
|
||||
* as attribute to the returned DOMElement
|
||||
*
|
||||
* @param int|string $node_name
|
||||
*/
|
||||
protected function fieldToElement(DOMDocument $doc, string $value, $node_name): DOMElement
|
||||
{
|
||||
$item = $doc->createElement($this->field_name);
|
||||
$item->appendChild($doc->createTextNode($value));
|
||||
|
||||
if ('' !== $this->column_attr) {
|
||||
$item->setAttribute($this->column_attr, (string) $node_name);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* XML root element setter.
|
||||
*/
|
||||
public function rootElement(string $node_name): self
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->root_name = $this->filterElementName($node_name);
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter XML element name.
|
||||
*
|
||||
* @throws DOMException If the Element name is invalid
|
||||
*/
|
||||
protected function filterElementName(string $value): string
|
||||
{
|
||||
return (new DOMElement($value))->tagName;
|
||||
}
|
||||
|
||||
/**
|
||||
* XML Record element setter.
|
||||
*/
|
||||
public function recordElement(string $node_name, string $record_offset_attribute_name = ''): self
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->record_name = $this->filterElementName($node_name);
|
||||
$clone->offset_attr = $this->filterAttributeName($record_offset_attribute_name);
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter XML attribute name.
|
||||
*
|
||||
* @param string $value Element name
|
||||
*
|
||||
* @throws DOMException If the Element attribute name is invalid
|
||||
*/
|
||||
protected function filterAttributeName(string $value): string
|
||||
{
|
||||
if ('' === $value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return (new DOMAttr($value))->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* XML Field element setter.
|
||||
*/
|
||||
public function fieldElement(string $node_name, string $fieldname_attribute_name = ''): self
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->field_name = $this->filterElementName($node_name);
|
||||
$clone->column_attr = $this->filterAttributeName($fieldname_attribute_name);
|
||||
|
||||
return $clone;
|
||||
}
|
||||
}
|
||||
48
pancake/system/vendor/league/csv/src/functions.php
vendored
Executable file
48
pancake/system/vendor/league/csv/src/functions.php
vendored
Executable file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\Csv;
|
||||
|
||||
/**
|
||||
* DEPRECATION WARNING! This class will be removed in the next major point release.
|
||||
*
|
||||
* @deprecated since version 9.7.0
|
||||
* @see Info::fetchBOMSequence()
|
||||
*
|
||||
* Returns the BOM sequence found at the start of the string.
|
||||
*
|
||||
* If no valid BOM sequence is found an empty string is returned
|
||||
*/
|
||||
function bom_match(string $str): string
|
||||
{
|
||||
return Info::fetchBOMSequence($str) ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string> $delimiters
|
||||
*
|
||||
* @return array<string,int>
|
||||
* @deprecated since version 9.7.0
|
||||
* @see Info::getDelimiterStats()
|
||||
*
|
||||
* Detect Delimiters usage in a {@link Reader} object.
|
||||
*
|
||||
* Returns a associative array where each key represents
|
||||
* a submitted delimiter and each value the number CSV fields found
|
||||
* when processing at most $limit CSV records with the given delimiter
|
||||
*
|
||||
*/
|
||||
function delimiter_detect(Reader $csv, array $delimiters, int $limit = 1): array
|
||||
{
|
||||
return Info::getDelimiterStats($csv, $delimiters, $limit);
|
||||
}
|
||||
14
pancake/system/vendor/league/csv/src/functions_include.php
vendored
Executable file
14
pancake/system/vendor/league/csv/src/functions_include.php
vendored
Executable file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* League.Csv (https://csv.thephpleague.com)
|
||||
*
|
||||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
if (!function_exists('League\Csv\bom_match')) {
|
||||
require __DIR__.'/functions.php';
|
||||
}
|
||||
19
pancake/system/vendor/league/event/LICENSE
vendored
Executable file
19
pancake/system/vendor/league/event/LICENSE
vendored
Executable file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2014 Frank de Jonge
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
37
pancake/system/vendor/league/event/composer.json
vendored
Executable file
37
pancake/system/vendor/league/event/composer.json
vendored
Executable file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "league/event",
|
||||
"description": "Event package",
|
||||
"keywords": ["event", "emitter", "listener"],
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Frank de Jonge",
|
||||
"email": "info@frenky.net"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"henrikbjorn/phpspec-code-coverage": "~1.0.1",
|
||||
"phpspec/phpspec": "^2.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Event\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"League\\Event\\Stub\\": "stubs/"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"bin-dir": "bin"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.2-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
64
pancake/system/vendor/league/event/src/AbstractEvent.php
vendored
Executable file
64
pancake/system/vendor/league/event/src/AbstractEvent.php
vendored
Executable file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
abstract class AbstractEvent implements EventInterface
|
||||
{
|
||||
/**
|
||||
* Has propagation stopped?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $propagationStopped = false;
|
||||
|
||||
/**
|
||||
* The emitter instance.
|
||||
*
|
||||
* @var EmitterInterface|null
|
||||
*/
|
||||
protected $emitter;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setEmitter(EmitterInterface $emitter)
|
||||
{
|
||||
$this->emitter = $emitter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getEmitter()
|
||||
{
|
||||
return $this->emitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function stopPropagation()
|
||||
{
|
||||
$this->propagationStopped = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function isPropagationStopped()
|
||||
{
|
||||
return $this->propagationStopped;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return get_class($this);
|
||||
}
|
||||
}
|
||||
14
pancake/system/vendor/league/event/src/AbstractListener.php
vendored
Executable file
14
pancake/system/vendor/league/event/src/AbstractListener.php
vendored
Executable file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
abstract class AbstractListener implements ListenerInterface
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function isListener($listener)
|
||||
{
|
||||
return $this === $listener;
|
||||
}
|
||||
}
|
||||
49
pancake/system/vendor/league/event/src/BufferedEmitter.php
vendored
Executable file
49
pancake/system/vendor/league/event/src/BufferedEmitter.php
vendored
Executable file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
class BufferedEmitter extends Emitter
|
||||
{
|
||||
/**
|
||||
* @var EventInterface[]
|
||||
*/
|
||||
protected $bufferedEvents = [];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function emit($event)
|
||||
{
|
||||
$this->bufferedEvents[] = $event;
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function emitBatch(array $events)
|
||||
{
|
||||
foreach ($events as $event) {
|
||||
$this->bufferedEvents[] = $event;
|
||||
}
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit the buffered events.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function emitBufferedEvents()
|
||||
{
|
||||
$result = [];
|
||||
|
||||
while ($event = array_shift($this->bufferedEvents)) {
|
||||
$result[] = parent::emit($event);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
65
pancake/system/vendor/league/event/src/CallbackListener.php
vendored
Executable file
65
pancake/system/vendor/league/event/src/CallbackListener.php
vendored
Executable file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
class CallbackListener implements ListenerInterface
|
||||
{
|
||||
/**
|
||||
* The callback.
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
protected $callback;
|
||||
|
||||
/**
|
||||
* Create a new callback listener instance.
|
||||
*
|
||||
* @param callable $callback
|
||||
*/
|
||||
public function __construct(callable $callback)
|
||||
{
|
||||
$this->callback = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the callback.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public function getCallback()
|
||||
{
|
||||
return $this->callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function handle(EventInterface $event)
|
||||
{
|
||||
call_user_func_array($this->callback, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function isListener($listener)
|
||||
{
|
||||
if ($listener instanceof CallbackListener) {
|
||||
$listener = $listener->getCallback();
|
||||
}
|
||||
|
||||
return $this->callback === $listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Named constructor
|
||||
*
|
||||
* @param callable $callable
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function fromCallable(callable $callable)
|
||||
{
|
||||
return new static($callable);
|
||||
}
|
||||
}
|
||||
268
pancake/system/vendor/league/event/src/Emitter.php
vendored
Executable file
268
pancake/system/vendor/league/event/src/Emitter.php
vendored
Executable file
@@ -0,0 +1,268 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
class Emitter implements EmitterInterface
|
||||
{
|
||||
/**
|
||||
* The registered listeners.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $listeners = [];
|
||||
|
||||
/**
|
||||
* The sorted listeners
|
||||
*
|
||||
* Listeners will get sorted and stored for re-use.
|
||||
*
|
||||
* @var ListenerInterface[]
|
||||
*/
|
||||
protected $sortedListeners = [];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function addListener($event, $listener, $priority = self::P_NORMAL)
|
||||
{
|
||||
$listener = $this->ensureListener($listener);
|
||||
$this->listeners[$event][$priority][] = $listener;
|
||||
$this->clearSortedListeners($event);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function addOneTimeListener($event, $listener, $priority = self::P_NORMAL)
|
||||
{
|
||||
$listener = $this->ensureListener($listener);
|
||||
$listener = new OneTimeListener($listener);
|
||||
|
||||
return $this->addListener($event, $listener, $priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function useListenerProvider(ListenerProviderInterface $provider)
|
||||
{
|
||||
$acceptor = new ListenerAcceptor($this);
|
||||
$provider->provideListeners($acceptor);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function removeListener($event, $listener)
|
||||
{
|
||||
$this->clearSortedListeners($event);
|
||||
$listeners = $this->hasListeners($event)
|
||||
? $this->listeners[$event]
|
||||
: [];
|
||||
|
||||
$filter = function ($registered) use ($listener) {
|
||||
return ! $registered->isListener($listener);
|
||||
};
|
||||
|
||||
foreach ($listeners as $priority => $collection) {
|
||||
$listeners[$priority] = array_filter($collection, $filter);
|
||||
}
|
||||
|
||||
$this->listeners[$event] = $listeners;
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function removeAllListeners($event)
|
||||
{
|
||||
$this->clearSortedListeners($event);
|
||||
|
||||
if ($this->hasListeners($event)) {
|
||||
unset($this->listeners[$event]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the input is a listener.
|
||||
*
|
||||
* @param ListenerInterface|callable $listener
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return ListenerInterface
|
||||
*/
|
||||
protected function ensureListener($listener)
|
||||
{
|
||||
if ($listener instanceof ListenerInterface) {
|
||||
return $listener;
|
||||
}
|
||||
|
||||
if (is_callable($listener)) {
|
||||
return CallbackListener::fromCallable($listener);
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException('Listeners should be ListenerInterface, Closure or callable. Received type: '.gettype($listener));
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function hasListeners($event)
|
||||
{
|
||||
if (! isset($this->listeners[$event]) || count($this->listeners[$event]) === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getListeners($event)
|
||||
{
|
||||
if (array_key_exists($event, $this->sortedListeners)) {
|
||||
return $this->sortedListeners[$event];
|
||||
}
|
||||
|
||||
return $this->sortedListeners[$event] = $this->getSortedListeners($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the listeners sorted by priority for a given event.
|
||||
*
|
||||
* @param string $event
|
||||
*
|
||||
* @return ListenerInterface[]
|
||||
*/
|
||||
protected function getSortedListeners($event)
|
||||
{
|
||||
if (! $this->hasListeners($event)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$listeners = $this->listeners[$event];
|
||||
krsort($listeners);
|
||||
|
||||
return call_user_func_array('array_merge', $listeners);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function emit($event)
|
||||
{
|
||||
list($name, $event) = $this->prepareEvent($event);
|
||||
$arguments = [$event] + func_get_args();
|
||||
$this->invokeListeners($name, $event, $arguments);
|
||||
$this->invokeListeners('*', $event, $arguments);
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function emitBatch(array $events)
|
||||
{
|
||||
$results = [];
|
||||
|
||||
foreach ($events as $event) {
|
||||
$results[] = $this->emit($event);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function emitGeneratedEvents(GeneratorInterface $generator)
|
||||
{
|
||||
$events = $generator->releaseEvents();
|
||||
|
||||
return $this->emitBatch($events);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the listeners for an event.
|
||||
*
|
||||
* @param string $name
|
||||
* @param EventInterface $event
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function invokeListeners($name, EventInterface $event, array $arguments)
|
||||
{
|
||||
$listeners = $this->getListeners($name);
|
||||
|
||||
foreach ($listeners as $listener) {
|
||||
if ($event->isPropagationStopped()) {
|
||||
break;
|
||||
}
|
||||
|
||||
call_user_func_array([$listener, 'handle'], $arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare an event for emitting.
|
||||
*
|
||||
* @param string|EventInterface $event
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareEvent($event)
|
||||
{
|
||||
$event = $this->ensureEvent($event);
|
||||
$name = $event->getName();
|
||||
$event->setEmitter($this);
|
||||
|
||||
return [$name, $event];
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure event input is of type EventInterface or convert it.
|
||||
*
|
||||
* @param string|EventInterface $event
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return EventInterface
|
||||
*/
|
||||
protected function ensureEvent($event)
|
||||
{
|
||||
if (is_string($event)) {
|
||||
return Event::named($event);
|
||||
}
|
||||
|
||||
if (! $event instanceof EventInterface) {
|
||||
throw new InvalidArgumentException('Events should be provides as Event instances or string, received type: '.gettype($event));
|
||||
}
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the sorted listeners for an event
|
||||
*
|
||||
* @param $event
|
||||
*/
|
||||
protected function clearSortedListeners($event)
|
||||
{
|
||||
unset($this->sortedListeners[$event]);
|
||||
}
|
||||
}
|
||||
22
pancake/system/vendor/league/event/src/EmitterAwareInterface.php
vendored
Executable file
22
pancake/system/vendor/league/event/src/EmitterAwareInterface.php
vendored
Executable file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
interface EmitterAwareInterface
|
||||
{
|
||||
/**
|
||||
* Set the Emitter.
|
||||
*
|
||||
* @param EmitterInterface $emitter
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEmitter(EmitterInterface $emitter = null);
|
||||
|
||||
/**
|
||||
* Get the Emitter.
|
||||
*
|
||||
* @return EmitterInterface
|
||||
*/
|
||||
public function getEmitter();
|
||||
}
|
||||
41
pancake/system/vendor/league/event/src/EmitterAwareTrait.php
vendored
Executable file
41
pancake/system/vendor/league/event/src/EmitterAwareTrait.php
vendored
Executable file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
trait EmitterAwareTrait
|
||||
{
|
||||
/**
|
||||
* The emitter instance.
|
||||
*
|
||||
* @var EmitterInterface|null
|
||||
*/
|
||||
protected $emitter;
|
||||
|
||||
/**
|
||||
* Set the Emitter.
|
||||
*
|
||||
* @param EmitterInterface|null $emitter
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEmitter(EmitterInterface $emitter = null)
|
||||
{
|
||||
$this->emitter = $emitter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Emitter.
|
||||
*
|
||||
* @return EmitterInterface
|
||||
*/
|
||||
public function getEmitter()
|
||||
{
|
||||
if (! $this->emitter) {
|
||||
$this->emitter = new Emitter();
|
||||
}
|
||||
|
||||
return $this->emitter;
|
||||
}
|
||||
}
|
||||
92
pancake/system/vendor/league/event/src/EmitterInterface.php
vendored
Executable file
92
pancake/system/vendor/league/event/src/EmitterInterface.php
vendored
Executable file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
interface EmitterInterface extends ListenerAcceptorInterface
|
||||
{
|
||||
/**
|
||||
* Remove a specific listener for an event.
|
||||
*
|
||||
* The first parameter should be the event name, and the second should be
|
||||
* the event listener. It may implement the League\Event\ListenerInterface
|
||||
* or simply be "callable".
|
||||
*
|
||||
* @param string $event
|
||||
* @param ListenerInterface|callable $listener
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function removeListener($event, $listener);
|
||||
|
||||
/**
|
||||
* Use a provider to add listeners.
|
||||
*
|
||||
* @param ListenerProviderInterface $provider
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function useListenerProvider(ListenerProviderInterface $provider);
|
||||
|
||||
/**
|
||||
* Remove all listeners for an event.
|
||||
*
|
||||
* The first parameter should be the event name. All event listeners will
|
||||
* be removed.
|
||||
*
|
||||
* @param string $event
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function removeAllListeners($event);
|
||||
|
||||
/**
|
||||
* Check whether an event has listeners.
|
||||
*
|
||||
* The first parameter should be the event name. We'll return true if the
|
||||
* event has one or more registered even listeners, and false otherwise.
|
||||
*
|
||||
* @param string $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasListeners($event);
|
||||
|
||||
/**
|
||||
* Get all the listeners for an event.
|
||||
*
|
||||
* The first parameter should be the event name. We'll return an array of
|
||||
* all the registered even listeners, or an empty array if there are none.
|
||||
*
|
||||
* @param string $event
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getListeners($event);
|
||||
|
||||
/**
|
||||
* Emit an event.
|
||||
*
|
||||
* @param string|EventInterface $event
|
||||
*
|
||||
* @return EventInterface
|
||||
*/
|
||||
public function emit($event);
|
||||
|
||||
/**
|
||||
* Emit a batch of events.
|
||||
*
|
||||
* @param array $events
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function emitBatch(array $events);
|
||||
|
||||
/**
|
||||
* Release all events stored in a generator
|
||||
*
|
||||
* @param GeneratorInterface $generator
|
||||
*
|
||||
* @return EventInterface[]
|
||||
*/
|
||||
public function emitGeneratedEvents(GeneratorInterface $generator);
|
||||
}
|
||||
113
pancake/system/vendor/league/event/src/EmitterTrait.php
vendored
Executable file
113
pancake/system/vendor/league/event/src/EmitterTrait.php
vendored
Executable file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
trait EmitterTrait
|
||||
{
|
||||
use EmitterAwareTrait;
|
||||
|
||||
/**
|
||||
* Add a listener for an event.
|
||||
*
|
||||
* The first parameter should be the event name, and the second should be
|
||||
* the event listener. It may implement the League\Event\ListenerInterface
|
||||
* or simply be "callable".
|
||||
*
|
||||
* @param string $event
|
||||
* @param ListenerInterface|callable $listener
|
||||
* @param int $priority
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addListener($event, $listener, $priority = ListenerAcceptorInterface::P_NORMAL)
|
||||
{
|
||||
$this->getEmitter()->addListener($event, $listener, $priority);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a one time listener for an event.
|
||||
*
|
||||
* The first parameter should be the event name, and the second should be
|
||||
* the event listener. It may implement the League\Event\ListenerInterface
|
||||
* or simply be "callable".
|
||||
*
|
||||
* @param string $event
|
||||
* @param ListenerInterface|callable $listener
|
||||
* @param int $priority
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addOneTimeListener($event, $listener, $priority = ListenerAcceptorInterface::P_NORMAL)
|
||||
{
|
||||
$this->getEmitter()->addOneTimeListener($event, $listener, $priority);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a specific listener for an event.
|
||||
*
|
||||
* The first parameter should be the event name, and the second should be
|
||||
* the event listener. It may implement the League\Event\ListenerInterface
|
||||
* or simply be "callable".
|
||||
*
|
||||
* @param string $event
|
||||
* @param ListenerInterface|callable $listener
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function removeListener($event, $listener)
|
||||
{
|
||||
$this->getEmitter()->removeListener($event, $listener);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all listeners for an event.
|
||||
*
|
||||
* The first parameter should be the event name. All event listeners will
|
||||
* be removed.
|
||||
*
|
||||
* @param string $event
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function removeAllListeners($event)
|
||||
{
|
||||
$this->getEmitter()->removeAllListeners($event);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add listeners from a provider.
|
||||
*
|
||||
* @param ListenerProviderInterface $provider
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function useListenerProvider(ListenerProviderInterface $provider)
|
||||
{
|
||||
$this->getEmitter()->useListenerProvider($provider);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit an event.
|
||||
*
|
||||
* @param string|EventInterface $event
|
||||
*
|
||||
* @return EventInterface
|
||||
*/
|
||||
public function emit($event)
|
||||
{
|
||||
$emitter = $this->getEmitter();
|
||||
$arguments = [$event] + func_get_args();
|
||||
|
||||
return call_user_func_array([$emitter, 'emit'], $arguments);
|
||||
}
|
||||
}
|
||||
43
pancake/system/vendor/league/event/src/Event.php
vendored
Executable file
43
pancake/system/vendor/league/event/src/Event.php
vendored
Executable file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
class Event extends AbstractEvent
|
||||
{
|
||||
/**
|
||||
* The event name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function named($name)
|
||||
{
|
||||
return new static($name);
|
||||
}
|
||||
}
|
||||
43
pancake/system/vendor/league/event/src/EventInterface.php
vendored
Executable file
43
pancake/system/vendor/league/event/src/EventInterface.php
vendored
Executable file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
interface EventInterface
|
||||
{
|
||||
/**
|
||||
* Set the Emitter.
|
||||
*
|
||||
* @param EmitterInterface $emitter
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEmitter(EmitterInterface $emitter);
|
||||
|
||||
/**
|
||||
* Get the Emitter.
|
||||
*
|
||||
* @return EmitterInterface
|
||||
*/
|
||||
public function getEmitter();
|
||||
|
||||
/**
|
||||
* Stop event propagation.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function stopPropagation();
|
||||
|
||||
/**
|
||||
* Check whether propagation was stopped.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPropagationStopped();
|
||||
|
||||
/**
|
||||
* Get the event name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
}
|
||||
10
pancake/system/vendor/league/event/src/Generator.php
vendored
Executable file
10
pancake/system/vendor/league/event/src/Generator.php
vendored
Executable file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
class Generator implements GeneratorInterface
|
||||
{
|
||||
use GeneratorTrait {
|
||||
addEvent as public;
|
||||
}
|
||||
}
|
||||
13
pancake/system/vendor/league/event/src/GeneratorInterface.php
vendored
Executable file
13
pancake/system/vendor/league/event/src/GeneratorInterface.php
vendored
Executable file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
interface GeneratorInterface
|
||||
{
|
||||
/**
|
||||
* Release all the added events.
|
||||
*
|
||||
* @return EventInterface[]
|
||||
*/
|
||||
public function releaseEvents();
|
||||
}
|
||||
40
pancake/system/vendor/league/event/src/GeneratorTrait.php
vendored
Executable file
40
pancake/system/vendor/league/event/src/GeneratorTrait.php
vendored
Executable file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
trait GeneratorTrait
|
||||
{
|
||||
/**
|
||||
* The registered events.
|
||||
*
|
||||
* @var EventInterface[]
|
||||
*/
|
||||
protected $events = [];
|
||||
|
||||
/**
|
||||
* Add an event.
|
||||
*
|
||||
* @param EventInterface $event
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function addEvent(EventInterface $event)
|
||||
{
|
||||
$this->events[] = $event;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release all the added events.
|
||||
*
|
||||
* @return EventInterface[]
|
||||
*/
|
||||
public function releaseEvents()
|
||||
{
|
||||
$events = $this->events;
|
||||
$this->events = [];
|
||||
|
||||
return $events;
|
||||
}
|
||||
}
|
||||
43
pancake/system/vendor/league/event/src/ListenerAcceptor.php
vendored
Executable file
43
pancake/system/vendor/league/event/src/ListenerAcceptor.php
vendored
Executable file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
class ListenerAcceptor implements ListenerAcceptorInterface
|
||||
{
|
||||
/**
|
||||
* The emitter instance.
|
||||
*
|
||||
* @var EmitterInterface|null
|
||||
*/
|
||||
protected $emitter;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param EmitterInterface $emitter
|
||||
*/
|
||||
public function __construct(EmitterInterface $emitter)
|
||||
{
|
||||
$this->emitter = $emitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function addListener($event, $listener, $priority = self::P_NORMAL)
|
||||
{
|
||||
$this->emitter->addListener($event, $listener, $priority);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function addOneTimeListener($event, $listener, $priority = self::P_NORMAL)
|
||||
{
|
||||
$this->emitter->addOneTimeListener($event, $listener, $priority);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
59
pancake/system/vendor/league/event/src/ListenerAcceptorInterface.php
vendored
Executable file
59
pancake/system/vendor/league/event/src/ListenerAcceptorInterface.php
vendored
Executable file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
interface ListenerAcceptorInterface
|
||||
{
|
||||
/**
|
||||
* High priority.
|
||||
*
|
||||
* @const int
|
||||
*/
|
||||
const P_HIGH = 100;
|
||||
|
||||
/**
|
||||
* Normal priority.
|
||||
*
|
||||
* @const int
|
||||
*/
|
||||
const P_NORMAL = 0;
|
||||
|
||||
/**
|
||||
* Low priority.
|
||||
*
|
||||
* @const int
|
||||
*/
|
||||
const P_LOW = -100;
|
||||
|
||||
/**
|
||||
* Add a listener for an event.
|
||||
*
|
||||
* The first parameter should be the event name, and the second should be
|
||||
* the event listener. It may implement the League\Event\ListenerInterface
|
||||
* or simply be "callable". In this case, the priority emitter also accepts
|
||||
* an optional third parameter specifying the priority as an integer. You
|
||||
* may use one of our predefined constants here if you want.
|
||||
*
|
||||
* @param string $event
|
||||
* @param ListenerInterface|callable $listener
|
||||
* @param int $priority
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addListener($event, $listener, $priority = self::P_NORMAL);
|
||||
|
||||
/**
|
||||
* Add a one time listener for an event.
|
||||
*
|
||||
* The first parameter should be the event name, and the second should be
|
||||
* the event listener. It may implement the League\Event\ListenerInterface
|
||||
* or simply be "callable".
|
||||
*
|
||||
* @param string $event
|
||||
* @param ListenerInterface|callable $listener
|
||||
* @param int $priority
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addOneTimeListener($event, $listener, $priority = self::P_NORMAL);
|
||||
}
|
||||
24
pancake/system/vendor/league/event/src/ListenerInterface.php
vendored
Executable file
24
pancake/system/vendor/league/event/src/ListenerInterface.php
vendored
Executable file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
interface ListenerInterface
|
||||
{
|
||||
/**
|
||||
* Handle an event.
|
||||
*
|
||||
* @param EventInterface $event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(EventInterface $event);
|
||||
|
||||
/**
|
||||
* Check whether the listener is the given parameter.
|
||||
*
|
||||
* @param mixed $listener
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isListener($listener);
|
||||
}
|
||||
15
pancake/system/vendor/league/event/src/ListenerProviderInterface.php
vendored
Executable file
15
pancake/system/vendor/league/event/src/ListenerProviderInterface.php
vendored
Executable file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
interface ListenerProviderInterface
|
||||
{
|
||||
/**
|
||||
* Provide event
|
||||
*
|
||||
* @param ListenerAcceptorInterface $listenerAcceptor
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function provideListeners(ListenerAcceptorInterface $listenerAcceptor);
|
||||
}
|
||||
57
pancake/system/vendor/league/event/src/OneTimeListener.php
vendored
Executable file
57
pancake/system/vendor/league/event/src/OneTimeListener.php
vendored
Executable file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace League\Event;
|
||||
|
||||
class OneTimeListener implements ListenerInterface
|
||||
{
|
||||
/**
|
||||
* The listener instance.
|
||||
*
|
||||
* @var ListenerInterface
|
||||
*/
|
||||
protected $listener;
|
||||
|
||||
/**
|
||||
* Create a new one time listener instance.
|
||||
*
|
||||
* @param ListenerInterface $listener
|
||||
*/
|
||||
public function __construct(ListenerInterface $listener)
|
||||
{
|
||||
$this->listener = $listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the wrapped listener.
|
||||
*
|
||||
* @return ListenerInterface
|
||||
*/
|
||||
public function getWrappedListener()
|
||||
{
|
||||
return $this->listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function handle(EventInterface $event)
|
||||
{
|
||||
$name = $event->getName();
|
||||
$emitter = $event->getEmitter();
|
||||
$emitter->removeListener($name, $this->listener);
|
||||
|
||||
return call_user_func_array([$this->listener, 'handle'], func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function isListener($listener)
|
||||
{
|
||||
if ($listener instanceof OneTimeListener) {
|
||||
$listener = $listener->getWrappedListener();
|
||||
}
|
||||
|
||||
return $this->listener->isListener($listener);
|
||||
}
|
||||
}
|
||||
21
pancake/system/vendor/league/flysystem-aws-s3-v3/LICENSE
vendored
Executable file
21
pancake/system/vendor/league/flysystem-aws-s3-v3/LICENSE
vendored
Executable file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2019 Frank de Jonge
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
161
pancake/system/vendor/league/flysystem-aws-s3-v3/changelog.md
vendored
Executable file
161
pancake/system/vendor/league/flysystem-aws-s3-v3/changelog.md
vendored
Executable file
@@ -0,0 +1,161 @@
|
||||
# Changelog
|
||||
|
||||
## 1.0.30 - 2022-07-02
|
||||
|
||||
* upgrade to list objects v2
|
||||
|
||||
## 1.0.29 - 2020-10-08
|
||||
|
||||
* copies now switch to multipart copy for large files.
|
||||
|
||||
## 1.0.28 - 2020-08-22
|
||||
|
||||
* __Allow streamed read by default.__<br/>
|
||||
This change prevents the stream from being seekable (func
|
||||
calls like rewind have no effect). Need to seek through the stream?
|
||||
Check out the docs to see how to disable streaming read: https://flysystem.thephpleague.com/v1/docs/adapter/aws-s3-v3/#streamed-reads
|
||||
|
||||
## 1.0.27 - 2020-08-22
|
||||
|
||||
* Revert always streaming reads (degraded functionality).
|
||||
|
||||
## 1.0.26 - 2020-08-18
|
||||
|
||||
* Always stream reads (#211)
|
||||
|
||||
## 1.0.25 - 2020-06-02
|
||||
|
||||
* Use `S3Client::encodeKey` for key encoding.
|
||||
|
||||
## 1.0.24 - 2020-02-23
|
||||
|
||||
* Depend on S3ClientInterface rather than the concrete client.
|
||||
|
||||
## 1.0.23 - 2019-06-05
|
||||
|
||||
* Prevent content type detection for directory creation.
|
||||
* Use `rawurlencode` instead of `urlencode` to treat url encoding in a spec compliant way.
|
||||
|
||||
## 1.0.22 - 2019-01-31
|
||||
|
||||
* Invert type check where string/resource difference is determined for ContentLength option.
|
||||
|
||||
## 1.0.21 - 2018-10-08
|
||||
|
||||
* Catch multipart upload errors.
|
||||
|
||||
## 1.0.20 - 2018-09-25
|
||||
|
||||
* Fixed prefix handling for uploads (writes and updates).
|
||||
|
||||
## 1.0.19 - 2018-03-27
|
||||
|
||||
* Added ETAG to response mapping.
|
||||
|
||||
## 1.0.18 - 2017-06-30
|
||||
|
||||
### Fixed
|
||||
|
||||
* Allow metadata to be returned through the getMetadata method.
|
||||
|
||||
## 1.0.17 - 2017-06-30
|
||||
|
||||
### Fixed
|
||||
|
||||
* Allow passing options to methods that don't accept options.
|
||||
|
||||
## 1.0.16 - 2017-06-08
|
||||
|
||||
### Improved
|
||||
|
||||
* Allow the `Tagging` meta option.
|
||||
|
||||
## 1.0.15 - 2017-04-28
|
||||
|
||||
### Improved
|
||||
|
||||
* Indicate this adapter can overwrite files.
|
||||
|
||||
## 1.0.14 - 2017-01-02
|
||||
|
||||
### Improved
|
||||
|
||||
* Now also detect mimetypes of streams.
|
||||
|
||||
## 1.0.13 - 2016-06-21
|
||||
|
||||
### Fixed
|
||||
|
||||
* Uploading a remote stream no longer results in an unexpected exception.
|
||||
|
||||
## 1.0.12 - 2016-06-06
|
||||
|
||||
### Improved
|
||||
|
||||
* Responses are now streamed instead of downloaded fully.
|
||||
|
||||
## 1.0.11 - 2016-05-03
|
||||
|
||||
### Fixed
|
||||
|
||||
* [::has] A regression introduced in 1.0.10 is addressed.
|
||||
|
||||
## 1.0.10 - 2016-04-19
|
||||
|
||||
### Fixed
|
||||
|
||||
* [::has] The `has` method now also respects implicit directories.
|
||||
|
||||
## 1.0.9 - 2015-11-19
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#49] Large listings only returned the last page of the listing.
|
||||
|
||||
## 1.0.8 - 2015-11-06
|
||||
|
||||
### Improved
|
||||
|
||||
* Non-recursive listings now retrieve a shallow listing for better performance.
|
||||
|
||||
## 1.0.7 - 2015-11-06
|
||||
|
||||
### Fixed
|
||||
|
||||
* The `copy` operation now `urlencode`'s the `CopySource` to allow characters like `+`.
|
||||
|
||||
## 1.0.6 - 2015-09-25
|
||||
|
||||
### Fixed
|
||||
|
||||
* The `has` operation now respects path prefix, bug introduced in 1.0.5.
|
||||
|
||||
## 1.0.5 - 2015-09-22
|
||||
|
||||
### Fixed
|
||||
|
||||
* `has` calls now use `doesObjectExist` rather than retrieving metadata.
|
||||
|
||||
## 1.0.4 - 2015-07-06
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed delete return value.
|
||||
|
||||
## 1.0.3 - 2015-06-16
|
||||
|
||||
### Fixed
|
||||
|
||||
* Use an iterator for contents listing to break through the 1000 objects limit.
|
||||
|
||||
## 1.0.2 - 2015-06-06
|
||||
|
||||
### Fixed
|
||||
|
||||
* Exception due to misconfiguration no longer causes a fatal error but are properly rethrown.
|
||||
|
||||
## 1.0.1 - 2015-05-31
|
||||
|
||||
### Fixed
|
||||
|
||||
* Stable release depending in the first v3 release of the AWS SDK.
|
||||
38
pancake/system/vendor/league/flysystem-aws-s3-v3/composer.json
vendored
Executable file
38
pancake/system/vendor/league/flysystem-aws-s3-v3/composer.json
vendored
Executable file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "league/flysystem-aws-s3-v3",
|
||||
"description": "Flysystem adapter for the AWS S3 SDK v3.x",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Frank de Jonge",
|
||||
"email": "info@frenky.net"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.5.0",
|
||||
"league/flysystem": "^1.0.40",
|
||||
"aws/aws-sdk-php": "^3.20.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "^2.0.0",
|
||||
"henrikbjorn/phpspec-code-coverage" : "~1.0.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Flysystem\\AwsS3v3\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"League\\Flysystem\\AwsS3v3\\Stub\\": "stub"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"bin-dir": "bin"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
723
pancake/system/vendor/league/flysystem-aws-s3-v3/src/AwsS3Adapter.php
vendored
Executable file
723
pancake/system/vendor/league/flysystem-aws-s3-v3/src/AwsS3Adapter.php
vendored
Executable file
@@ -0,0 +1,723 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\AwsS3v3;
|
||||
|
||||
use Aws\Result;
|
||||
use Aws\S3\Exception\DeleteMultipleObjectsException;
|
||||
use Aws\S3\Exception\S3Exception;
|
||||
use Aws\S3\Exception\S3MultipartUploadException;
|
||||
use Aws\S3\S3Client;
|
||||
use Aws\S3\S3ClientInterface;
|
||||
use League\Flysystem\AdapterInterface;
|
||||
use League\Flysystem\Adapter\AbstractAdapter;
|
||||
use League\Flysystem\Adapter\CanOverwriteFiles;
|
||||
use League\Flysystem\Config;
|
||||
use League\Flysystem\Util;
|
||||
|
||||
class AwsS3Adapter extends AbstractAdapter implements CanOverwriteFiles
|
||||
{
|
||||
const PUBLIC_GRANT_URI = 'http://acs.amazonaws.com/groups/global/AllUsers';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $resultMap = [
|
||||
'Body' => 'contents',
|
||||
'ContentLength' => 'size',
|
||||
'ContentType' => 'mimetype',
|
||||
'Size' => 'size',
|
||||
'Metadata' => 'metadata',
|
||||
'StorageClass' => 'storageclass',
|
||||
'ETag' => 'etag',
|
||||
'VersionId' => 'versionid'
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $metaOptions = [
|
||||
'ACL',
|
||||
'CacheControl',
|
||||
'ContentDisposition',
|
||||
'ContentEncoding',
|
||||
'ContentLength',
|
||||
'ContentMD5',
|
||||
'ContentType',
|
||||
'Expires',
|
||||
'GrantFullControl',
|
||||
'GrantRead',
|
||||
'GrantReadACP',
|
||||
'GrantWriteACP',
|
||||
'Metadata',
|
||||
'RequestPayer',
|
||||
'SSECustomerAlgorithm',
|
||||
'SSECustomerKey',
|
||||
'SSECustomerKeyMD5',
|
||||
'SSEKMSKeyId',
|
||||
'ServerSideEncryption',
|
||||
'StorageClass',
|
||||
'Tagging',
|
||||
'WebsiteRedirectLocation',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var S3ClientInterface
|
||||
*/
|
||||
protected $s3Client;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $bucket;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $streamReads;
|
||||
|
||||
public function __construct(S3ClientInterface $client, $bucket, $prefix = '', array $options = [], $streamReads = true)
|
||||
{
|
||||
$this->s3Client = $client;
|
||||
$this->bucket = $bucket;
|
||||
$this->setPathPrefix($prefix);
|
||||
$this->options = $options;
|
||||
$this->streamReads = $streamReads;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the S3Client bucket.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBucket()
|
||||
{
|
||||
return $this->bucket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the S3Client bucket.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function setBucket($bucket)
|
||||
{
|
||||
$this->bucket = $bucket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the S3Client instance.
|
||||
*
|
||||
* @return S3ClientInterface
|
||||
*/
|
||||
public function getClient()
|
||||
{
|
||||
return $this->s3Client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a new file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $contents
|
||||
* @param Config $config Config object
|
||||
*
|
||||
* @return false|array false on failure file meta data on success
|
||||
*/
|
||||
public function write($path, $contents, Config $config)
|
||||
{
|
||||
return $this->upload($path, $contents, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $contents
|
||||
* @param Config $config Config object
|
||||
*
|
||||
* @return false|array false on failure file meta data on success
|
||||
*/
|
||||
public function update($path, $contents, Config $config)
|
||||
{
|
||||
return $this->upload($path, $contents, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $newpath
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function rename($path, $newpath)
|
||||
{
|
||||
if ( ! $this->copy($path, $newpath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->delete($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a file.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete($path)
|
||||
{
|
||||
$location = $this->applyPathPrefix($path);
|
||||
|
||||
$command = $this->s3Client->getCommand(
|
||||
'deleteObject',
|
||||
[
|
||||
'Bucket' => $this->bucket,
|
||||
'Key' => $location,
|
||||
]
|
||||
);
|
||||
|
||||
$this->s3Client->execute($command);
|
||||
|
||||
return ! $this->has($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a directory.
|
||||
*
|
||||
* @param string $dirname
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteDir($dirname)
|
||||
{
|
||||
try {
|
||||
$prefix = $this->applyPathPrefix($dirname) . '/';
|
||||
$this->s3Client->deleteMatchingObjects($this->bucket, $prefix);
|
||||
} catch (DeleteMultipleObjectsException $exception) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a directory.
|
||||
*
|
||||
* @param string $dirname directory name
|
||||
* @param Config $config
|
||||
*
|
||||
* @return bool|array
|
||||
*/
|
||||
public function createDir($dirname, Config $config)
|
||||
{
|
||||
return $this->upload($dirname . '/', '', $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a file exists.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($path)
|
||||
{
|
||||
$location = $this->applyPathPrefix($path);
|
||||
|
||||
if ($this->s3Client->doesObjectExist($this->bucket, $location, $this->options)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->doesDirectoryExist($location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a file.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return false|array
|
||||
*/
|
||||
public function read($path)
|
||||
{
|
||||
$response = $this->readObject($path);
|
||||
|
||||
if ($response !== false) {
|
||||
$response['contents'] = $response['contents']->getContents();
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* List contents of a directory.
|
||||
*
|
||||
* @param string $directory
|
||||
* @param bool $recursive
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listContents($directory = '', $recursive = false)
|
||||
{
|
||||
$prefix = $this->applyPathPrefix(rtrim($directory, '/') . '/');
|
||||
$options = ['Bucket' => $this->bucket, 'Prefix' => ltrim($prefix, '/')];
|
||||
|
||||
if ($recursive === false) {
|
||||
$options['Delimiter'] = '/';
|
||||
}
|
||||
|
||||
$listing = $this->retrievePaginatedListing($options);
|
||||
$normalizer = [$this, 'normalizeResponse'];
|
||||
$normalized = array_map($normalizer, $listing);
|
||||
|
||||
return Util::emulateDirectories($normalized);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function retrievePaginatedListing(array $options)
|
||||
{
|
||||
$resultPaginator = $this->s3Client->getPaginator('ListObjectsV2', $options);
|
||||
$listing = [];
|
||||
|
||||
foreach ($resultPaginator as $result) {
|
||||
$listing = array_merge($listing, $result->get('Contents') ?: [], $result->get('CommonPrefixes') ?: []);
|
||||
}
|
||||
|
||||
return $listing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the meta data of a file or directory.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return false|array
|
||||
*/
|
||||
public function getMetadata($path)
|
||||
{
|
||||
$command = $this->s3Client->getCommand(
|
||||
'headObject',
|
||||
[
|
||||
'Bucket' => $this->bucket,
|
||||
'Key' => $this->applyPathPrefix($path),
|
||||
] + $this->options
|
||||
);
|
||||
|
||||
/* @var Result $result */
|
||||
try {
|
||||
$result = $this->s3Client->execute($command);
|
||||
} catch (S3Exception $exception) {
|
||||
if ($this->is404Exception($exception)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
return $this->normalizeResponse($result->toArray(), $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is404Exception(S3Exception $exception)
|
||||
{
|
||||
$response = $exception->getResponse();
|
||||
|
||||
if ($response !== null && $response->getStatusCode() === 404) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the meta data of a file or directory.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return false|array
|
||||
*/
|
||||
public function getSize($path)
|
||||
{
|
||||
return $this->getMetadata($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mimetype of a file.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return false|array
|
||||
*/
|
||||
public function getMimetype($path)
|
||||
{
|
||||
return $this->getMetadata($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the timestamp of a file.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return false|array
|
||||
*/
|
||||
public function getTimestamp($path)
|
||||
{
|
||||
return $this->getMetadata($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a new file using a stream.
|
||||
*
|
||||
* @param string $path
|
||||
* @param resource $resource
|
||||
* @param Config $config Config object
|
||||
*
|
||||
* @return array|false false on failure file meta data on success
|
||||
*/
|
||||
public function writeStream($path, $resource, Config $config)
|
||||
{
|
||||
return $this->upload($path, $resource, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a file using a stream.
|
||||
*
|
||||
* @param string $path
|
||||
* @param resource $resource
|
||||
* @param Config $config Config object
|
||||
*
|
||||
* @return array|false false on failure file meta data on success
|
||||
*/
|
||||
public function updateStream($path, $resource, Config $config)
|
||||
{
|
||||
return $this->upload($path, $resource, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $newpath
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function copy($path, $newpath)
|
||||
{
|
||||
try {
|
||||
$this->s3Client->copy(
|
||||
$this->bucket,
|
||||
$this->applyPathPrefix($path),
|
||||
$this->bucket,
|
||||
$this->applyPathPrefix($newpath),
|
||||
$this->getRawVisibility($path) === AdapterInterface::VISIBILITY_PUBLIC
|
||||
? 'public-read' : 'private',
|
||||
$this->options
|
||||
);
|
||||
} catch (S3Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a file as a stream.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
public function readStream($path)
|
||||
{
|
||||
$response = $this->readObject($path);
|
||||
|
||||
if ($response !== false) {
|
||||
$response['stream'] = $response['contents']->detach();
|
||||
unset($response['contents']);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an object and normalize the response.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
protected function readObject($path)
|
||||
{
|
||||
$options = [
|
||||
'Bucket' => $this->bucket,
|
||||
'Key' => $this->applyPathPrefix($path),
|
||||
] + $this->options;
|
||||
|
||||
if ($this->streamReads && ! isset($options['@http']['stream'])) {
|
||||
$options['@http']['stream'] = true;
|
||||
}
|
||||
|
||||
$command = $this->s3Client->getCommand('getObject', $options + $this->options);
|
||||
|
||||
try {
|
||||
/** @var Result $response */
|
||||
$response = $this->s3Client->execute($command);
|
||||
} catch (S3Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->normalizeResponse($response->toArray(), $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the visibility for a file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $visibility
|
||||
*
|
||||
* @return array|false file meta data
|
||||
*/
|
||||
public function setVisibility($path, $visibility)
|
||||
{
|
||||
$command = $this->s3Client->getCommand(
|
||||
'putObjectAcl',
|
||||
[
|
||||
'Bucket' => $this->bucket,
|
||||
'Key' => $this->applyPathPrefix($path),
|
||||
'ACL' => $visibility === AdapterInterface::VISIBILITY_PUBLIC ? 'public-read' : 'private',
|
||||
]
|
||||
);
|
||||
|
||||
try {
|
||||
$this->s3Client->execute($command);
|
||||
} catch (S3Exception $exception) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return compact('path', 'visibility');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the visibility of a file.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
public function getVisibility($path)
|
||||
{
|
||||
return ['visibility' => $this->getRawVisibility($path)];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function applyPathPrefix($path)
|
||||
{
|
||||
return ltrim(parent::applyPathPrefix($path), '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setPathPrefix($prefix)
|
||||
{
|
||||
$prefix = ltrim((string) $prefix, '/');
|
||||
|
||||
return parent::setPathPrefix($prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object acl presented as a visibility.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getRawVisibility($path)
|
||||
{
|
||||
$command = $this->s3Client->getCommand(
|
||||
'getObjectAcl',
|
||||
[
|
||||
'Bucket' => $this->bucket,
|
||||
'Key' => $this->applyPathPrefix($path),
|
||||
]
|
||||
);
|
||||
|
||||
$result = $this->s3Client->execute($command);
|
||||
$visibility = AdapterInterface::VISIBILITY_PRIVATE;
|
||||
|
||||
foreach ($result->get('Grants') as $grant) {
|
||||
if (
|
||||
isset($grant['Grantee']['URI'])
|
||||
&& $grant['Grantee']['URI'] === self::PUBLIC_GRANT_URI
|
||||
&& $grant['Permission'] === 'READ'
|
||||
) {
|
||||
$visibility = AdapterInterface::VISIBILITY_PUBLIC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $visibility;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload an object.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string|resource $body
|
||||
* @param Config $config
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
protected function upload($path, $body, Config $config)
|
||||
{
|
||||
$key = $this->applyPathPrefix($path);
|
||||
$options = $this->getOptionsFromConfig($config);
|
||||
$acl = array_key_exists('ACL', $options) ? $options['ACL'] : 'private';
|
||||
|
||||
if (!$this->isOnlyDir($path)) {
|
||||
if ( ! isset($options['ContentType'])) {
|
||||
$options['ContentType'] = Util::guessMimeType($path, $body);
|
||||
}
|
||||
|
||||
if ( ! isset($options['ContentLength'])) {
|
||||
$options['ContentLength'] = is_resource($body) ? Util::getStreamSize($body) : Util::contentSize($body);
|
||||
}
|
||||
|
||||
if ($options['ContentLength'] === null) {
|
||||
unset($options['ContentLength']);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->s3Client->upload($this->bucket, $key, $body, $acl, ['params' => $options]);
|
||||
} catch (S3MultipartUploadException $multipartUploadException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->normalizeResponse($options, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the path contains only directories
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isOnlyDir($path)
|
||||
{
|
||||
return substr($path, -1) === '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get options from the config.
|
||||
*
|
||||
* @param Config $config
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getOptionsFromConfig(Config $config)
|
||||
{
|
||||
$options = $this->options;
|
||||
|
||||
if ($visibility = $config->get('visibility')) {
|
||||
// For local reference
|
||||
$options['visibility'] = $visibility;
|
||||
// For external reference
|
||||
$options['ACL'] = $visibility === AdapterInterface::VISIBILITY_PUBLIC ? 'public-read' : 'private';
|
||||
}
|
||||
|
||||
if ($mimetype = $config->get('mimetype')) {
|
||||
// For local reference
|
||||
$options['mimetype'] = $mimetype;
|
||||
// For external reference
|
||||
$options['ContentType'] = $mimetype;
|
||||
}
|
||||
|
||||
foreach (static::$metaOptions as $option) {
|
||||
if ( ! $config->has($option)) {
|
||||
continue;
|
||||
}
|
||||
$options[$option] = $config->get($option);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the object result array.
|
||||
*
|
||||
* @param array $response
|
||||
* @param string $path
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function normalizeResponse(array $response, $path = null)
|
||||
{
|
||||
$result = [
|
||||
'path' => $path ?: $this->removePathPrefix(
|
||||
isset($response['Key']) ? $response['Key'] : $response['Prefix']
|
||||
),
|
||||
];
|
||||
$result = array_merge($result, Util::pathinfo($result['path']));
|
||||
|
||||
if (isset($response['LastModified'])) {
|
||||
$result['timestamp'] = strtotime($response['LastModified']);
|
||||
}
|
||||
|
||||
if ($this->isOnlyDir($result['path'])) {
|
||||
$result['type'] = 'dir';
|
||||
$result['path'] = rtrim($result['path'], '/');
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return array_merge($result, Util::map($response, static::$resultMap), ['type' => 'file']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $location
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function doesDirectoryExist($location)
|
||||
{
|
||||
// Maybe this isn't an actual key, but a prefix.
|
||||
// Do a prefix listing of objects to determine.
|
||||
$command = $this->s3Client->getCommand(
|
||||
'ListObjectsV2',
|
||||
[
|
||||
'Bucket' => $this->bucket,
|
||||
'Prefix' => rtrim($location, '/') . '/',
|
||||
'MaxKeys' => 1,
|
||||
]
|
||||
);
|
||||
|
||||
try {
|
||||
$result = $this->s3Client->execute($command);
|
||||
|
||||
return $result['Contents'] || $result['CommonPrefixes'];
|
||||
} catch (S3Exception $e) {
|
||||
if (in_array($e->getStatusCode(), [403, 404], true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
76
pancake/system/vendor/league/flysystem/CODE_OF_CONDUCT.md
vendored
Executable file
76
pancake/system/vendor/league/flysystem/CODE_OF_CONDUCT.md
vendored
Executable file
@@ -0,0 +1,76 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at info+flysystem@frankdejonge.nl. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
19
pancake/system/vendor/league/flysystem/LICENSE
vendored
Executable file
19
pancake/system/vendor/league/flysystem/LICENSE
vendored
Executable file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2013-2019 Frank de Jonge
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
16
pancake/system/vendor/league/flysystem/SECURITY.md
vendored
Executable file
16
pancake/system/vendor/league/flysystem/SECURITY.md
vendored
Executable file
@@ -0,0 +1,16 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 1.0.x | :white_check_mark: |
|
||||
| 2.0.x | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
When you've encountered a security vulnerability, please disclose it securely.
|
||||
|
||||
The security process is described at:
|
||||
[https://flysystem.thephpleague.com/docs/security/](https://flysystem.thephpleague.com/docs/security/)
|
||||
|
||||
68
pancake/system/vendor/league/flysystem/composer.json
vendored
Executable file
68
pancake/system/vendor/league/flysystem/composer.json
vendored
Executable file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
"type": "library",
|
||||
"description": "Filesystem abstraction: Many filesystems, one API.",
|
||||
"keywords": [
|
||||
"filesystem", "filesystems", "files", "storage", "dropbox", "aws",
|
||||
"abstraction", "s3", "ftp", "sftp", "remote", "webdav",
|
||||
"file systems", "cloud", "cloud files", "rackspace", "copy.com"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"type": "other",
|
||||
"url": "https://offset.earth/frankdejonge"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Frank de Jonge",
|
||||
"email": "info@frenky.net"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"ext-fileinfo": "*",
|
||||
"league/mime-type-detection": "^1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/prophecy": "^1.11.1",
|
||||
"phpunit/phpunit": "^8.5.8"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Flysystem\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"League\\Flysystem\\Stub\\": "stub/"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem",
|
||||
"league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files",
|
||||
"league/flysystem-azure": "Allows you to use Windows Azure Blob storage",
|
||||
"league/flysystem-webdav": "Allows you to use WebDAV storage",
|
||||
"league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2",
|
||||
"league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3",
|
||||
"spatie/flysystem-dropbox": "Allows you to use Dropbox storage",
|
||||
"srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications",
|
||||
"league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching",
|
||||
"ext-ftp": "Allows you to use FTP server storage",
|
||||
"ext-openssl": "Allows you to use FTPS server storage",
|
||||
"league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib",
|
||||
"league/flysystem-ziparchive": "Allows you to use ZipArchive adapter"
|
||||
},
|
||||
"conflict": {
|
||||
"league/flysystem-sftp": "<1.0.6"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1-dev"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"phpstan": "php phpstan.php"
|
||||
}
|
||||
}
|
||||
19
pancake/system/vendor/league/flysystem/deprecations.md
vendored
Executable file
19
pancake/system/vendor/league/flysystem/deprecations.md
vendored
Executable file
@@ -0,0 +1,19 @@
|
||||
# Deprecations
|
||||
|
||||
This document lists all the planned deprecations.
|
||||
|
||||
## Handlers will be removed in 2.0
|
||||
|
||||
The `Handler` type and associated calls will be removed in version 2.0.
|
||||
|
||||
### Upgrade path
|
||||
|
||||
You should create your own implementation for handling OOP usage,
|
||||
but it's recommended to move away from using an OOP-style wrapper entirely.
|
||||
|
||||
The reason for this is that it's too easy for implementation details (for
|
||||
your application this is Flysystem) to leak into the application. The most
|
||||
important part for Flysystem is that it improves portability and creates a
|
||||
solid boundary between your application core and the infrastructure you use.
|
||||
The OOP-style handling breaks this principle, therefore I want to stop
|
||||
promoting it.
|
||||
72
pancake/system/vendor/league/flysystem/src/Adapter/AbstractAdapter.php
vendored
Executable file
72
pancake/system/vendor/league/flysystem/src/Adapter/AbstractAdapter.php
vendored
Executable file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Adapter;
|
||||
|
||||
use League\Flysystem\AdapterInterface;
|
||||
|
||||
abstract class AbstractAdapter implements AdapterInterface
|
||||
{
|
||||
/**
|
||||
* @var string|null path prefix
|
||||
*/
|
||||
protected $pathPrefix;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $pathSeparator = '/';
|
||||
|
||||
/**
|
||||
* Set the path prefix.
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPathPrefix($prefix)
|
||||
{
|
||||
$prefix = (string) $prefix;
|
||||
|
||||
if ($prefix === '') {
|
||||
$this->pathPrefix = null;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->pathPrefix = rtrim($prefix, '\\/') . $this->pathSeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path prefix.
|
||||
*
|
||||
* @return string|null path prefix or null if pathPrefix is empty
|
||||
*/
|
||||
public function getPathPrefix()
|
||||
{
|
||||
return $this->pathPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix a path.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return string prefixed path
|
||||
*/
|
||||
public function applyPathPrefix($path)
|
||||
{
|
||||
return $this->getPathPrefix() . ltrim($path, '\\/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a path prefix.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return string path without the prefix
|
||||
*/
|
||||
public function removePathPrefix($path)
|
||||
{
|
||||
return substr($path, strlen((string) $this->getPathPrefix()));
|
||||
}
|
||||
}
|
||||
705
pancake/system/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php
vendored
Executable file
705
pancake/system/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php
vendored
Executable file
@@ -0,0 +1,705 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Adapter;
|
||||
|
||||
use DateTime;
|
||||
use League\Flysystem\AdapterInterface;
|
||||
use League\Flysystem\Config;
|
||||
use League\Flysystem\NotSupportedException;
|
||||
use League\Flysystem\SafeStorage;
|
||||
use RuntimeException;
|
||||
|
||||
abstract class AbstractFtpAdapter extends AbstractAdapter
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $host;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $port = 21;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $ssl = false;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $timeout = 90;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $passive = true;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $separator = '/';
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $root;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $permPublic = 0744;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $permPrivate = 0700;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $configurable = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $systemType;
|
||||
|
||||
/**
|
||||
* @var SafeStorage
|
||||
*/
|
||||
protected $safeStorage;
|
||||
|
||||
/**
|
||||
* True to enable timestamps for FTP servers that return unix-style listings.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $enableTimestampsOnUnixListings = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct(array $config)
|
||||
{
|
||||
$this->safeStorage = new SafeStorage();
|
||||
$this->setConfig($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the config.
|
||||
*
|
||||
* @param array $config
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setConfig(array $config)
|
||||
{
|
||||
foreach ($this->configurable as $setting) {
|
||||
if ( ! isset($config[$setting])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$method = 'set' . ucfirst($setting);
|
||||
|
||||
if (method_exists($this, $method)) {
|
||||
$this->$method($config[$setting]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the host.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHost()
|
||||
{
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the host.
|
||||
*
|
||||
* @param string $host
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setHost($host)
|
||||
{
|
||||
$this->host = $host;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the public permission value.
|
||||
*
|
||||
* @param int $permPublic
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPermPublic($permPublic)
|
||||
{
|
||||
$this->permPublic = $permPublic;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the private permission value.
|
||||
*
|
||||
* @param int $permPrivate
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPermPrivate($permPrivate)
|
||||
{
|
||||
$this->permPrivate = $permPrivate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ftp port.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getPort()
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root folder to work from.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRoot()
|
||||
{
|
||||
return $this->root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ftp port.
|
||||
*
|
||||
* @param int|string $port
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPort($port)
|
||||
{
|
||||
$this->port = (int) $port;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the root folder to work from.
|
||||
*
|
||||
* @param string $root
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRoot($root)
|
||||
{
|
||||
$this->root = rtrim($root, '\\/') . $this->separator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ftp username.
|
||||
*
|
||||
* @return string username
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
$username = $this->safeStorage->retrieveSafely('username');
|
||||
|
||||
return $username !== null ? $username : 'anonymous';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ftp username.
|
||||
*
|
||||
* @param string $username
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setUsername($username)
|
||||
{
|
||||
$this->safeStorage->storeSafely('username', $username);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the password.
|
||||
*
|
||||
* @return string password
|
||||
*/
|
||||
public function getPassword()
|
||||
{
|
||||
return $this->safeStorage->retrieveSafely('password');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ftp password.
|
||||
*
|
||||
* @param string $password
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPassword($password)
|
||||
{
|
||||
$this->safeStorage->storeSafely('password', $password);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of seconds before the connection will timeout.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getTimeout()
|
||||
{
|
||||
return $this->timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the amount of seconds before the connection should timeout.
|
||||
*
|
||||
* @param int $timeout
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTimeout($timeout)
|
||||
{
|
||||
$this->timeout = (int) $timeout;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FTP system type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSystemType()
|
||||
{
|
||||
return $this->systemType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the FTP system type (windows or unix).
|
||||
*
|
||||
* @param string $systemType
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setSystemType($systemType)
|
||||
{
|
||||
$this->systemType = strtolower($systemType);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* True to enable timestamps for FTP servers that return unix-style listings.
|
||||
*
|
||||
* @param bool $bool
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEnableTimestampsOnUnixListings($bool = false)
|
||||
{
|
||||
$this->enableTimestampsOnUnixListings = $bool;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function listContents($directory = '', $recursive = false)
|
||||
{
|
||||
return $this->listDirectoryContents($directory, $recursive);
|
||||
}
|
||||
|
||||
abstract protected function listDirectoryContents($directory, $recursive = false);
|
||||
|
||||
/**
|
||||
* Normalize a directory listing.
|
||||
*
|
||||
* @param array $listing
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return array directory listing
|
||||
*/
|
||||
protected function normalizeListing(array $listing, $prefix = '')
|
||||
{
|
||||
$base = $prefix;
|
||||
$result = [];
|
||||
$listing = $this->removeDotDirectories($listing);
|
||||
|
||||
while ($item = array_shift($listing)) {
|
||||
if (preg_match('#^.*:$#', $item)) {
|
||||
$base = preg_replace('~^\./*|:$~', '', $item);
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[] = $this->normalizeObject($item, $base);
|
||||
}
|
||||
|
||||
return $this->sortListing($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort a directory listing.
|
||||
*
|
||||
* @param array $result
|
||||
*
|
||||
* @return array sorted listing
|
||||
*/
|
||||
protected function sortListing(array $result)
|
||||
{
|
||||
$compare = function ($one, $two) {
|
||||
return strnatcmp($one['path'], $two['path']);
|
||||
};
|
||||
|
||||
usort($result, $compare);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a file entry.
|
||||
*
|
||||
* @param string $item
|
||||
* @param string $base
|
||||
*
|
||||
* @return array normalized file array
|
||||
*
|
||||
* @throws NotSupportedException
|
||||
*/
|
||||
protected function normalizeObject($item, $base)
|
||||
{
|
||||
$systemType = $this->systemType ?: $this->detectSystemType($item);
|
||||
|
||||
if ($systemType === 'unix') {
|
||||
return $this->normalizeUnixObject($item, $base);
|
||||
} elseif ($systemType === 'windows') {
|
||||
return $this->normalizeWindowsObject($item, $base);
|
||||
}
|
||||
|
||||
throw NotSupportedException::forFtpSystemType($systemType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a Unix file entry.
|
||||
*
|
||||
* Given $item contains:
|
||||
* '-rw-r--r-- 1 ftp ftp 409 Aug 19 09:01 file1.txt'
|
||||
*
|
||||
* This function will return:
|
||||
* [
|
||||
* 'type' => 'file',
|
||||
* 'path' => 'file1.txt',
|
||||
* 'visibility' => 'public',
|
||||
* 'size' => 409,
|
||||
* 'timestamp' => 1566205260
|
||||
* ]
|
||||
*
|
||||
* @param string $item
|
||||
* @param string $base
|
||||
*
|
||||
* @return array normalized file array
|
||||
*/
|
||||
protected function normalizeUnixObject($item, $base)
|
||||
{
|
||||
$item = preg_replace('#\s+#', ' ', trim($item), 7);
|
||||
|
||||
if (count(explode(' ', $item, 9)) !== 9) {
|
||||
throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts.");
|
||||
}
|
||||
|
||||
list($permissions, /* $number */, /* $owner */, /* $group */, $size, $month, $day, $timeOrYear, $name) = explode(' ', $item, 9);
|
||||
$type = $this->detectType($permissions);
|
||||
$path = $base === '' ? $name : $base . $this->separator . $name;
|
||||
|
||||
if ($type === 'dir') {
|
||||
$result = compact('type', 'path');
|
||||
if ($this->enableTimestampsOnUnixListings) {
|
||||
$timestamp = $this->normalizeUnixTimestamp($month, $day, $timeOrYear);
|
||||
$result += compact('timestamp');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$permissions = $this->normalizePermissions($permissions);
|
||||
$visibility = $permissions & 0044 ? AdapterInterface::VISIBILITY_PUBLIC : AdapterInterface::VISIBILITY_PRIVATE;
|
||||
$size = (int) $size;
|
||||
|
||||
$result = compact('type', 'path', 'visibility', 'size');
|
||||
if ($this->enableTimestampsOnUnixListings) {
|
||||
$timestamp = $this->normalizeUnixTimestamp($month, $day, $timeOrYear);
|
||||
$result += compact('timestamp');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only accurate to the minute (current year), or to the day.
|
||||
*
|
||||
* Inadequacies in timestamp accuracy are due to limitations of the FTP 'LIST' command
|
||||
*
|
||||
* Note: The 'MLSD' command is a machine-readable replacement for 'LIST'
|
||||
* but many FTP servers do not support it :(
|
||||
*
|
||||
* @param string $month e.g. 'Aug'
|
||||
* @param string $day e.g. '19'
|
||||
* @param string $timeOrYear e.g. '09:01' OR '2015'
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function normalizeUnixTimestamp($month, $day, $timeOrYear)
|
||||
{
|
||||
if (is_numeric($timeOrYear)) {
|
||||
$year = $timeOrYear;
|
||||
$hour = '00';
|
||||
$minute = '00';
|
||||
$seconds = '00';
|
||||
} else {
|
||||
$year = date('Y');
|
||||
list($hour, $minute) = explode(':', $timeOrYear);
|
||||
$seconds = '00';
|
||||
}
|
||||
$dateTime = DateTime::createFromFormat('Y-M-j-G:i:s', "{$year}-{$month}-{$day}-{$hour}:{$minute}:{$seconds}");
|
||||
|
||||
return $dateTime->getTimestamp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a Windows/DOS file entry.
|
||||
*
|
||||
* @param string $item
|
||||
* @param string $base
|
||||
*
|
||||
* @return array normalized file array
|
||||
*/
|
||||
protected function normalizeWindowsObject($item, $base)
|
||||
{
|
||||
$item = preg_replace('#\s+#', ' ', trim($item), 3);
|
||||
|
||||
if (count(explode(' ', $item, 4)) !== 4) {
|
||||
throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts.");
|
||||
}
|
||||
|
||||
list($date, $time, $size, $name) = explode(' ', $item, 4);
|
||||
$path = $base === '' ? $name : $base . $this->separator . $name;
|
||||
|
||||
// Check for the correct date/time format
|
||||
$format = strlen($date) === 8 ? 'm-d-yH:iA' : 'Y-m-dH:i';
|
||||
$dt = DateTime::createFromFormat($format, $date . $time);
|
||||
$timestamp = $dt ? $dt->getTimestamp() : (int) strtotime("$date $time");
|
||||
|
||||
if ($size === '<DIR>') {
|
||||
$type = 'dir';
|
||||
|
||||
return compact('type', 'path', 'timestamp');
|
||||
}
|
||||
|
||||
$type = 'file';
|
||||
$visibility = AdapterInterface::VISIBILITY_PUBLIC;
|
||||
$size = (int) $size;
|
||||
|
||||
return compact('type', 'path', 'visibility', 'size', 'timestamp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the system type from a listing item.
|
||||
*
|
||||
* @param string $item
|
||||
*
|
||||
* @return string the system type
|
||||
*/
|
||||
protected function detectSystemType($item)
|
||||
{
|
||||
return preg_match('/^[0-9]{2,4}-[0-9]{2}-[0-9]{2}/', trim($item)) ? 'windows' : 'unix';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file type from the permissions.
|
||||
*
|
||||
* @param string $permissions
|
||||
*
|
||||
* @return string file type
|
||||
*/
|
||||
protected function detectType($permissions)
|
||||
{
|
||||
return substr($permissions, 0, 1) === 'd' ? 'dir' : 'file';
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a permissions string.
|
||||
*
|
||||
* @param string $permissions
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function normalizePermissions($permissions)
|
||||
{
|
||||
if (is_numeric($permissions)) {
|
||||
return ((int) $permissions) & 0777;
|
||||
}
|
||||
|
||||
// remove the type identifier
|
||||
$permissions = substr($permissions, 1);
|
||||
|
||||
// map the string rights to the numeric counterparts
|
||||
$map = ['-' => '0', 'r' => '4', 'w' => '2', 'x' => '1'];
|
||||
$permissions = strtr($permissions, $map);
|
||||
|
||||
// split up the permission groups
|
||||
$parts = str_split($permissions, 3);
|
||||
|
||||
// convert the groups
|
||||
$mapper = function ($part) {
|
||||
return array_sum(str_split($part));
|
||||
};
|
||||
|
||||
// converts to decimal number
|
||||
return octdec(implode('', array_map($mapper, $parts)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out dot-directories.
|
||||
*
|
||||
* @param array $list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function removeDotDirectories(array $list)
|
||||
{
|
||||
$filter = function ($line) {
|
||||
return $line !== '' && ! preg_match('#.* \.(\.)?$|^total#', $line);
|
||||
};
|
||||
|
||||
return array_filter($list, $filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function has($path)
|
||||
{
|
||||
return $this->getMetadata($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSize($path)
|
||||
{
|
||||
return $this->getMetadata($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getVisibility($path)
|
||||
{
|
||||
return $this->getMetadata($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure a directory exists.
|
||||
*
|
||||
* @param string $dirname
|
||||
*/
|
||||
public function ensureDirectory($dirname)
|
||||
{
|
||||
$dirname = (string) $dirname;
|
||||
|
||||
if ($dirname !== '' && ! $this->has($dirname)) {
|
||||
$this->createDir($dirname, new Config());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
if ( ! $this->isConnected()) {
|
||||
$this->disconnect();
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the public permission value.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getPermPublic()
|
||||
{
|
||||
return $this->permPublic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the private permission value.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getPermPrivate()
|
||||
{
|
||||
return $this->permPrivate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect on destruction.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Establish a connection.
|
||||
*/
|
||||
abstract public function connect();
|
||||
|
||||
/**
|
||||
* Close the connection.
|
||||
*/
|
||||
abstract public function disconnect();
|
||||
|
||||
/**
|
||||
* Check if a connection is active.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function isConnected();
|
||||
|
||||
protected function escapePath($path)
|
||||
{
|
||||
return str_replace(['*', '[', ']'], ['\\*', '\\[', '\\]'], $path);
|
||||
}
|
||||
}
|
||||
12
pancake/system/vendor/league/flysystem/src/Adapter/CanOverwriteFiles.php
vendored
Executable file
12
pancake/system/vendor/league/flysystem/src/Adapter/CanOverwriteFiles.php
vendored
Executable file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace League\Flysystem\Adapter;
|
||||
|
||||
/**
|
||||
* Adapters that implement this interface let the Filesystem know that files can be overwritten using the write
|
||||
* functions and don't need the update function to be called. This can help improve performance when asserts are disabled.
|
||||
*/
|
||||
interface CanOverwriteFiles
|
||||
{
|
||||
}
|
||||
584
pancake/system/vendor/league/flysystem/src/Adapter/Ftp.php
vendored
Executable file
584
pancake/system/vendor/league/flysystem/src/Adapter/Ftp.php
vendored
Executable file
@@ -0,0 +1,584 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Adapter;
|
||||
|
||||
use League\Flysystem\Adapter\Polyfill\StreamedCopyTrait;
|
||||
use League\Flysystem\AdapterInterface;
|
||||
use League\Flysystem\Config;
|
||||
use League\Flysystem\ConnectionErrorException;
|
||||
use League\Flysystem\ConnectionRuntimeException;
|
||||
use League\Flysystem\InvalidRootException;
|
||||
use League\Flysystem\Util;
|
||||
use League\Flysystem\Util\MimeType;
|
||||
|
||||
use function in_array;
|
||||
|
||||
class Ftp extends AbstractFtpAdapter
|
||||
{
|
||||
use StreamedCopyTrait;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $transferMode = FTP_BINARY;
|
||||
|
||||
/**
|
||||
* @var null|bool
|
||||
*/
|
||||
protected $ignorePassiveAddress = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $recurseManually = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $utf8 = false;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $configurable = [
|
||||
'host',
|
||||
'port',
|
||||
'username',
|
||||
'password',
|
||||
'ssl',
|
||||
'timeout',
|
||||
'root',
|
||||
'permPrivate',
|
||||
'permPublic',
|
||||
'passive',
|
||||
'transferMode',
|
||||
'systemType',
|
||||
'ignorePassiveAddress',
|
||||
'recurseManually',
|
||||
'utf8',
|
||||
'enableTimestampsOnUnixListings',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isPureFtpd;
|
||||
|
||||
/**
|
||||
* Set the transfer mode.
|
||||
*
|
||||
* @param int $mode
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTransferMode($mode)
|
||||
{
|
||||
$this->transferMode = $mode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if Ssl is enabled.
|
||||
*
|
||||
* @param bool $ssl
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setSsl($ssl)
|
||||
{
|
||||
$this->ssl = (bool) $ssl;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if passive mode should be used.
|
||||
*
|
||||
* @param bool $passive
|
||||
*/
|
||||
public function setPassive($passive = true)
|
||||
{
|
||||
$this->passive = $passive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $ignorePassiveAddress
|
||||
*/
|
||||
public function setIgnorePassiveAddress($ignorePassiveAddress)
|
||||
{
|
||||
$this->ignorePassiveAddress = $ignorePassiveAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $recurseManually
|
||||
*/
|
||||
public function setRecurseManually($recurseManually)
|
||||
{
|
||||
$this->recurseManually = $recurseManually;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $utf8
|
||||
*/
|
||||
public function setUtf8($utf8)
|
||||
{
|
||||
$this->utf8 = (bool) $utf8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the FTP server.
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
$tries = 3;
|
||||
start_connecting:
|
||||
|
||||
if ($this->ssl) {
|
||||
$this->connection = @ftp_ssl_connect($this->getHost(), $this->getPort(), $this->getTimeout());
|
||||
} else {
|
||||
$this->connection = @ftp_connect($this->getHost(), $this->getPort(), $this->getTimeout());
|
||||
}
|
||||
|
||||
if ( ! $this->connection) {
|
||||
$tries--;
|
||||
|
||||
if ($tries > 0) goto start_connecting;
|
||||
|
||||
throw new ConnectionRuntimeException('Could not connect to host: ' . $this->getHost() . ', port:' . $this->getPort());
|
||||
}
|
||||
|
||||
$this->login();
|
||||
$this->setUtf8Mode();
|
||||
$this->setConnectionPassiveMode();
|
||||
$this->setConnectionRoot();
|
||||
$this->isPureFtpd = $this->isPureFtpdServer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connection to UTF-8 mode.
|
||||
*/
|
||||
protected function setUtf8Mode()
|
||||
{
|
||||
if ($this->utf8) {
|
||||
$response = ftp_raw($this->connection, "OPTS UTF8 ON");
|
||||
if (!in_array(substr($response[0], 0, 3), ['200', '202'])) {
|
||||
throw new ConnectionRuntimeException(
|
||||
'Could not set UTF-8 mode for connection: ' . $this->getHost() . '::' . $this->getPort()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connections to passive mode.
|
||||
*
|
||||
* @throws ConnectionRuntimeException
|
||||
*/
|
||||
protected function setConnectionPassiveMode()
|
||||
{
|
||||
if (is_bool($this->ignorePassiveAddress) && defined('FTP_USEPASVADDRESS')) {
|
||||
ftp_set_option($this->connection, FTP_USEPASVADDRESS, ! $this->ignorePassiveAddress);
|
||||
}
|
||||
|
||||
if ( ! ftp_pasv($this->connection, $this->passive)) {
|
||||
throw new ConnectionRuntimeException(
|
||||
'Could not set passive mode for connection: ' . $this->getHost() . '::' . $this->getPort()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connection root.
|
||||
*/
|
||||
protected function setConnectionRoot()
|
||||
{
|
||||
$root = $this->getRoot();
|
||||
$connection = $this->connection;
|
||||
|
||||
if ($root && ! ftp_chdir($connection, $root)) {
|
||||
throw new InvalidRootException('Root is invalid or does not exist: ' . $this->getRoot());
|
||||
}
|
||||
|
||||
// Store absolute path for further reference.
|
||||
// This is needed when creating directories and
|
||||
// initial root was a relative path, else the root
|
||||
// would be relative to the chdir'd path.
|
||||
$this->root = ftp_pwd($connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Login.
|
||||
*
|
||||
* @throws ConnectionRuntimeException
|
||||
*/
|
||||
protected function login()
|
||||
{
|
||||
set_error_handler(function () {
|
||||
});
|
||||
$isLoggedIn = ftp_login(
|
||||
$this->connection,
|
||||
$this->getUsername(),
|
||||
$this->getPassword()
|
||||
);
|
||||
restore_error_handler();
|
||||
|
||||
if ( ! $isLoggedIn) {
|
||||
$this->disconnect();
|
||||
throw new ConnectionRuntimeException(
|
||||
'Could not login with connection: ' . $this->getHost() . '::' . $this->getPort(
|
||||
) . ', username: ' . $this->getUsername()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from the FTP server.
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
if ($this->hasFtpConnection()) {
|
||||
@ftp_close($this->connection);
|
||||
}
|
||||
|
||||
$this->connection = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function write($path, $contents, Config $config)
|
||||
{
|
||||
$stream = fopen('php://temp', 'w+b');
|
||||
fwrite($stream, $contents);
|
||||
rewind($stream);
|
||||
$result = $this->writeStream($path, $stream, $config);
|
||||
fclose($stream);
|
||||
|
||||
if ($result === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result['contents'] = $contents;
|
||||
$result['mimetype'] = $config->get('mimetype') ?: Util::guessMimeType($path, $contents);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function writeStream($path, $resource, Config $config)
|
||||
{
|
||||
$this->ensureDirectory(Util::dirname($path));
|
||||
|
||||
if ( ! ftp_fput($this->getConnection(), $path, $resource, $this->transferMode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($visibility = $config->get('visibility')) {
|
||||
$this->setVisibility($path, $visibility);
|
||||
}
|
||||
|
||||
$type = 'file';
|
||||
|
||||
return compact('type', 'path', 'visibility');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function update($path, $contents, Config $config)
|
||||
{
|
||||
return $this->write($path, $contents, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function updateStream($path, $resource, Config $config)
|
||||
{
|
||||
return $this->writeStream($path, $resource, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function rename($path, $newpath)
|
||||
{
|
||||
return ftp_rename($this->getConnection(), $path, $newpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function delete($path)
|
||||
{
|
||||
return ftp_delete($this->getConnection(), $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function deleteDir($dirname)
|
||||
{
|
||||
$connection = $this->getConnection();
|
||||
$contents = array_reverse($this->listDirectoryContents($dirname, false));
|
||||
|
||||
foreach ($contents as $object) {
|
||||
if ($object['type'] === 'file') {
|
||||
if ( ! ftp_delete($connection, $object['path'])) {
|
||||
return false;
|
||||
}
|
||||
} elseif ( ! $this->deleteDir($object['path'])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return ftp_rmdir($connection, $dirname);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function createDir($dirname, Config $config)
|
||||
{
|
||||
$connection = $this->getConnection();
|
||||
$directories = explode('/', $dirname);
|
||||
|
||||
foreach ($directories as $directory) {
|
||||
if (false === $this->createActualDirectory($directory, $connection)) {
|
||||
$this->setConnectionRoot();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ftp_chdir($connection, $directory);
|
||||
}
|
||||
|
||||
$this->setConnectionRoot();
|
||||
|
||||
return ['type' => 'dir', 'path' => $dirname];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a directory.
|
||||
*
|
||||
* @param string $directory
|
||||
* @param resource $connection
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function createActualDirectory($directory, $connection)
|
||||
{
|
||||
// List the current directory
|
||||
$listing = ftp_nlist($connection, '.') ?: [];
|
||||
|
||||
foreach ($listing as $key => $item) {
|
||||
if (preg_match('~^\./.*~', $item)) {
|
||||
$listing[$key] = substr($item, 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array($directory, $listing, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (boolean) ftp_mkdir($connection, $directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getMetadata($path)
|
||||
{
|
||||
if ($path === '') {
|
||||
return ['type' => 'dir', 'path' => ''];
|
||||
}
|
||||
|
||||
if (@ftp_chdir($this->getConnection(), $path) === true) {
|
||||
$this->setConnectionRoot();
|
||||
|
||||
return ['type' => 'dir', 'path' => $path];
|
||||
}
|
||||
|
||||
$listing = $this->ftpRawlist('-A', $path);
|
||||
|
||||
if (empty($listing) || in_array('total 0', $listing, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/.* not found/', $listing[0])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/^total [0-9]*$/', $listing[0])) {
|
||||
array_shift($listing);
|
||||
}
|
||||
|
||||
return $this->normalizeObject($listing[0], '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getMimetype($path)
|
||||
{
|
||||
if ( ! $metadata = $this->getMetadata($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$metadata['mimetype'] = MimeType::detectByFilename($path);
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getTimestamp($path)
|
||||
{
|
||||
$timestamp = ftp_mdtm($this->getConnection(), $path);
|
||||
|
||||
return ($timestamp !== -1) ? ['path' => $path, 'timestamp' => $timestamp] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function read($path)
|
||||
{
|
||||
if ( ! $object = $this->readStream($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$object['contents'] = stream_get_contents($object['stream']);
|
||||
fclose($object['stream']);
|
||||
unset($object['stream']);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function readStream($path)
|
||||
{
|
||||
$stream = fopen('php://temp', 'w+b');
|
||||
$result = ftp_fget($this->getConnection(), $stream, $path, $this->transferMode);
|
||||
rewind($stream);
|
||||
|
||||
if ( ! $result) {
|
||||
fclose($stream);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return ['type' => 'file', 'path' => $path, 'stream' => $stream];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setVisibility($path, $visibility)
|
||||
{
|
||||
$mode = $visibility === AdapterInterface::VISIBILITY_PUBLIC ? $this->getPermPublic() : $this->getPermPrivate();
|
||||
|
||||
if ( ! ftp_chmod($this->getConnection(), $mode, $path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return compact('path', 'visibility');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*
|
||||
* @param string $directory
|
||||
*/
|
||||
protected function listDirectoryContents($directory, $recursive = true)
|
||||
{
|
||||
if ($recursive && $this->recurseManually) {
|
||||
return $this->listDirectoryContentsRecursive($directory);
|
||||
}
|
||||
|
||||
$options = $recursive ? '-alnR' : '-aln';
|
||||
$listing = $this->ftpRawlist($options, $directory);
|
||||
|
||||
return $listing ? $this->normalizeListing($listing, $directory) : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*
|
||||
* @param string $directory
|
||||
*/
|
||||
protected function listDirectoryContentsRecursive($directory)
|
||||
{
|
||||
$listing = $this->normalizeListing($this->ftpRawlist('-aln', $directory) ?: [], $directory);
|
||||
$output = [];
|
||||
|
||||
foreach ($listing as $item) {
|
||||
$output[] = $item;
|
||||
if ($item['type'] !== 'dir') {
|
||||
continue;
|
||||
}
|
||||
$output = array_merge($output, $this->listDirectoryContentsRecursive($item['path']));
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the connection is open.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws ConnectionErrorException
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
return $this->hasFtpConnection() && $this->getRawExecResponseCode('NOOP') === 200;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function isPureFtpdServer()
|
||||
{
|
||||
$response = ftp_raw($this->connection, 'HELP');
|
||||
|
||||
return stripos(implode(' ', $response), 'Pure-FTPd') !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The ftp_rawlist function with optional escaping.
|
||||
*
|
||||
* @param string $options
|
||||
* @param string $path
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function ftpRawlist($options, $path)
|
||||
{
|
||||
$connection = $this->getConnection();
|
||||
|
||||
if ($this->isPureFtpd) {
|
||||
$path = str_replace([' ', '[', ']'], ['\ ', '\\[', '\\]'], $path);
|
||||
}
|
||||
|
||||
return ftp_rawlist($connection, $options . ' ' . $this->escapePath($path));
|
||||
}
|
||||
|
||||
private function getRawExecResponseCode($command)
|
||||
{
|
||||
$response = @ftp_raw($this->connection, trim($command)) ?: [];
|
||||
|
||||
return (int) preg_replace('/\D/', '', implode(' ', (array) $response));
|
||||
}
|
||||
|
||||
private function hasFtpConnection(): bool
|
||||
{
|
||||
return is_resource($this->connection) || $this->connection instanceof \FTP\Connection;
|
||||
}
|
||||
}
|
||||
48
pancake/system/vendor/league/flysystem/src/Adapter/Ftpd.php
vendored
Executable file
48
pancake/system/vendor/league/flysystem/src/Adapter/Ftpd.php
vendored
Executable file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Adapter;
|
||||
|
||||
class Ftpd extends Ftp
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getMetadata($path)
|
||||
{
|
||||
if ($path === '') {
|
||||
return ['type' => 'dir', 'path' => ''];
|
||||
}
|
||||
|
||||
if (@ftp_chdir($this->getConnection(), $path) === true) {
|
||||
$this->setConnectionRoot();
|
||||
|
||||
return ['type' => 'dir', 'path' => $path];
|
||||
}
|
||||
|
||||
$object = ftp_raw($this->getConnection(), 'STAT ' . $this->escapePath($path));
|
||||
|
||||
if ( ! $object || count($object) < 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (substr($object[1], 0, 5) === "ftpd:") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->normalizeObject($object[1], '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function listDirectoryContents($directory, $recursive = true)
|
||||
{
|
||||
$listing = ftp_rawlist($this->getConnection(), $this->escapePath($directory), $recursive);
|
||||
|
||||
if ($listing === false || ( ! empty($listing) && substr($listing[0], 0, 5) === "ftpd:")) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->normalizeListing($listing, $directory);
|
||||
}
|
||||
}
|
||||
533
pancake/system/vendor/league/flysystem/src/Adapter/Local.php
vendored
Executable file
533
pancake/system/vendor/league/flysystem/src/Adapter/Local.php
vendored
Executable file
@@ -0,0 +1,533 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Adapter;
|
||||
|
||||
use DirectoryIterator;
|
||||
use FilesystemIterator;
|
||||
use finfo as Finfo;
|
||||
use League\Flysystem\Config;
|
||||
use League\Flysystem\Exception;
|
||||
use League\Flysystem\NotSupportedException;
|
||||
use League\Flysystem\UnreadableFileException;
|
||||
use League\Flysystem\Util;
|
||||
use LogicException;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use SplFileInfo;
|
||||
|
||||
class Local extends AbstractAdapter
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
const SKIP_LINKS = 0001;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
const DISALLOW_LINKS = 0002;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $permissions = [
|
||||
'file' => [
|
||||
'public' => 0644,
|
||||
'private' => 0600,
|
||||
],
|
||||
'dir' => [
|
||||
'public' => 0755,
|
||||
'private' => 0700,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $pathSeparator = DIRECTORY_SEPARATOR;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $permissionMap;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $writeFlags;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $linkHandling;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $root
|
||||
* @param int $writeFlags
|
||||
* @param int $linkHandling
|
||||
* @param array $permissions
|
||||
*
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function __construct($root, $writeFlags = LOCK_EX, $linkHandling = self::DISALLOW_LINKS, array $permissions = [])
|
||||
{
|
||||
$root = is_link($root) ? realpath($root) : $root;
|
||||
$this->permissionMap = array_replace_recursive(static::$permissions, $permissions);
|
||||
$this->ensureDirectory($root);
|
||||
|
||||
if ( ! is_dir($root) || ! is_readable($root)) {
|
||||
throw new LogicException('The root path ' . $root . ' is not readable.');
|
||||
}
|
||||
|
||||
$this->setPathPrefix($root);
|
||||
$this->writeFlags = $writeFlags;
|
||||
$this->linkHandling = $linkHandling;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the root directory exists.
|
||||
*
|
||||
* @param string $root root directory path
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws Exception in case the root directory can not be created
|
||||
*/
|
||||
protected function ensureDirectory($root)
|
||||
{
|
||||
if ( ! is_dir($root)) {
|
||||
$umask = umask(0);
|
||||
|
||||
if ( ! @mkdir($root, $this->permissionMap['dir']['public'], true)) {
|
||||
$mkdirError = error_get_last();
|
||||
}
|
||||
|
||||
umask($umask);
|
||||
clearstatcache(false, $root);
|
||||
|
||||
if ( ! is_dir($root)) {
|
||||
$errorMessage = isset($mkdirError['message']) ? $mkdirError['message'] : '';
|
||||
throw new Exception(sprintf('Impossible to create the root directory "%s". %s', $root, $errorMessage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function has($path)
|
||||
{
|
||||
$location = $this->applyPathPrefix($path);
|
||||
|
||||
return file_exists($location);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function write($path, $contents, Config $config)
|
||||
{
|
||||
$location = $this->applyPathPrefix($path);
|
||||
$this->ensureDirectory(dirname($location));
|
||||
|
||||
if (($size = file_put_contents($location, $contents, $this->writeFlags)) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$type = 'file';
|
||||
$result = compact('contents', 'type', 'size', 'path');
|
||||
|
||||
if ($visibility = $config->get('visibility')) {
|
||||
$result['visibility'] = $visibility;
|
||||
$this->setVisibility($path, $visibility);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function writeStream($path, $resource, Config $config)
|
||||
{
|
||||
$location = $this->applyPathPrefix($path);
|
||||
$this->ensureDirectory(dirname($location));
|
||||
$stream = fopen($location, 'w+b');
|
||||
|
||||
if ( ! $stream || stream_copy_to_stream($resource, $stream) === false || ! fclose($stream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$type = 'file';
|
||||
$result = compact('type', 'path');
|
||||
|
||||
if ($visibility = $config->get('visibility')) {
|
||||
$this->setVisibility($path, $visibility);
|
||||
$result['visibility'] = $visibility;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function readStream($path)
|
||||
{
|
||||
$location = $this->applyPathPrefix($path);
|
||||
$stream = fopen($location, 'rb');
|
||||
|
||||
return ['type' => 'file', 'path' => $path, 'stream' => $stream];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function updateStream($path, $resource, Config $config)
|
||||
{
|
||||
return $this->writeStream($path, $resource, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function update($path, $contents, Config $config)
|
||||
{
|
||||
$location = $this->applyPathPrefix($path);
|
||||
$size = file_put_contents($location, $contents, $this->writeFlags);
|
||||
|
||||
if ($size === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$type = 'file';
|
||||
|
||||
$result = compact('type', 'path', 'size', 'contents');
|
||||
|
||||
if ($visibility = $config->get('visibility')) {
|
||||
$this->setVisibility($path, $visibility);
|
||||
$result['visibility'] = $visibility;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function read($path)
|
||||
{
|
||||
$location = $this->applyPathPrefix($path);
|
||||
$contents = @file_get_contents($location);
|
||||
|
||||
if ($contents === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ['type' => 'file', 'path' => $path, 'contents' => $contents];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function rename($path, $newpath)
|
||||
{
|
||||
$location = $this->applyPathPrefix($path);
|
||||
$destination = $this->applyPathPrefix($newpath);
|
||||
$parentDirectory = $this->applyPathPrefix(Util::dirname($newpath));
|
||||
$this->ensureDirectory($parentDirectory);
|
||||
|
||||
return rename($location, $destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function copy($path, $newpath)
|
||||
{
|
||||
$location = $this->applyPathPrefix($path);
|
||||
$destination = $this->applyPathPrefix($newpath);
|
||||
$this->ensureDirectory(dirname($destination));
|
||||
|
||||
return copy($location, $destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function delete($path)
|
||||
{
|
||||
$location = $this->applyPathPrefix($path);
|
||||
|
||||
return @unlink($location);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function listContents($directory = '', $recursive = false)
|
||||
{
|
||||
$result = [];
|
||||
$location = $this->applyPathPrefix($directory);
|
||||
|
||||
if ( ! is_dir($location)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$iterator = $recursive ? $this->getRecursiveDirectoryIterator($location) : $this->getDirectoryIterator($location);
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
$path = $this->getFilePath($file);
|
||||
|
||||
if (preg_match('#(^|/|\\\\)\.{1,2}$#', $path)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[] = $this->normalizeFileInfo($file);
|
||||
}
|
||||
|
||||
unset($iterator);
|
||||
|
||||
return array_filter($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getMetadata($path)
|
||||
{
|
||||
$location = $this->applyPathPrefix($path);
|
||||
clearstatcache(false, $location);
|
||||
$info = new SplFileInfo($location);
|
||||
|
||||
return $this->normalizeFileInfo($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSize($path)
|
||||
{
|
||||
return $this->getMetadata($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getMimetype($path)
|
||||
{
|
||||
$location = $this->applyPathPrefix($path);
|
||||
$finfo = new Finfo(FILEINFO_MIME_TYPE);
|
||||
$mimetype = $finfo->file($location);
|
||||
|
||||
if (in_array($mimetype, ['application/octet-stream', 'inode/x-empty', 'application/x-empty'])) {
|
||||
$mimetype = Util\MimeType::detectByFilename($location);
|
||||
}
|
||||
|
||||
return ['path' => $path, 'type' => 'file', 'mimetype' => $mimetype];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getTimestamp($path)
|
||||
{
|
||||
return $this->getMetadata($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getVisibility($path)
|
||||
{
|
||||
$location = $this->applyPathPrefix($path);
|
||||
clearstatcache(false, $location);
|
||||
$permissions = octdec(substr(sprintf('%o', fileperms($location)), -4));
|
||||
$type = is_dir($location) ? 'dir' : 'file';
|
||||
|
||||
foreach ($this->permissionMap[$type] as $visibility => $visibilityPermissions) {
|
||||
if ($visibilityPermissions == $permissions) {
|
||||
return compact('path', 'visibility');
|
||||
}
|
||||
}
|
||||
|
||||
$visibility = substr(sprintf('%o', fileperms($location)), -4);
|
||||
|
||||
return compact('path', 'visibility');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setVisibility($path, $visibility)
|
||||
{
|
||||
$location = $this->applyPathPrefix($path);
|
||||
$type = is_dir($location) ? 'dir' : 'file';
|
||||
$success = chmod($location, $this->permissionMap[$type][$visibility]);
|
||||
|
||||
if ($success === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return compact('path', 'visibility');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function createDir($dirname, Config $config)
|
||||
{
|
||||
$location = $this->applyPathPrefix($dirname);
|
||||
$umask = umask(0);
|
||||
$visibility = $config->get('visibility', 'public');
|
||||
$return = ['path' => $dirname, 'type' => 'dir'];
|
||||
|
||||
if ( ! is_dir($location)) {
|
||||
if (false === @mkdir($location, $this->permissionMap['dir'][$visibility], true)
|
||||
|| false === is_dir($location)) {
|
||||
$return = false;
|
||||
}
|
||||
}
|
||||
|
||||
umask($umask);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function deleteDir($dirname)
|
||||
{
|
||||
$location = $this->applyPathPrefix($dirname);
|
||||
|
||||
if ( ! is_dir($location)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$contents = $this->getRecursiveDirectoryIterator($location, RecursiveIteratorIterator::CHILD_FIRST);
|
||||
|
||||
/** @var SplFileInfo $file */
|
||||
foreach ($contents as $file) {
|
||||
$this->guardAgainstUnreadableFileInfo($file);
|
||||
$this->deleteFileInfoObject($file);
|
||||
}
|
||||
|
||||
unset($contents);
|
||||
|
||||
return rmdir($location);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SplFileInfo $file
|
||||
*/
|
||||
protected function deleteFileInfoObject(SplFileInfo $file)
|
||||
{
|
||||
switch ($file->getType()) {
|
||||
case 'dir':
|
||||
rmdir($file->getRealPath());
|
||||
break;
|
||||
case 'link':
|
||||
unlink($file->getPathname());
|
||||
break;
|
||||
default:
|
||||
unlink($file->getRealPath());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the file info.
|
||||
*
|
||||
* @param SplFileInfo $file
|
||||
*
|
||||
* @return array|void
|
||||
*
|
||||
* @throws NotSupportedException
|
||||
*/
|
||||
protected function normalizeFileInfo(SplFileInfo $file)
|
||||
{
|
||||
if ( ! $file->isLink()) {
|
||||
return $this->mapFileInfo($file);
|
||||
}
|
||||
|
||||
if ($this->linkHandling & self::DISALLOW_LINKS) {
|
||||
throw NotSupportedException::forLink($file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the normalized path from a SplFileInfo object.
|
||||
*
|
||||
* @param SplFileInfo $file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getFilePath(SplFileInfo $file)
|
||||
{
|
||||
$location = $file->getPathname();
|
||||
$path = $this->removePathPrefix($location);
|
||||
|
||||
return trim(str_replace('\\', '/', $path), '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param int $mode
|
||||
*
|
||||
* @return RecursiveIteratorIterator
|
||||
*/
|
||||
protected function getRecursiveDirectoryIterator($path, $mode = RecursiveIteratorIterator::SELF_FIRST)
|
||||
{
|
||||
return new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
|
||||
$mode
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*
|
||||
* @return DirectoryIterator
|
||||
*/
|
||||
protected function getDirectoryIterator($path)
|
||||
{
|
||||
$iterator = new DirectoryIterator($path);
|
||||
|
||||
return $iterator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SplFileInfo $file
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function mapFileInfo(SplFileInfo $file)
|
||||
{
|
||||
$normalized = [
|
||||
'type' => $file->getType(),
|
||||
'path' => $this->getFilePath($file),
|
||||
];
|
||||
|
||||
$normalized['timestamp'] = $file->getMTime();
|
||||
|
||||
if ($normalized['type'] === 'file') {
|
||||
$normalized['size'] = $file->getSize();
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SplFileInfo $file
|
||||
*
|
||||
* @throws UnreadableFileException
|
||||
*/
|
||||
protected function guardAgainstUnreadableFileInfo(SplFileInfo $file)
|
||||
{
|
||||
if ( ! $file->isReadable()) {
|
||||
throw UnreadableFileException::forFileInfo($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
144
pancake/system/vendor/league/flysystem/src/Adapter/NullAdapter.php
vendored
Executable file
144
pancake/system/vendor/league/flysystem/src/Adapter/NullAdapter.php
vendored
Executable file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Adapter;
|
||||
|
||||
use League\Flysystem\Adapter\Polyfill\StreamedCopyTrait;
|
||||
use League\Flysystem\Adapter\Polyfill\StreamedTrait;
|
||||
use League\Flysystem\Config;
|
||||
|
||||
class NullAdapter extends AbstractAdapter
|
||||
{
|
||||
use StreamedTrait;
|
||||
use StreamedCopyTrait;
|
||||
|
||||
/**
|
||||
* Check whether a file is present.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function write($path, $contents, Config $config)
|
||||
{
|
||||
$type = 'file';
|
||||
$result = compact('contents', 'type', 'path');
|
||||
|
||||
if ($visibility = $config->get('visibility')) {
|
||||
$result['visibility'] = $visibility;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function update($path, $contents, Config $config)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function read($path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function rename($path, $newpath)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function delete($path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function listContents($directory = '', $recursive = false)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getMetadata($path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSize($path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getMimetype($path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getTimestamp($path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getVisibility($path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setVisibility($path, $visibility)
|
||||
{
|
||||
return compact('visibility');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function createDir($dirname, Config $config)
|
||||
{
|
||||
return ['path' => $dirname, 'type' => 'dir'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function deleteDir($dirname)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
33
pancake/system/vendor/league/flysystem/src/Adapter/Polyfill/NotSupportingVisibilityTrait.php
vendored
Executable file
33
pancake/system/vendor/league/flysystem/src/Adapter/Polyfill/NotSupportingVisibilityTrait.php
vendored
Executable file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Adapter\Polyfill;
|
||||
|
||||
use LogicException;
|
||||
|
||||
trait NotSupportingVisibilityTrait
|
||||
{
|
||||
/**
|
||||
* Get the visibility of a file.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function getVisibility($path)
|
||||
{
|
||||
throw new LogicException(get_class($this) . ' does not support visibility. Path: ' . $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the visibility for a file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $visibility
|
||||
*
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function setVisibility($path, $visibility)
|
||||
{
|
||||
throw new LogicException(get_class($this) . ' does not support visibility. Path: ' . $path . ', visibility: ' . $visibility);
|
||||
}
|
||||
}
|
||||
51
pancake/system/vendor/league/flysystem/src/Adapter/Polyfill/StreamedCopyTrait.php
vendored
Executable file
51
pancake/system/vendor/league/flysystem/src/Adapter/Polyfill/StreamedCopyTrait.php
vendored
Executable file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Adapter\Polyfill;
|
||||
|
||||
use League\Flysystem\Config;
|
||||
|
||||
trait StreamedCopyTrait
|
||||
{
|
||||
/**
|
||||
* Copy a file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $newpath
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function copy($path, $newpath)
|
||||
{
|
||||
$response = $this->readStream($path);
|
||||
|
||||
if ($response === false || ! is_resource($response['stream'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = $this->writeStream($newpath, $response['stream'], new Config());
|
||||
|
||||
if ($result !== false && is_resource($response['stream'])) {
|
||||
fclose($response['stream']);
|
||||
}
|
||||
|
||||
return $result !== false;
|
||||
}
|
||||
|
||||
// Required abstract method
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
abstract public function readStream($path);
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param resource $resource
|
||||
* @param Config $config
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
abstract public function writeStream($path, $resource, Config $config);
|
||||
}
|
||||
44
pancake/system/vendor/league/flysystem/src/Adapter/Polyfill/StreamedReadingTrait.php
vendored
Executable file
44
pancake/system/vendor/league/flysystem/src/Adapter/Polyfill/StreamedReadingTrait.php
vendored
Executable file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Adapter\Polyfill;
|
||||
|
||||
/**
|
||||
* A helper for adapters that only handle strings to provide read streams.
|
||||
*/
|
||||
trait StreamedReadingTrait
|
||||
{
|
||||
/**
|
||||
* Reads a file as a stream.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return array|false
|
||||
*
|
||||
* @see League\Flysystem\ReadInterface::readStream()
|
||||
*/
|
||||
public function readStream($path)
|
||||
{
|
||||
if ( ! $data = $this->read($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$stream = fopen('php://temp', 'w+b');
|
||||
fwrite($stream, $data['contents']);
|
||||
rewind($stream);
|
||||
$data['stream'] = $stream;
|
||||
unset($data['contents']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a file.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return array|false
|
||||
*
|
||||
* @see League\Flysystem\ReadInterface::read()
|
||||
*/
|
||||
abstract public function read($path);
|
||||
}
|
||||
9
pancake/system/vendor/league/flysystem/src/Adapter/Polyfill/StreamedTrait.php
vendored
Executable file
9
pancake/system/vendor/league/flysystem/src/Adapter/Polyfill/StreamedTrait.php
vendored
Executable file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Adapter\Polyfill;
|
||||
|
||||
trait StreamedTrait
|
||||
{
|
||||
use StreamedReadingTrait;
|
||||
use StreamedWritingTrait;
|
||||
}
|
||||
60
pancake/system/vendor/league/flysystem/src/Adapter/Polyfill/StreamedWritingTrait.php
vendored
Executable file
60
pancake/system/vendor/league/flysystem/src/Adapter/Polyfill/StreamedWritingTrait.php
vendored
Executable file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Adapter\Polyfill;
|
||||
|
||||
use League\Flysystem\Config;
|
||||
use League\Flysystem\Util;
|
||||
|
||||
trait StreamedWritingTrait
|
||||
{
|
||||
/**
|
||||
* Stream fallback delegator.
|
||||
*
|
||||
* @param string $path
|
||||
* @param resource $resource
|
||||
* @param Config $config
|
||||
* @param string $fallback
|
||||
*
|
||||
* @return mixed fallback result
|
||||
*/
|
||||
protected function stream($path, $resource, Config $config, $fallback)
|
||||
{
|
||||
Util::rewindStream($resource);
|
||||
$contents = stream_get_contents($resource);
|
||||
$fallbackCall = [$this, $fallback];
|
||||
|
||||
return call_user_func($fallbackCall, $path, $contents, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write using a stream.
|
||||
*
|
||||
* @param string $path
|
||||
* @param resource $resource
|
||||
* @param Config $config
|
||||
*
|
||||
* @return mixed false or file metadata
|
||||
*/
|
||||
public function writeStream($path, $resource, Config $config)
|
||||
{
|
||||
return $this->stream($path, $resource, $config, 'write');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a file using a stream.
|
||||
*
|
||||
* @param string $path
|
||||
* @param resource $resource
|
||||
* @param Config $config Config object or visibility setting
|
||||
*
|
||||
* @return mixed false of file metadata
|
||||
*/
|
||||
public function updateStream($path, $resource, Config $config)
|
||||
{
|
||||
return $this->stream($path, $resource, $config, 'update');
|
||||
}
|
||||
|
||||
// Required abstract methods
|
||||
abstract public function write($pash, $contents, Config $config);
|
||||
abstract public function update($pash, $contents, Config $config);
|
||||
}
|
||||
8
pancake/system/vendor/league/flysystem/src/Adapter/SynologyFtp.php
vendored
Executable file
8
pancake/system/vendor/league/flysystem/src/Adapter/SynologyFtp.php
vendored
Executable file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Adapter;
|
||||
|
||||
class SynologyFtp extends Ftpd
|
||||
{
|
||||
// This class merely exists because of BC.
|
||||
}
|
||||
118
pancake/system/vendor/league/flysystem/src/AdapterInterface.php
vendored
Executable file
118
pancake/system/vendor/league/flysystem/src/AdapterInterface.php
vendored
Executable file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
interface AdapterInterface extends ReadInterface
|
||||
{
|
||||
/**
|
||||
* @const VISIBILITY_PUBLIC public visibility
|
||||
*/
|
||||
const VISIBILITY_PUBLIC = 'public';
|
||||
|
||||
/**
|
||||
* @const VISIBILITY_PRIVATE private visibility
|
||||
*/
|
||||
const VISIBILITY_PRIVATE = 'private';
|
||||
|
||||
/**
|
||||
* Write a new file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $contents
|
||||
* @param Config $config Config object
|
||||
*
|
||||
* @return array|false false on failure file meta data on success
|
||||
*/
|
||||
public function write($path, $contents, Config $config);
|
||||
|
||||
/**
|
||||
* Write a new file using a stream.
|
||||
*
|
||||
* @param string $path
|
||||
* @param resource $resource
|
||||
* @param Config $config Config object
|
||||
*
|
||||
* @return array|false false on failure file meta data on success
|
||||
*/
|
||||
public function writeStream($path, $resource, Config $config);
|
||||
|
||||
/**
|
||||
* Update a file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $contents
|
||||
* @param Config $config Config object
|
||||
*
|
||||
* @return array|false false on failure file meta data on success
|
||||
*/
|
||||
public function update($path, $contents, Config $config);
|
||||
|
||||
/**
|
||||
* Update a file using a stream.
|
||||
*
|
||||
* @param string $path
|
||||
* @param resource $resource
|
||||
* @param Config $config Config object
|
||||
*
|
||||
* @return array|false false on failure file meta data on success
|
||||
*/
|
||||
public function updateStream($path, $resource, Config $config);
|
||||
|
||||
/**
|
||||
* Rename a file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $newpath
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function rename($path, $newpath);
|
||||
|
||||
/**
|
||||
* Copy a file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $newpath
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function copy($path, $newpath);
|
||||
|
||||
/**
|
||||
* Delete a file.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete($path);
|
||||
|
||||
/**
|
||||
* Delete a directory.
|
||||
*
|
||||
* @param string $dirname
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteDir($dirname);
|
||||
|
||||
/**
|
||||
* Create a directory.
|
||||
*
|
||||
* @param string $dirname directory name
|
||||
* @param Config $config
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
public function createDir($dirname, Config $config);
|
||||
|
||||
/**
|
||||
* Set the visibility for a file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $visibility
|
||||
*
|
||||
* @return array|false file meta data
|
||||
*/
|
||||
public function setVisibility($path, $visibility);
|
||||
}
|
||||
107
pancake/system/vendor/league/flysystem/src/Config.php
vendored
Executable file
107
pancake/system/vendor/league/flysystem/src/Config.php
vendored
Executable file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
class Config
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings = [];
|
||||
|
||||
/**
|
||||
* @var Config|null
|
||||
*/
|
||||
protected $fallback;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct(array $settings = [])
|
||||
{
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a setting.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed config setting or default when not found
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
if ( ! array_key_exists($key, $this->settings)) {
|
||||
return $this->getDefault($key, $default);
|
||||
}
|
||||
|
||||
return $this->settings[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an item exists by key.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
if (array_key_exists($key, $this->settings)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->fallback instanceof Config
|
||||
? $this->fallback->has($key)
|
||||
: false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to retrieve a default setting from a config fallback.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed config setting or default when not found
|
||||
*/
|
||||
protected function getDefault($key, $default)
|
||||
{
|
||||
if ( ! $this->fallback) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->fallback->get($key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a setting.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->settings[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fallback.
|
||||
*
|
||||
* @param Config $fallback
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFallback(Config $fallback)
|
||||
{
|
||||
$this->fallback = $fallback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
49
pancake/system/vendor/league/flysystem/src/ConfigAwareTrait.php
vendored
Executable file
49
pancake/system/vendor/league/flysystem/src/ConfigAwareTrait.php
vendored
Executable file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
trait ConfigAwareTrait
|
||||
{
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Set the config.
|
||||
*
|
||||
* @param Config|array|null $config
|
||||
*/
|
||||
protected function setConfig($config)
|
||||
{
|
||||
$this->config = $config ? Util::ensureConfig($config) : new Config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Config.
|
||||
*
|
||||
* @return Config config object
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a config array to a Config object with the correct fallback.
|
||||
*
|
||||
* @param array $config
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
protected function prepareConfig(array $config)
|
||||
{
|
||||
$config = new Config($config);
|
||||
$config->setFallback($this->getConfig());
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
9
pancake/system/vendor/league/flysystem/src/ConnectionErrorException.php
vendored
Executable file
9
pancake/system/vendor/league/flysystem/src/ConnectionErrorException.php
vendored
Executable file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
use ErrorException;
|
||||
|
||||
class ConnectionErrorException extends ErrorException implements FilesystemException
|
||||
{
|
||||
}
|
||||
9
pancake/system/vendor/league/flysystem/src/ConnectionRuntimeException.php
vendored
Executable file
9
pancake/system/vendor/league/flysystem/src/ConnectionRuntimeException.php
vendored
Executable file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class ConnectionRuntimeException extends RuntimeException implements FilesystemException
|
||||
{
|
||||
}
|
||||
17
pancake/system/vendor/league/flysystem/src/CorruptedPathDetected.php
vendored
Executable file
17
pancake/system/vendor/league/flysystem/src/CorruptedPathDetected.php
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
use LogicException;
|
||||
|
||||
class CorruptedPathDetected extends LogicException implements FilesystemException
|
||||
{
|
||||
/**
|
||||
* @param string $path
|
||||
* @return CorruptedPathDetected
|
||||
*/
|
||||
public static function forPath($path)
|
||||
{
|
||||
return new CorruptedPathDetected("Corrupted path detected: " . $path);
|
||||
}
|
||||
}
|
||||
31
pancake/system/vendor/league/flysystem/src/Directory.php
vendored
Executable file
31
pancake/system/vendor/league/flysystem/src/Directory.php
vendored
Executable file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
class Directory extends Handler
|
||||
{
|
||||
/**
|
||||
* Delete the directory.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
return $this->filesystem->deleteDir($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* List the directory contents.
|
||||
*
|
||||
* @param bool $recursive
|
||||
*
|
||||
* @return array|bool directory contents or false
|
||||
*/
|
||||
public function getContents($recursive = false)
|
||||
{
|
||||
return $this->filesystem->listContents($this->path, $recursive);
|
||||
}
|
||||
}
|
||||
8
pancake/system/vendor/league/flysystem/src/Exception.php
vendored
Executable file
8
pancake/system/vendor/league/flysystem/src/Exception.php
vendored
Executable file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
class Exception extends \Exception implements FilesystemException
|
||||
{
|
||||
//
|
||||
}
|
||||
205
pancake/system/vendor/league/flysystem/src/File.php
vendored
Executable file
205
pancake/system/vendor/league/flysystem/src/File.php
vendored
Executable file
@@ -0,0 +1,205 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
class File extends Handler
|
||||
{
|
||||
/**
|
||||
* Check whether the file exists.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exists()
|
||||
{
|
||||
return $this->filesystem->has($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the file.
|
||||
*
|
||||
* @return string|false file contents
|
||||
*/
|
||||
public function read()
|
||||
{
|
||||
return $this->filesystem->read($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the file as a stream.
|
||||
*
|
||||
* @return resource|false file stream
|
||||
*/
|
||||
public function readStream()
|
||||
{
|
||||
return $this->filesystem->readStream($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the new file.
|
||||
*
|
||||
* @param string $content
|
||||
*
|
||||
* @return bool success boolean
|
||||
*/
|
||||
public function write($content)
|
||||
{
|
||||
return $this->filesystem->write($this->path, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the new file using a stream.
|
||||
*
|
||||
* @param resource $resource
|
||||
*
|
||||
* @return bool success boolean
|
||||
*/
|
||||
public function writeStream($resource)
|
||||
{
|
||||
return $this->filesystem->writeStream($this->path, $resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the file contents.
|
||||
*
|
||||
* @param string $content
|
||||
*
|
||||
* @return bool success boolean
|
||||
*/
|
||||
public function update($content)
|
||||
{
|
||||
return $this->filesystem->update($this->path, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the file contents with a stream.
|
||||
*
|
||||
* @param resource $resource
|
||||
*
|
||||
* @return bool success boolean
|
||||
*/
|
||||
public function updateStream($resource)
|
||||
{
|
||||
return $this->filesystem->updateStream($this->path, $resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the file or update if exists.
|
||||
*
|
||||
* @param string $content
|
||||
*
|
||||
* @return bool success boolean
|
||||
*/
|
||||
public function put($content)
|
||||
{
|
||||
return $this->filesystem->put($this->path, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the file or update if exists using a stream.
|
||||
*
|
||||
* @param resource $resource
|
||||
*
|
||||
* @return bool success boolean
|
||||
*/
|
||||
public function putStream($resource)
|
||||
{
|
||||
return $this->filesystem->putStream($this->path, $resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename the file.
|
||||
*
|
||||
* @param string $newpath
|
||||
*
|
||||
* @return bool success boolean
|
||||
*/
|
||||
public function rename($newpath)
|
||||
{
|
||||
if ($this->filesystem->rename($this->path, $newpath)) {
|
||||
$this->path = $newpath;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the file.
|
||||
*
|
||||
* @param string $newpath
|
||||
*
|
||||
* @return File|false new file or false
|
||||
*/
|
||||
public function copy($newpath)
|
||||
{
|
||||
if ($this->filesystem->copy($this->path, $newpath)) {
|
||||
return new File($this->filesystem, $newpath);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file's timestamp.
|
||||
*
|
||||
* @return string|false The timestamp or false on failure.
|
||||
*/
|
||||
public function getTimestamp()
|
||||
{
|
||||
return $this->filesystem->getTimestamp($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file's mimetype.
|
||||
*
|
||||
* @return string|false The file mime-type or false on failure.
|
||||
*/
|
||||
public function getMimetype()
|
||||
{
|
||||
return $this->filesystem->getMimetype($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file's visibility.
|
||||
*
|
||||
* @return string|false The visibility (public|private) or false on failure.
|
||||
*/
|
||||
public function getVisibility()
|
||||
{
|
||||
return $this->filesystem->getVisibility($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file's metadata.
|
||||
*
|
||||
* @return array|false The file metadata or false on failure.
|
||||
*/
|
||||
public function getMetadata()
|
||||
{
|
||||
return $this->filesystem->getMetadata($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file size.
|
||||
*
|
||||
* @return int|false The file size or false on failure.
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
return $this->filesystem->getSize($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the file.
|
||||
*
|
||||
* @return bool success boolean
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
return $this->filesystem->delete($this->path);
|
||||
}
|
||||
}
|
||||
37
pancake/system/vendor/league/flysystem/src/FileExistsException.php
vendored
Executable file
37
pancake/system/vendor/league/flysystem/src/FileExistsException.php
vendored
Executable file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
use Exception as BaseException;
|
||||
|
||||
class FileExistsException extends Exception
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $path
|
||||
* @param int $code
|
||||
* @param BaseException $previous
|
||||
*/
|
||||
public function __construct($path, $code = 0, BaseException $previous = null)
|
||||
{
|
||||
$this->path = $path;
|
||||
|
||||
parent::__construct('File already exists at path: ' . $this->getPath(), $code, $previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path which was found.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
}
|
||||
37
pancake/system/vendor/league/flysystem/src/FileNotFoundException.php
vendored
Executable file
37
pancake/system/vendor/league/flysystem/src/FileNotFoundException.php
vendored
Executable file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
use Exception as BaseException;
|
||||
|
||||
class FileNotFoundException extends Exception
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $path
|
||||
* @param int $code
|
||||
* @param \Exception $previous
|
||||
*/
|
||||
public function __construct($path, $code = 0, BaseException $previous = null)
|
||||
{
|
||||
$this->path = $path;
|
||||
|
||||
parent::__construct('File not found at path: ' . $this->getPath(), $code, $previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path which was not found.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
}
|
||||
409
pancake/system/vendor/league/flysystem/src/Filesystem.php
vendored
Executable file
409
pancake/system/vendor/league/flysystem/src/Filesystem.php
vendored
Executable file
@@ -0,0 +1,409 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use League\Flysystem\Adapter\CanOverwriteFiles;
|
||||
use League\Flysystem\Plugin\PluggableTrait;
|
||||
use League\Flysystem\Util\ContentListingFormatter;
|
||||
|
||||
/**
|
||||
* @method void emptyDir(string $dirname)
|
||||
* @method array|false getWithMetadata(string $path, string[] $metadata)
|
||||
* @method bool forceCopy(string $path, string $newpath)
|
||||
* @method bool forceRename(string $path, string $newpath)
|
||||
* @method array listFiles(string $path = '', boolean $recursive = false)
|
||||
* @method string[] listPaths(string $path = '', boolean $recursive = false)
|
||||
* @method array listWith(string[] $keys = [], $directory = '', $recursive = false)
|
||||
*/
|
||||
class Filesystem implements FilesystemInterface
|
||||
{
|
||||
use PluggableTrait;
|
||||
use ConfigAwareTrait;
|
||||
|
||||
/**
|
||||
* @var AdapterInterface
|
||||
*/
|
||||
protected $adapter;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param AdapterInterface $adapter
|
||||
* @param Config|array $config
|
||||
*/
|
||||
public function __construct(AdapterInterface $adapter, $config = null)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
$this->setConfig($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Adapter.
|
||||
*
|
||||
* @return AdapterInterface adapter
|
||||
*/
|
||||
public function getAdapter()
|
||||
{
|
||||
return $this->adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function has($path)
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
|
||||
return strlen($path) === 0 ? false : (bool) $this->getAdapter()->has($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function write($path, $contents, array $config = [])
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
$this->assertAbsent($path);
|
||||
$config = $this->prepareConfig($config);
|
||||
|
||||
return (bool) $this->getAdapter()->write($path, $contents, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function writeStream($path, $resource, array $config = [])
|
||||
{
|
||||
if ( ! is_resource($resource) || get_resource_type($resource) !== 'stream') {
|
||||
throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.');
|
||||
}
|
||||
|
||||
$path = Util::normalizePath($path);
|
||||
$this->assertAbsent($path);
|
||||
$config = $this->prepareConfig($config);
|
||||
|
||||
Util::rewindStream($resource);
|
||||
|
||||
return (bool) $this->getAdapter()->writeStream($path, $resource, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function put($path, $contents, array $config = [])
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
$config = $this->prepareConfig($config);
|
||||
|
||||
if ( ! $this->getAdapter() instanceof CanOverwriteFiles && $this->has($path)) {
|
||||
return (bool) $this->getAdapter()->update($path, $contents, $config);
|
||||
}
|
||||
|
||||
return (bool) $this->getAdapter()->write($path, $contents, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function putStream($path, $resource, array $config = [])
|
||||
{
|
||||
if ( ! is_resource($resource) || get_resource_type($resource) !== 'stream') {
|
||||
throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.');
|
||||
}
|
||||
|
||||
$path = Util::normalizePath($path);
|
||||
$config = $this->prepareConfig($config);
|
||||
Util::rewindStream($resource);
|
||||
|
||||
if ( ! $this->getAdapter() instanceof CanOverwriteFiles && $this->has($path)) {
|
||||
return (bool) $this->getAdapter()->updateStream($path, $resource, $config);
|
||||
}
|
||||
|
||||
return (bool) $this->getAdapter()->writeStream($path, $resource, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function readAndDelete($path)
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
$this->assertPresent($path);
|
||||
$contents = $this->read($path);
|
||||
|
||||
if ($contents === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->delete($path);
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function update($path, $contents, array $config = [])
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
$config = $this->prepareConfig($config);
|
||||
|
||||
$this->assertPresent($path);
|
||||
|
||||
return (bool) $this->getAdapter()->update($path, $contents, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function updateStream($path, $resource, array $config = [])
|
||||
{
|
||||
if ( ! is_resource($resource) || get_resource_type($resource) !== 'stream') {
|
||||
throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.');
|
||||
}
|
||||
|
||||
$path = Util::normalizePath($path);
|
||||
$config = $this->prepareConfig($config);
|
||||
$this->assertPresent($path);
|
||||
Util::rewindStream($resource);
|
||||
|
||||
return (bool) $this->getAdapter()->updateStream($path, $resource, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function read($path)
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
$this->assertPresent($path);
|
||||
|
||||
if ( ! ($object = $this->getAdapter()->read($path))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $object['contents'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function readStream($path)
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
$this->assertPresent($path);
|
||||
|
||||
if ( ! $object = $this->getAdapter()->readStream($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $object['stream'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function rename($path, $newpath)
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
$newpath = Util::normalizePath($newpath);
|
||||
$this->assertPresent($path);
|
||||
$this->assertAbsent($newpath);
|
||||
|
||||
return (bool) $this->getAdapter()->rename($path, $newpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function copy($path, $newpath)
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
$newpath = Util::normalizePath($newpath);
|
||||
$this->assertPresent($path);
|
||||
$this->assertAbsent($newpath);
|
||||
|
||||
return $this->getAdapter()->copy($path, $newpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function delete($path)
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
$this->assertPresent($path);
|
||||
|
||||
return $this->getAdapter()->delete($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function deleteDir($dirname)
|
||||
{
|
||||
$dirname = Util::normalizePath($dirname);
|
||||
|
||||
if ($dirname === '') {
|
||||
throw new RootViolationException('Root directories can not be deleted.');
|
||||
}
|
||||
|
||||
return (bool) $this->getAdapter()->deleteDir($dirname);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function createDir($dirname, array $config = [])
|
||||
{
|
||||
$dirname = Util::normalizePath($dirname);
|
||||
$config = $this->prepareConfig($config);
|
||||
|
||||
return (bool) $this->getAdapter()->createDir($dirname, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function listContents($directory = '', $recursive = false)
|
||||
{
|
||||
$directory = Util::normalizePath($directory);
|
||||
$contents = $this->getAdapter()->listContents($directory, $recursive);
|
||||
|
||||
return (new ContentListingFormatter($directory, $recursive, $this->config->get('case_sensitive', true)))
|
||||
->formatListing($contents);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getMimetype($path)
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
$this->assertPresent($path);
|
||||
|
||||
if (( ! $object = $this->getAdapter()->getMimetype($path)) || ! array_key_exists('mimetype', $object)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $object['mimetype'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getTimestamp($path)
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
$this->assertPresent($path);
|
||||
|
||||
if (( ! $object = $this->getAdapter()->getTimestamp($path)) || ! array_key_exists('timestamp', $object)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (int) $object['timestamp'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getVisibility($path)
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
$this->assertPresent($path);
|
||||
|
||||
if (( ! $object = $this->getAdapter()->getVisibility($path)) || ! array_key_exists('visibility', $object)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $object['visibility'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSize($path)
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
$this->assertPresent($path);
|
||||
|
||||
if (( ! $object = $this->getAdapter()->getSize($path)) || ! array_key_exists('size', $object)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (int) $object['size'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setVisibility($path, $visibility)
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
$this->assertPresent($path);
|
||||
|
||||
return (bool) $this->getAdapter()->setVisibility($path, $visibility);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getMetadata($path)
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
$this->assertPresent($path);
|
||||
|
||||
return $this->getAdapter()->getMetadata($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function get($path, Handler $handler = null)
|
||||
{
|
||||
$path = Util::normalizePath($path);
|
||||
|
||||
if ( ! $handler) {
|
||||
$metadata = $this->getMetadata($path);
|
||||
$handler = ($metadata && $metadata['type'] === 'file') ? new File($this, $path) : new Directory($this, $path);
|
||||
}
|
||||
|
||||
$handler->setPath($path);
|
||||
$handler->setFilesystem($this);
|
||||
|
||||
return $handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert a file is present.
|
||||
*
|
||||
* @param string $path path to file
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function assertPresent($path)
|
||||
{
|
||||
if ($this->config->get('disable_asserts', false) === false && ! $this->has($path)) {
|
||||
throw new FileNotFoundException($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert a file is absent.
|
||||
*
|
||||
* @param string $path path to file
|
||||
*
|
||||
* @throws FileExistsException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function assertAbsent($path)
|
||||
{
|
||||
if ($this->config->get('disable_asserts', false) === false && $this->has($path)) {
|
||||
throw new FileExistsException($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
7
pancake/system/vendor/league/flysystem/src/FilesystemException.php
vendored
Executable file
7
pancake/system/vendor/league/flysystem/src/FilesystemException.php
vendored
Executable file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
interface FilesystemException
|
||||
{
|
||||
}
|
||||
284
pancake/system/vendor/league/flysystem/src/FilesystemInterface.php
vendored
Executable file
284
pancake/system/vendor/league/flysystem/src/FilesystemInterface.php
vendored
Executable file
@@ -0,0 +1,284 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
interface FilesystemInterface
|
||||
{
|
||||
/**
|
||||
* Check whether a file exists.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($path);
|
||||
|
||||
/**
|
||||
* Read a file.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return string|false The file contents or false on failure.
|
||||
*/
|
||||
public function read($path);
|
||||
|
||||
/**
|
||||
* Retrieves a read-stream for a path.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return resource|false The path resource or false on failure.
|
||||
*/
|
||||
public function readStream($path);
|
||||
|
||||
/**
|
||||
* List contents of a directory.
|
||||
*
|
||||
* @param string $directory The directory to list.
|
||||
* @param bool $recursive Whether to list recursively.
|
||||
*
|
||||
* @return array A list of file metadata.
|
||||
*/
|
||||
public function listContents($directory = '', $recursive = false);
|
||||
|
||||
/**
|
||||
* Get a file's metadata.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return array|false The file metadata or false on failure.
|
||||
*/
|
||||
public function getMetadata($path);
|
||||
|
||||
/**
|
||||
* Get a file's size.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return int|false The file size or false on failure.
|
||||
*/
|
||||
public function getSize($path);
|
||||
|
||||
/**
|
||||
* Get a file's mime-type.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return string|false The file mime-type or false on failure.
|
||||
*/
|
||||
public function getMimetype($path);
|
||||
|
||||
/**
|
||||
* Get a file's timestamp.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return int|false The timestamp or false on failure.
|
||||
*/
|
||||
public function getTimestamp($path);
|
||||
|
||||
/**
|
||||
* Get a file's visibility.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return string|false The visibility (public|private) or false on failure.
|
||||
*/
|
||||
public function getVisibility($path);
|
||||
|
||||
/**
|
||||
* Write a new file.
|
||||
*
|
||||
* @param string $path The path of the new file.
|
||||
* @param string $contents The file contents.
|
||||
* @param array $config An optional configuration array.
|
||||
*
|
||||
* @throws FileExistsException
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function write($path, $contents, array $config = []);
|
||||
|
||||
/**
|
||||
* Write a new file using a stream.
|
||||
*
|
||||
* @param string $path The path of the new file.
|
||||
* @param resource $resource The file handle.
|
||||
* @param array $config An optional configuration array.
|
||||
*
|
||||
* @throws InvalidArgumentException If $resource is not a file handle.
|
||||
* @throws FileExistsException
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function writeStream($path, $resource, array $config = []);
|
||||
|
||||
/**
|
||||
* Update an existing file.
|
||||
*
|
||||
* @param string $path The path of the existing file.
|
||||
* @param string $contents The file contents.
|
||||
* @param array $config An optional configuration array.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function update($path, $contents, array $config = []);
|
||||
|
||||
/**
|
||||
* Update an existing file using a stream.
|
||||
*
|
||||
* @param string $path The path of the existing file.
|
||||
* @param resource $resource The file handle.
|
||||
* @param array $config An optional configuration array.
|
||||
*
|
||||
* @throws InvalidArgumentException If $resource is not a file handle.
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function updateStream($path, $resource, array $config = []);
|
||||
|
||||
/**
|
||||
* Rename a file.
|
||||
*
|
||||
* @param string $path Path to the existing file.
|
||||
* @param string $newpath The new path of the file.
|
||||
*
|
||||
* @throws FileExistsException Thrown if $newpath exists.
|
||||
* @throws FileNotFoundException Thrown if $path does not exist.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function rename($path, $newpath);
|
||||
|
||||
/**
|
||||
* Copy a file.
|
||||
*
|
||||
* @param string $path Path to the existing file.
|
||||
* @param string $newpath The new path of the file.
|
||||
*
|
||||
* @throws FileExistsException Thrown if $newpath exists.
|
||||
* @throws FileNotFoundException Thrown if $path does not exist.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function copy($path, $newpath);
|
||||
|
||||
/**
|
||||
* Delete a file.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function delete($path);
|
||||
|
||||
/**
|
||||
* Delete a directory.
|
||||
*
|
||||
* @param string $dirname
|
||||
*
|
||||
* @throws RootViolationException Thrown if $dirname is empty.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function deleteDir($dirname);
|
||||
|
||||
/**
|
||||
* Create a directory.
|
||||
*
|
||||
* @param string $dirname The name of the new directory.
|
||||
* @param array $config An optional configuration array.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function createDir($dirname, array $config = []);
|
||||
|
||||
/**
|
||||
* Set the visibility for a file.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
* @param string $visibility One of 'public' or 'private'.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function setVisibility($path, $visibility);
|
||||
|
||||
/**
|
||||
* Create a file or update if exists.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
* @param string $contents The file contents.
|
||||
* @param array $config An optional configuration array.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function put($path, $contents, array $config = []);
|
||||
|
||||
/**
|
||||
* Create a file or update if exists.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
* @param resource $resource The file handle.
|
||||
* @param array $config An optional configuration array.
|
||||
*
|
||||
* @throws InvalidArgumentException Thrown if $resource is not a resource.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function putStream($path, $resource, array $config = []);
|
||||
|
||||
/**
|
||||
* Read and delete a file.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return string|false The file contents, or false on failure.
|
||||
*/
|
||||
public function readAndDelete($path);
|
||||
|
||||
/**
|
||||
* Get a file/directory handler.
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
* @param Handler $handler An optional existing handler to populate.
|
||||
*
|
||||
* @return Handler Either a file or directory handler.
|
||||
*/
|
||||
public function get($path, Handler $handler = null);
|
||||
|
||||
/**
|
||||
* Register a plugin.
|
||||
*
|
||||
* @param PluginInterface $plugin The plugin to register.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addPlugin(PluginInterface $plugin);
|
||||
}
|
||||
12
pancake/system/vendor/league/flysystem/src/FilesystemNotFoundException.php
vendored
Executable file
12
pancake/system/vendor/league/flysystem/src/FilesystemNotFoundException.php
vendored
Executable file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
use LogicException;
|
||||
|
||||
/**
|
||||
* Thrown when the MountManager cannot find a filesystem.
|
||||
*/
|
||||
class FilesystemNotFoundException extends LogicException implements FilesystemException
|
||||
{
|
||||
}
|
||||
137
pancake/system/vendor/league/flysystem/src/Handler.php
vendored
Executable file
137
pancake/system/vendor/league/flysystem/src/Handler.php
vendored
Executable file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
use BadMethodCallException;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
abstract class Handler
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* @var FilesystemInterface
|
||||
*/
|
||||
protected $filesystem;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param FilesystemInterface $filesystem
|
||||
* @param string $path
|
||||
*/
|
||||
public function __construct(FilesystemInterface $filesystem = null, $path = null)
|
||||
{
|
||||
$this->path = $path;
|
||||
$this->filesystem = $filesystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the entree is a directory.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDir()
|
||||
{
|
||||
return $this->getType() === 'dir';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the entree is a file.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isFile()
|
||||
{
|
||||
return $this->getType() === 'file';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entree type (file|dir).
|
||||
*
|
||||
* @return string file or dir
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
$metadata = $this->filesystem->getMetadata($this->path);
|
||||
|
||||
return $metadata ? $metadata['type'] : 'dir';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Filesystem object.
|
||||
*
|
||||
* @param FilesystemInterface $filesystem
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFilesystem(FilesystemInterface $filesystem)
|
||||
{
|
||||
$this->filesystem = $filesystem;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the Filesystem object.
|
||||
*
|
||||
* @return FilesystemInterface
|
||||
*/
|
||||
public function getFilesystem()
|
||||
{
|
||||
return $this->filesystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the entree path.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPath($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entree path.
|
||||
*
|
||||
* @return string path
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugins pass-through.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, array $arguments)
|
||||
{
|
||||
array_unshift($arguments, $this->path);
|
||||
$callback = [$this->filesystem, $method];
|
||||
|
||||
try {
|
||||
return call_user_func_array($callback, $arguments);
|
||||
} catch (BadMethodCallException $e) {
|
||||
throw new BadMethodCallException(
|
||||
'Call to undefined method '
|
||||
. get_called_class()
|
||||
. '::' . $method
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
9
pancake/system/vendor/league/flysystem/src/InvalidRootException.php
vendored
Executable file
9
pancake/system/vendor/league/flysystem/src/InvalidRootException.php
vendored
Executable file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class InvalidRootException extends RuntimeException implements FilesystemException
|
||||
{
|
||||
}
|
||||
648
pancake/system/vendor/league/flysystem/src/MountManager.php
vendored
Executable file
648
pancake/system/vendor/league/flysystem/src/MountManager.php
vendored
Executable file
@@ -0,0 +1,648 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use League\Flysystem\Plugin\PluggableTrait;
|
||||
use League\Flysystem\Plugin\PluginNotFoundException;
|
||||
|
||||
/**
|
||||
* Class MountManager.
|
||||
*
|
||||
* Proxies methods to Filesystem (@see __call):
|
||||
*
|
||||
* @method AdapterInterface getAdapter($prefix)
|
||||
* @method Config getConfig($prefix)
|
||||
* @method array listFiles($directory = '', $recursive = false)
|
||||
* @method array listPaths($directory = '', $recursive = false)
|
||||
* @method array getWithMetadata($path, array $metadata)
|
||||
* @method Filesystem flushCache()
|
||||
* @method void assertPresent($path)
|
||||
* @method void assertAbsent($path)
|
||||
* @method Filesystem addPlugin(PluginInterface $plugin)
|
||||
*/
|
||||
class MountManager implements FilesystemInterface
|
||||
{
|
||||
use PluggableTrait;
|
||||
|
||||
/**
|
||||
* @var FilesystemInterface[]
|
||||
*/
|
||||
protected $filesystems = [];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param FilesystemInterface[] $filesystems [:prefix => Filesystem,]
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $filesystems = [])
|
||||
{
|
||||
$this->mountFilesystems($filesystems);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mount filesystems.
|
||||
*
|
||||
* @param FilesystemInterface[] $filesystems [:prefix => Filesystem,]
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function mountFilesystems(array $filesystems)
|
||||
{
|
||||
foreach ($filesystems as $prefix => $filesystem) {
|
||||
$this->mountFilesystem($prefix, $filesystem);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mount filesystems.
|
||||
*
|
||||
* @param string $prefix
|
||||
* @param FilesystemInterface $filesystem
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function mountFilesystem($prefix, FilesystemInterface $filesystem)
|
||||
{
|
||||
if ( ! is_string($prefix)) {
|
||||
throw new InvalidArgumentException(__METHOD__ . ' expects argument #1 to be a string.');
|
||||
}
|
||||
|
||||
$this->filesystems[$prefix] = $filesystem;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filesystem with the corresponding prefix.
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @throws FilesystemNotFoundException
|
||||
*
|
||||
* @return FilesystemInterface
|
||||
*/
|
||||
public function getFilesystem($prefix)
|
||||
{
|
||||
if ( ! isset($this->filesystems[$prefix])) {
|
||||
throw new FilesystemNotFoundException('No filesystem mounted with prefix ' . $prefix);
|
||||
}
|
||||
|
||||
return $this->filesystems[$prefix];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the prefix from an arguments array.
|
||||
*
|
||||
* @param array $arguments
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return array [:prefix, :arguments]
|
||||
*/
|
||||
public function filterPrefix(array $arguments)
|
||||
{
|
||||
if (empty($arguments)) {
|
||||
throw new InvalidArgumentException('At least one argument needed');
|
||||
}
|
||||
|
||||
$path = array_shift($arguments);
|
||||
|
||||
if ( ! is_string($path)) {
|
||||
throw new InvalidArgumentException('First argument should be a string');
|
||||
}
|
||||
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
array_unshift($arguments, $path);
|
||||
|
||||
return [$prefix, $arguments];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $directory
|
||||
* @param bool $recursive
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws FilesystemNotFoundException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listContents($directory = '', $recursive = false)
|
||||
{
|
||||
list($prefix, $directory) = $this->getPrefixAndPath($directory);
|
||||
$filesystem = $this->getFilesystem($prefix);
|
||||
$result = $filesystem->listContents($directory, $recursive);
|
||||
|
||||
foreach ($result as &$file) {
|
||||
$file['filesystem'] = $prefix;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call forwarder.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws FilesystemNotFoundException
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $arguments)
|
||||
{
|
||||
list($prefix, $arguments) = $this->filterPrefix($arguments);
|
||||
|
||||
return $this->invokePluginOnFilesystem($method, $arguments, $prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
* @param array $config
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws FilesystemNotFoundException
|
||||
* @throws FileExistsException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function copy($from, $to, array $config = [])
|
||||
{
|
||||
list($prefixFrom, $from) = $this->getPrefixAndPath($from);
|
||||
|
||||
$buffer = $this->getFilesystem($prefixFrom)->readStream($from);
|
||||
|
||||
if ($buffer === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
list($prefixTo, $to) = $this->getPrefixAndPath($to);
|
||||
|
||||
$result = $this->getFilesystem($prefixTo)->writeStream($to, $buffer, $config);
|
||||
|
||||
if (is_resource($buffer)) {
|
||||
fclose($buffer);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* List with plugin adapter.
|
||||
*
|
||||
* @param array $keys
|
||||
* @param string $directory
|
||||
* @param bool $recursive
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws FilesystemNotFoundException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listWith(array $keys = [], $directory = '', $recursive = false)
|
||||
{
|
||||
list($prefix, $directory) = $this->getPrefixAndPath($directory);
|
||||
$arguments = [$keys, $directory, $recursive];
|
||||
|
||||
return $this->invokePluginOnFilesystem('listWith', $arguments, $prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a file.
|
||||
*
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
* @param array $config
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws FilesystemNotFoundException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function move($from, $to, array $config = [])
|
||||
{
|
||||
list($prefixFrom, $pathFrom) = $this->getPrefixAndPath($from);
|
||||
list($prefixTo, $pathTo) = $this->getPrefixAndPath($to);
|
||||
|
||||
if ($prefixFrom === $prefixTo) {
|
||||
$filesystem = $this->getFilesystem($prefixFrom);
|
||||
$renamed = $filesystem->rename($pathFrom, $pathTo);
|
||||
|
||||
if ($renamed && isset($config['visibility'])) {
|
||||
return $filesystem->setVisibility($pathTo, $config['visibility']);
|
||||
}
|
||||
|
||||
return $renamed;
|
||||
}
|
||||
|
||||
$copied = $this->copy($from, $to, $config);
|
||||
|
||||
if ($copied) {
|
||||
return $this->delete($from);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke a plugin on a filesystem mounted on a given prefix.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
* @param string $prefix
|
||||
*
|
||||
* @throws FilesystemNotFoundException
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function invokePluginOnFilesystem($method, $arguments, $prefix)
|
||||
{
|
||||
$filesystem = $this->getFilesystem($prefix);
|
||||
|
||||
try {
|
||||
return $this->invokePlugin($method, $arguments, $filesystem);
|
||||
} catch (PluginNotFoundException $e) {
|
||||
// Let it pass, it's ok, don't panic.
|
||||
}
|
||||
|
||||
$callback = [$filesystem, $method];
|
||||
|
||||
return call_user_func_array($callback, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return string[] [:prefix, :path]
|
||||
*/
|
||||
protected function getPrefixAndPath($path)
|
||||
{
|
||||
if (strpos($path, '://') < 1) {
|
||||
throw new InvalidArgumentException('No prefix detected in path: ' . $path);
|
||||
}
|
||||
|
||||
return explode('://', $path, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a file exists.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($path)
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->has($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a file.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return string|false The file contents or false on failure.
|
||||
*/
|
||||
public function read($path)
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->read($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a read-stream for a path.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return resource|false The path resource or false on failure.
|
||||
*/
|
||||
public function readStream($path)
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->readStream($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a file's metadata.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return array|false The file metadata or false on failure.
|
||||
*/
|
||||
public function getMetadata($path)
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->getMetadata($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a file's size.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return int|false The file size or false on failure.
|
||||
*/
|
||||
public function getSize($path)
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->getSize($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a file's mime-type.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return string|false The file mime-type or false on failure.
|
||||
*/
|
||||
public function getMimetype($path)
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->getMimetype($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a file's timestamp.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return string|false The timestamp or false on failure.
|
||||
*/
|
||||
public function getTimestamp($path)
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->getTimestamp($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a file's visibility.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return string|false The visibility (public|private) or false on failure.
|
||||
*/
|
||||
public function getVisibility($path)
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->getVisibility($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a new file.
|
||||
*
|
||||
* @param string $path The path of the new file.
|
||||
* @param string $contents The file contents.
|
||||
* @param array $config An optional configuration array.
|
||||
*
|
||||
* @throws FileExistsException
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function write($path, $contents, array $config = [])
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->write($path, $contents, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a new file using a stream.
|
||||
*
|
||||
* @param string $path The path of the new file.
|
||||
* @param resource $resource The file handle.
|
||||
* @param array $config An optional configuration array.
|
||||
*
|
||||
* @throws InvalidArgumentException If $resource is not a file handle.
|
||||
* @throws FileExistsException
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function writeStream($path, $resource, array $config = [])
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->writeStream($path, $resource, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing file.
|
||||
*
|
||||
* @param string $path The path of the existing file.
|
||||
* @param string $contents The file contents.
|
||||
* @param array $config An optional configuration array.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function update($path, $contents, array $config = [])
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->update($path, $contents, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing file using a stream.
|
||||
*
|
||||
* @param string $path The path of the existing file.
|
||||
* @param resource $resource The file handle.
|
||||
* @param array $config An optional configuration array.
|
||||
*
|
||||
* @throws InvalidArgumentException If $resource is not a file handle.
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function updateStream($path, $resource, array $config = [])
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->updateStream($path, $resource, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a file.
|
||||
*
|
||||
* @param string $path Path to the existing file.
|
||||
* @param string $newpath The new path of the file.
|
||||
*
|
||||
* @throws FileExistsException Thrown if $newpath exists.
|
||||
* @throws FileNotFoundException Thrown if $path does not exist.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function rename($path, $newpath)
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->rename($path, $newpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a file.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function delete($path)
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->delete($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a directory.
|
||||
*
|
||||
* @param string $dirname
|
||||
*
|
||||
* @throws RootViolationException Thrown if $dirname is empty.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function deleteDir($dirname)
|
||||
{
|
||||
list($prefix, $dirname) = $this->getPrefixAndPath($dirname);
|
||||
|
||||
return $this->getFilesystem($prefix)->deleteDir($dirname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a directory.
|
||||
*
|
||||
* @param string $dirname The name of the new directory.
|
||||
* @param array $config An optional configuration array.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function createDir($dirname, array $config = [])
|
||||
{
|
||||
list($prefix, $dirname) = $this->getPrefixAndPath($dirname);
|
||||
|
||||
return $this->getFilesystem($prefix)->createDir($dirname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the visibility for a file.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
* @param string $visibility One of 'public' or 'private'.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function setVisibility($path, $visibility)
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->setVisibility($path, $visibility);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a file or update if exists.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
* @param string $contents The file contents.
|
||||
* @param array $config An optional configuration array.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function put($path, $contents, array $config = [])
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->put($path, $contents, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a file or update if exists.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
* @param resource $resource The file handle.
|
||||
* @param array $config An optional configuration array.
|
||||
*
|
||||
* @throws InvalidArgumentException Thrown if $resource is not a resource.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function putStream($path, $resource, array $config = [])
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->putStream($path, $resource, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and delete a file.
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return string|false The file contents, or false on failure.
|
||||
*/
|
||||
public function readAndDelete($path)
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->readAndDelete($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a file/directory handler.
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $path The path to the file.
|
||||
* @param Handler $handler An optional existing handler to populate.
|
||||
*
|
||||
* @return Handler Either a file or directory handler.
|
||||
*/
|
||||
public function get($path, Handler $handler = null)
|
||||
{
|
||||
list($prefix, $path) = $this->getPrefixAndPath($path);
|
||||
|
||||
return $this->getFilesystem($prefix)->get($path);
|
||||
}
|
||||
}
|
||||
37
pancake/system/vendor/league/flysystem/src/NotSupportedException.php
vendored
Executable file
37
pancake/system/vendor/league/flysystem/src/NotSupportedException.php
vendored
Executable file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem;
|
||||
|
||||
use RuntimeException;
|
||||
use SplFileInfo;
|
||||
|
||||
class NotSupportedException extends RuntimeException implements FilesystemException
|
||||
{
|
||||
/**
|
||||
* Create a new exception for a link.
|
||||
*
|
||||
* @param SplFileInfo $file
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function forLink(SplFileInfo $file)
|
||||
{
|
||||
$message = 'Links are not supported, encountered link at ';
|
||||
|
||||
return new static($message . $file->getPathname());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new exception for a link.
|
||||
*
|
||||
* @param string $systemType
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function forFtpSystemType($systemType)
|
||||
{
|
||||
$message = "The FTP system type '$systemType' is currently not supported.";
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
24
pancake/system/vendor/league/flysystem/src/Plugin/AbstractPlugin.php
vendored
Executable file
24
pancake/system/vendor/league/flysystem/src/Plugin/AbstractPlugin.php
vendored
Executable file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Plugin;
|
||||
|
||||
use League\Flysystem\FilesystemInterface;
|
||||
use League\Flysystem\PluginInterface;
|
||||
|
||||
abstract class AbstractPlugin implements PluginInterface
|
||||
{
|
||||
/**
|
||||
* @var FilesystemInterface
|
||||
*/
|
||||
protected $filesystem;
|
||||
|
||||
/**
|
||||
* Set the Filesystem object.
|
||||
*
|
||||
* @param FilesystemInterface $filesystem
|
||||
*/
|
||||
public function setFilesystem(FilesystemInterface $filesystem)
|
||||
{
|
||||
$this->filesystem = $filesystem;
|
||||
}
|
||||
}
|
||||
34
pancake/system/vendor/league/flysystem/src/Plugin/EmptyDir.php
vendored
Executable file
34
pancake/system/vendor/league/flysystem/src/Plugin/EmptyDir.php
vendored
Executable file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Plugin;
|
||||
|
||||
class EmptyDir extends AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* Get the method name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return 'emptyDir';
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty a directory's contents.
|
||||
*
|
||||
* @param string $dirname
|
||||
*/
|
||||
public function handle($dirname)
|
||||
{
|
||||
$listing = $this->filesystem->listContents($dirname, false);
|
||||
|
||||
foreach ($listing as $item) {
|
||||
if ($item['type'] === 'dir') {
|
||||
$this->filesystem->deleteDir($item['path']);
|
||||
} else {
|
||||
$this->filesystem->delete($item['path']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
44
pancake/system/vendor/league/flysystem/src/Plugin/ForcedCopy.php
vendored
Executable file
44
pancake/system/vendor/league/flysystem/src/Plugin/ForcedCopy.php
vendored
Executable file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Plugin;
|
||||
|
||||
use League\Flysystem\FileExistsException;
|
||||
use League\Flysystem\FileNotFoundException;
|
||||
|
||||
class ForcedCopy extends AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return 'forceCopy';
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a file, overwriting any existing files.
|
||||
*
|
||||
* @param string $path Path to the existing file.
|
||||
* @param string $newpath The new path of the file.
|
||||
*
|
||||
* @throws FileExistsException
|
||||
* @throws FileNotFoundException Thrown if $path does not exist.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function handle($path, $newpath)
|
||||
{
|
||||
try {
|
||||
$deleted = $this->filesystem->delete($newpath);
|
||||
} catch (FileNotFoundException $e) {
|
||||
// The destination path does not exist. That's ok.
|
||||
$deleted = true;
|
||||
}
|
||||
|
||||
if ($deleted) {
|
||||
return $this->filesystem->copy($path, $newpath);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
44
pancake/system/vendor/league/flysystem/src/Plugin/ForcedRename.php
vendored
Executable file
44
pancake/system/vendor/league/flysystem/src/Plugin/ForcedRename.php
vendored
Executable file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Plugin;
|
||||
|
||||
use League\Flysystem\FileExistsException;
|
||||
use League\Flysystem\FileNotFoundException;
|
||||
|
||||
class ForcedRename extends AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return 'forceRename';
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames a file, overwriting the destination if it exists.
|
||||
*
|
||||
* @param string $path Path to the existing file.
|
||||
* @param string $newpath The new path of the file.
|
||||
*
|
||||
* @throws FileNotFoundException Thrown if $path does not exist.
|
||||
* @throws FileExistsException
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function handle($path, $newpath)
|
||||
{
|
||||
try {
|
||||
$deleted = $this->filesystem->delete($newpath);
|
||||
} catch (FileNotFoundException $e) {
|
||||
// The destination path does not exist. That's ok.
|
||||
$deleted = true;
|
||||
}
|
||||
|
||||
if ($deleted) {
|
||||
return $this->filesystem->rename($path, $newpath);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
51
pancake/system/vendor/league/flysystem/src/Plugin/GetWithMetadata.php
vendored
Executable file
51
pancake/system/vendor/league/flysystem/src/Plugin/GetWithMetadata.php
vendored
Executable file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Plugin;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use League\Flysystem\FileNotFoundException;
|
||||
|
||||
class GetWithMetadata extends AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* Get the method name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return 'getWithMetadata';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get metadata for an object with required metadata.
|
||||
*
|
||||
* @param string $path path to file
|
||||
* @param string[] $metadata metadata keys
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws FileNotFoundException
|
||||
*
|
||||
* @return array|false metadata
|
||||
*/
|
||||
public function handle($path, array $metadata)
|
||||
{
|
||||
$object = $this->filesystem->getMetadata($path);
|
||||
|
||||
if ( ! $object) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$keys = array_diff($metadata, array_keys($object));
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if ( ! method_exists($this->filesystem, $method = 'get' . ucfirst($key))) {
|
||||
throw new InvalidArgumentException('Could not fetch metadata: ' . $key);
|
||||
}
|
||||
|
||||
$object[$key] = $this->filesystem->{$method}($path);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
35
pancake/system/vendor/league/flysystem/src/Plugin/ListFiles.php
vendored
Executable file
35
pancake/system/vendor/league/flysystem/src/Plugin/ListFiles.php
vendored
Executable file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Plugin;
|
||||
|
||||
class ListFiles extends AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* Get the method name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return 'listFiles';
|
||||
}
|
||||
|
||||
/**
|
||||
* List all files in the directory.
|
||||
*
|
||||
* @param string $directory
|
||||
* @param bool $recursive
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function handle($directory = '', $recursive = false)
|
||||
{
|
||||
$contents = $this->filesystem->listContents($directory, $recursive);
|
||||
|
||||
$filter = function ($object) {
|
||||
return $object['type'] === 'file';
|
||||
};
|
||||
|
||||
return array_values(array_filter($contents, $filter));
|
||||
}
|
||||
}
|
||||
36
pancake/system/vendor/league/flysystem/src/Plugin/ListPaths.php
vendored
Executable file
36
pancake/system/vendor/league/flysystem/src/Plugin/ListPaths.php
vendored
Executable file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Plugin;
|
||||
|
||||
class ListPaths extends AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* Get the method name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return 'listPaths';
|
||||
}
|
||||
|
||||
/**
|
||||
* List all paths.
|
||||
*
|
||||
* @param string $directory
|
||||
* @param bool $recursive
|
||||
*
|
||||
* @return string[] paths
|
||||
*/
|
||||
public function handle($directory = '', $recursive = false)
|
||||
{
|
||||
$result = [];
|
||||
$contents = $this->filesystem->listContents($directory, $recursive);
|
||||
|
||||
foreach ($contents as $object) {
|
||||
$result[] = $object['path'];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
60
pancake/system/vendor/league/flysystem/src/Plugin/ListWith.php
vendored
Executable file
60
pancake/system/vendor/league/flysystem/src/Plugin/ListWith.php
vendored
Executable file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Plugin;
|
||||
|
||||
class ListWith extends AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* Get the method name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return 'listWith';
|
||||
}
|
||||
|
||||
/**
|
||||
* List contents with metadata.
|
||||
*
|
||||
* @param string[] $keys
|
||||
* @param string $directory
|
||||
* @param bool $recursive
|
||||
*
|
||||
* @return array listing with metadata
|
||||
*/
|
||||
public function handle(array $keys = [], $directory = '', $recursive = false)
|
||||
{
|
||||
$contents = $this->filesystem->listContents($directory, $recursive);
|
||||
|
||||
foreach ($contents as $index => $object) {
|
||||
if ($object['type'] === 'file') {
|
||||
$missingKeys = array_diff($keys, array_keys($object));
|
||||
$contents[$index] = array_reduce($missingKeys, [$this, 'getMetadataByName'], $object);
|
||||
}
|
||||
}
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a meta-data value by key name.
|
||||
*
|
||||
* @param array $object
|
||||
* @param string $key
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getMetadataByName(array $object, $key)
|
||||
{
|
||||
$method = 'get' . ucfirst($key);
|
||||
|
||||
if ( ! method_exists($this->filesystem, $method)) {
|
||||
throw new \InvalidArgumentException('Could not get meta-data for key: ' . $key);
|
||||
}
|
||||
|
||||
$object[$key] = $this->filesystem->{$method}($object['path']);
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
97
pancake/system/vendor/league/flysystem/src/Plugin/PluggableTrait.php
vendored
Executable file
97
pancake/system/vendor/league/flysystem/src/Plugin/PluggableTrait.php
vendored
Executable file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace League\Flysystem\Plugin;
|
||||
|
||||
use BadMethodCallException;
|
||||
use League\Flysystem\FilesystemInterface;
|
||||
use League\Flysystem\PluginInterface;
|
||||
use LogicException;
|
||||
|
||||
trait PluggableTrait
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $plugins = [];
|
||||
|
||||
/**
|
||||
* Register a plugin.
|
||||
*
|
||||
* @param PluginInterface $plugin
|
||||
*
|
||||
* @throws LogicException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addPlugin(PluginInterface $plugin)
|
||||
{
|
||||
if ( ! method_exists($plugin, 'handle')) {
|
||||
throw new LogicException(get_class($plugin) . ' does not have a handle method.');
|
||||
}
|
||||
|
||||
$this->plugins[$plugin->getMethod()] = $plugin;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a specific plugin.
|
||||
*
|
||||
* @param string $method
|
||||
*
|
||||
* @throws PluginNotFoundException
|
||||
*
|
||||
* @return PluginInterface
|
||||
*/
|
||||
protected function findPlugin($method)
|
||||
{
|
||||
if ( ! isset($this->plugins[$method])) {
|
||||
throw new PluginNotFoundException('Plugin not found for method: ' . $method);
|
||||
}
|
||||
|
||||
return $this->plugins[$method];
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke a plugin by method name.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
* @param FilesystemInterface $filesystem
|
||||
*
|
||||
* @throws PluginNotFoundException
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function invokePlugin($method, array $arguments, FilesystemInterface $filesystem)
|
||||
{
|
||||
$plugin = $this->findPlugin($method);
|
||||
$plugin->setFilesystem($filesystem);
|
||||
$callback = [$plugin, 'handle'];
|
||||
|
||||
return call_user_func_array($callback, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugins pass-through.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
*
|
||||
* @throws BadMethodCallException
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, array $arguments)
|
||||
{
|
||||
try {
|
||||
return $this->invokePlugin($method, $arguments, $this);
|
||||
} catch (PluginNotFoundException $e) {
|
||||
throw new BadMethodCallException(
|
||||
'Call to undefined method '
|
||||
. get_class($this)
|
||||
. '::' . $method
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user