/vendor/symfony/finder/Iterator/CustomFilterIterator.php |
@@ -0,0 +1,63 @@ |
<?php |
|
/* |
* This file is part of the Symfony package. |
* |
* (c) Fabien Potencier <fabien@symfony.com> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace Symfony\Component\Finder\Iterator; |
|
/** |
* CustomFilterIterator filters files by applying anonymous functions. |
* |
* The anonymous function receives a \SplFileInfo and must return false |
* to remove files. |
* |
* @author Fabien Potencier <fabien@symfony.com> |
*/ |
class CustomFilterIterator extends FilterIterator |
{ |
private $filters = array(); |
|
/** |
* Constructor. |
* |
* @param \Iterator $iterator The Iterator to filter |
* @param callable[] $filters An array of PHP callbacks |
* |
* @throws \InvalidArgumentException |
*/ |
public function __construct(\Iterator $iterator, array $filters) |
{ |
foreach ($filters as $filter) { |
if (!is_callable($filter)) { |
throw new \InvalidArgumentException('Invalid PHP callback.'); |
} |
} |
$this->filters = $filters; |
|
parent::__construct($iterator); |
} |
|
/** |
* Filters the iterator values. |
* |
* @return bool true if the value should be kept, false otherwise |
*/ |
public function accept() |
{ |
$fileinfo = $this->current(); |
|
foreach ($this->filters as $filter) { |
if (false === call_user_func($filter, $fileinfo)) { |
return false; |
} |
} |
|
return true; |
} |
} |
/vendor/symfony/finder/Iterator/DateRangeFilterIterator.php |
@@ -0,0 +1,60 @@ |
<?php |
|
/* |
* This file is part of the Symfony package. |
* |
* (c) Fabien Potencier <fabien@symfony.com> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace Symfony\Component\Finder\Iterator; |
|
use Symfony\Component\Finder\Comparator\DateComparator; |
|
/** |
* DateRangeFilterIterator filters out files that are not in the given date range (last modified dates). |
* |
* @author Fabien Potencier <fabien@symfony.com> |
*/ |
class DateRangeFilterIterator extends FilterIterator |
{ |
private $comparators = array(); |
|
/** |
* Constructor. |
* |
* @param \Iterator $iterator The Iterator to filter |
* @param DateComparator[] $comparators An array of DateComparator instances |
*/ |
public function __construct(\Iterator $iterator, array $comparators) |
{ |
$this->comparators = $comparators; |
|
parent::__construct($iterator); |
} |
|
/** |
* Filters the iterator values. |
* |
* @return bool true if the value should be kept, false otherwise |
*/ |
public function accept() |
{ |
$fileinfo = $this->current(); |
|
if (!file_exists($fileinfo->getPathname())) { |
return false; |
} |
|
$filedate = $fileinfo->getMTime(); |
foreach ($this->comparators as $compare) { |
if (!$compare->test($filedate)) { |
return false; |
} |
} |
|
return true; |
} |
} |
/vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php |
@@ -0,0 +1,47 @@ |
<?php |
|
/* |
* This file is part of the Symfony package. |
* |
* (c) Fabien Potencier <fabien@symfony.com> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace Symfony\Component\Finder\Iterator; |
|
/** |
* DepthRangeFilterIterator limits the directory depth. |
* |
* @author Fabien Potencier <fabien@symfony.com> |
*/ |
class DepthRangeFilterIterator extends FilterIterator |
{ |
private $minDepth = 0; |
|
/** |
* Constructor. |
* |
* @param \RecursiveIteratorIterator $iterator The Iterator to filter |
* @param int $minDepth The min depth |
* @param int $maxDepth The max depth |
*/ |
public function __construct(\RecursiveIteratorIterator $iterator, $minDepth = 0, $maxDepth = PHP_INT_MAX) |
{ |
$this->minDepth = $minDepth; |
$iterator->setMaxDepth(PHP_INT_MAX === $maxDepth ? -1 : $maxDepth); |
|
parent::__construct($iterator); |
} |
|
/** |
* Filters the iterator values. |
* |
* @return bool true if the value should be kept, false otherwise |
*/ |
public function accept() |
{ |
return $this->getInnerIterator()->getDepth() >= $this->minDepth; |
} |
} |
/vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php |
@@ -0,0 +1,86 @@ |
<?php |
|
/* |
* This file is part of the Symfony package. |
* |
* (c) Fabien Potencier <fabien@symfony.com> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace Symfony\Component\Finder\Iterator; |
|
/** |
* ExcludeDirectoryFilterIterator filters out directories. |
* |
* @author Fabien Potencier <fabien@symfony.com> |
*/ |
class ExcludeDirectoryFilterIterator extends FilterIterator implements \RecursiveIterator |
{ |
private $iterator; |
private $isRecursive; |
private $excludedDirs = array(); |
private $excludedPattern; |
|
/** |
* Constructor. |
* |
* @param \Iterator $iterator The Iterator to filter |
* @param array $directories An array of directories to exclude |
*/ |
public function __construct(\Iterator $iterator, array $directories) |
{ |
$this->iterator = $iterator; |
$this->isRecursive = $iterator instanceof \RecursiveIterator; |
$patterns = array(); |
foreach ($directories as $directory) { |
$directory = rtrim($directory, '/'); |
if (!$this->isRecursive || false !== strpos($directory, '/')) { |
$patterns[] = preg_quote($directory, '#'); |
} else { |
$this->excludedDirs[$directory] = true; |
} |
} |
if ($patterns) { |
$this->excludedPattern = '#(?:^|/)(?:'.implode('|', $patterns).')(?:/|$)#'; |
} |
|
parent::__construct($iterator); |
} |
|
/** |
* Filters the iterator values. |
* |
* @return bool True if the value should be kept, false otherwise |
*/ |
public function accept() |
{ |
if ($this->isRecursive && isset($this->excludedDirs[$this->getFilename()]) && $this->isDir()) { |
return false; |
} |
|
if ($this->excludedPattern) { |
$path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath(); |
$path = str_replace('\\', '/', $path); |
|
return !preg_match($this->excludedPattern, $path); |
} |
|
return true; |
} |
|
public function hasChildren() |
{ |
return $this->isRecursive && $this->iterator->hasChildren(); |
} |
|
public function getChildren() |
{ |
$children = new self($this->iterator->getChildren(), array()); |
$children->excludedDirs = $this->excludedDirs; |
$children->excludedPattern = $this->excludedPattern; |
|
return $children; |
} |
} |
/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php |
@@ -0,0 +1,55 @@ |
<?php |
|
/* |
* This file is part of the Symfony package. |
* |
* (c) Fabien Potencier <fabien@symfony.com> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace Symfony\Component\Finder\Iterator; |
|
/** |
* FileTypeFilterIterator only keeps files, directories, or both. |
* |
* @author Fabien Potencier <fabien@symfony.com> |
*/ |
class FileTypeFilterIterator extends FilterIterator |
{ |
const ONLY_FILES = 1; |
const ONLY_DIRECTORIES = 2; |
|
private $mode; |
|
/** |
* Constructor. |
* |
* @param \Iterator $iterator The Iterator to filter |
* @param int $mode The mode (self::ONLY_FILES or self::ONLY_DIRECTORIES) |
*/ |
public function __construct(\Iterator $iterator, $mode) |
{ |
$this->mode = $mode; |
|
parent::__construct($iterator); |
} |
|
/** |
* Filters the iterator values. |
* |
* @return bool true if the value should be kept, false otherwise |
*/ |
public function accept() |
{ |
$fileinfo = $this->current(); |
if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) { |
return false; |
} elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $fileinfo->isDir()) { |
return false; |
} |
|
return true; |
} |
} |
/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php |
@@ -0,0 +1,58 @@ |
<?php |
|
/* |
* This file is part of the Symfony package. |
* |
* (c) Fabien Potencier <fabien@symfony.com> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace Symfony\Component\Finder\Iterator; |
|
/** |
* FilecontentFilterIterator filters files by their contents using patterns (regexps or strings). |
* |
* @author Fabien Potencier <fabien@symfony.com> |
* @author Włodzimierz Gajda <gajdaw@gajdaw.pl> |
*/ |
class FilecontentFilterIterator extends MultiplePcreFilterIterator |
{ |
/** |
* Filters the iterator values. |
* |
* @return bool true if the value should be kept, false otherwise |
*/ |
public function accept() |
{ |
if (!$this->matchRegexps && !$this->noMatchRegexps) { |
return true; |
} |
|
$fileinfo = $this->current(); |
|
if ($fileinfo->isDir() || !$fileinfo->isReadable()) { |
return false; |
} |
|
$content = $fileinfo->getContents(); |
if (!$content) { |
return false; |
} |
|
return $this->isAccepted($content); |
} |
|
/** |
* Converts string to regexp if necessary. |
* |
* @param string $str Pattern: string or regexp |
* |
* @return string regexp corresponding to a given string or regexp |
*/ |
protected function toRegex($str) |
{ |
return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/'; |
} |
} |
/vendor/symfony/finder/Iterator/FilenameFilterIterator.php |
@@ -0,0 +1,47 @@ |
<?php |
|
/* |
* This file is part of the Symfony package. |
* |
* (c) Fabien Potencier <fabien@symfony.com> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace Symfony\Component\Finder\Iterator; |
|
use Symfony\Component\Finder\Glob; |
|
/** |
* FilenameFilterIterator filters files by patterns (a regexp, a glob, or a string). |
* |
* @author Fabien Potencier <fabien@symfony.com> |
*/ |
class FilenameFilterIterator extends MultiplePcreFilterIterator |
{ |
/** |
* Filters the iterator values. |
* |
* @return bool true if the value should be kept, false otherwise |
*/ |
public function accept() |
{ |
return $this->isAccepted($this->current()->getFilename()); |
} |
|
/** |
* Converts glob to regexp. |
* |
* PCRE patterns are left unchanged. |
* Glob strings are transformed with Glob::toRegex(). |
* |
* @param string $str Pattern: glob or regexp |
* |
* @return string regexp corresponding to a given glob or regexp |
*/ |
protected function toRegex($str) |
{ |
return $this->isRegex($str) ? $str : Glob::toRegex($str); |
} |
} |
/vendor/symfony/finder/Iterator/FilterIterator.php |
@@ -0,0 +1,58 @@ |
<?php |
|
/* |
* This file is part of the Symfony package. |
* |
* (c) Fabien Potencier <fabien@symfony.com> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace Symfony\Component\Finder\Iterator; |
|
/** |
* This iterator just overrides the rewind method in order to correct a PHP bug, |
* which existed before version 5.5.23/5.6.7. |
* |
* @see https://bugs.php.net/68557 |
* |
* @author Alex Bogomazov |
*/ |
abstract class FilterIterator extends \FilterIterator |
{ |
/** |
* This is a workaround for the problem with \FilterIterator leaving inner \FilesystemIterator in wrong state after |
* rewind in some cases. |
* |
* @see FilterIterator::rewind() |
*/ |
public function rewind() |
{ |
if (\PHP_VERSION_ID > 50607 || (\PHP_VERSION_ID > 50523 && \PHP_VERSION_ID < 50600)) { |
parent::rewind(); |
|
return; |
} |
|
$iterator = $this; |
while ($iterator instanceof \OuterIterator) { |
$innerIterator = $iterator->getInnerIterator(); |
|
if ($innerIterator instanceof RecursiveDirectoryIterator) { |
// this condition is necessary for iterators to work properly with non-local filesystems like ftp |
if ($innerIterator->isRewindable()) { |
$innerIterator->next(); |
$innerIterator->rewind(); |
} |
} elseif ($innerIterator instanceof \FilesystemIterator) { |
$innerIterator->next(); |
$innerIterator->rewind(); |
} |
|
$iterator = $innerIterator; |
} |
|
parent::rewind(); |
} |
} |
/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php |
@@ -0,0 +1,114 @@ |
<?php |
|
/* |
* This file is part of the Symfony package. |
* |
* (c) Fabien Potencier <fabien@symfony.com> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace Symfony\Component\Finder\Iterator; |
|
/** |
* MultiplePcreFilterIterator filters files using patterns (regexps, globs or strings). |
* |
* @author Fabien Potencier <fabien@symfony.com> |
*/ |
abstract class MultiplePcreFilterIterator extends FilterIterator |
{ |
protected $matchRegexps = array(); |
protected $noMatchRegexps = array(); |
|
/** |
* Constructor. |
* |
* @param \Iterator $iterator The Iterator to filter |
* @param array $matchPatterns An array of patterns that need to match |
* @param array $noMatchPatterns An array of patterns that need to not match |
*/ |
public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns) |
{ |
foreach ($matchPatterns as $pattern) { |
$this->matchRegexps[] = $this->toRegex($pattern); |
} |
|
foreach ($noMatchPatterns as $pattern) { |
$this->noMatchRegexps[] = $this->toRegex($pattern); |
} |
|
parent::__construct($iterator); |
} |
|
/** |
* Checks whether the string is accepted by the regex filters. |
* |
* If there is no regexps defined in the class, this method will accept the string. |
* Such case can be handled by child classes before calling the method if they want to |
* apply a different behavior. |
* |
* @param string $string The string to be matched against filters |
* |
* @return bool |
*/ |
protected function isAccepted($string) |
{ |
// should at least not match one rule to exclude |
foreach ($this->noMatchRegexps as $regex) { |
if (preg_match($regex, $string)) { |
return false; |
} |
} |
|
// should at least match one rule |
if ($this->matchRegexps) { |
foreach ($this->matchRegexps as $regex) { |
if (preg_match($regex, $string)) { |
return true; |
} |
} |
|
return false; |
} |
|
// If there is no match rules, the file is accepted |
return true; |
} |
|
/** |
* Checks whether the string is a regex. |
* |
* @param string $str |
* |
* @return bool Whether the given string is a regex |
*/ |
protected function isRegex($str) |
{ |
if (preg_match('/^(.{3,}?)[imsxuADU]*$/', $str, $m)) { |
$start = substr($m[1], 0, 1); |
$end = substr($m[1], -1); |
|
if ($start === $end) { |
return !preg_match('/[*?[:alnum:] \\\\]/', $start); |
} |
|
foreach (array(array('{', '}'), array('(', ')'), array('[', ']'), array('<', '>')) as $delimiters) { |
if ($start === $delimiters[0] && $end === $delimiters[1]) { |
return true; |
} |
} |
} |
|
return false; |
} |
|
/** |
* Converts string into regexp. |
* |
* @param string $str Pattern |
* |
* @return string regexp corresponding to a given string |
*/ |
abstract protected function toRegex($str); |
} |
/vendor/symfony/finder/Iterator/PathFilterIterator.php |
@@ -0,0 +1,56 @@ |
<?php |
|
/* |
* This file is part of the Symfony package. |
* |
* (c) Fabien Potencier <fabien@symfony.com> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace Symfony\Component\Finder\Iterator; |
|
/** |
* PathFilterIterator filters files by path patterns (e.g. some/special/dir). |
* |
* @author Fabien Potencier <fabien@symfony.com> |
* @author Włodzimierz Gajda <gajdaw@gajdaw.pl> |
*/ |
class PathFilterIterator extends MultiplePcreFilterIterator |
{ |
/** |
* Filters the iterator values. |
* |
* @return bool true if the value should be kept, false otherwise |
*/ |
public function accept() |
{ |
$filename = $this->current()->getRelativePathname(); |
|
if ('\\' === DIRECTORY_SEPARATOR) { |
$filename = str_replace('\\', '/', $filename); |
} |
|
return $this->isAccepted($filename); |
} |
|
/** |
* Converts strings to regexp. |
* |
* PCRE patterns are left unchanged. |
* |
* Default conversion: |
* 'lorem/ipsum/dolor' ==> 'lorem\/ipsum\/dolor/' |
* |
* Use only / as directory separator (on Windows also). |
* |
* @param string $str Pattern: regexp or dirname |
* |
* @return string regexp corresponding to a given string or regexp |
*/ |
protected function toRegex($str) |
{ |
return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/'; |
} |
} |
/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php |
@@ -0,0 +1,156 @@ |
<?php |
|
/* |
* This file is part of the Symfony package. |
* |
* (c) Fabien Potencier <fabien@symfony.com> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace Symfony\Component\Finder\Iterator; |
|
use Symfony\Component\Finder\Exception\AccessDeniedException; |
use Symfony\Component\Finder\SplFileInfo; |
|
/** |
* Extends the \RecursiveDirectoryIterator to support relative paths. |
* |
* @author Victor Berchet <victor@suumit.com> |
*/ |
class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator |
{ |
/** |
* @var bool |
*/ |
private $ignoreUnreadableDirs; |
|
/** |
* @var bool |
*/ |
private $rewindable; |
|
// these 3 properties take part of the performance optimization to avoid redoing the same work in all iterations |
private $rootPath; |
private $subPath; |
private $directorySeparator = '/'; |
|
/** |
* Constructor. |
* |
* @param string $path |
* @param int $flags |
* @param bool $ignoreUnreadableDirs |
* |
* @throws \RuntimeException |
*/ |
public function __construct($path, $flags, $ignoreUnreadableDirs = false) |
{ |
if ($flags & (self::CURRENT_AS_PATHNAME | self::CURRENT_AS_SELF)) { |
throw new \RuntimeException('This iterator only support returning current as fileinfo.'); |
} |
|
parent::__construct($path, $flags); |
$this->ignoreUnreadableDirs = $ignoreUnreadableDirs; |
$this->rootPath = $path; |
if ('/' !== DIRECTORY_SEPARATOR && !($flags & self::UNIX_PATHS)) { |
$this->directorySeparator = DIRECTORY_SEPARATOR; |
} |
} |
|
/** |
* Return an instance of SplFileInfo with support for relative paths. |
* |
* @return SplFileInfo File information |
*/ |
public function current() |
{ |
// the logic here avoids redoing the same work in all iterations |
|
if (null === $subPathname = $this->subPath) { |
$subPathname = $this->subPath = (string) $this->getSubPath(); |
} |
if ('' !== $subPathname) { |
$subPathname .= $this->directorySeparator; |
} |
$subPathname .= $this->getFilename(); |
|
return new SplFileInfo($this->rootPath.$this->directorySeparator.$subPathname, $this->subPath, $subPathname); |
} |
|
/** |
* @return \RecursiveIterator |
* |
* @throws AccessDeniedException |
*/ |
public function getChildren() |
{ |
try { |
$children = parent::getChildren(); |
|
if ($children instanceof self) { |
// parent method will call the constructor with default arguments, so unreadable dirs won't be ignored anymore |
$children->ignoreUnreadableDirs = $this->ignoreUnreadableDirs; |
|
// performance optimization to avoid redoing the same work in all children |
$children->rewindable = &$this->rewindable; |
$children->rootPath = $this->rootPath; |
} |
|
return $children; |
} catch (\UnexpectedValueException $e) { |
if ($this->ignoreUnreadableDirs) { |
// If directory is unreadable and finder is set to ignore it, a fake empty content is returned. |
return new \RecursiveArrayIterator(array()); |
} else { |
throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e); |
} |
} |
} |
|
/** |
* Do nothing for non rewindable stream. |
*/ |
public function rewind() |
{ |
if (false === $this->isRewindable()) { |
return; |
} |
|
// @see https://bugs.php.net/68557 |
if (\PHP_VERSION_ID < 50523 || \PHP_VERSION_ID >= 50600 && \PHP_VERSION_ID < 50607) { |
parent::next(); |
} |
|
parent::rewind(); |
} |
|
/** |
* Checks if the stream is rewindable. |
* |
* @return bool true when the stream is rewindable, false otherwise |
*/ |
public function isRewindable() |
{ |
if (null !== $this->rewindable) { |
return $this->rewindable; |
} |
|
// workaround for an HHVM bug, should be removed when https://github.com/facebook/hhvm/issues/7281 is fixed |
if ('' === $this->getPath()) { |
return $this->rewindable = false; |
} |
|
if (false !== $stream = @opendir($this->getPath())) { |
$infos = stream_get_meta_data($stream); |
closedir($stream); |
|
if ($infos['seekable']) { |
return $this->rewindable = true; |
} |
} |
|
return $this->rewindable = false; |
} |
} |
/vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php |
@@ -0,0 +1,59 @@ |
<?php |
|
/* |
* This file is part of the Symfony package. |
* |
* (c) Fabien Potencier <fabien@symfony.com> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace Symfony\Component\Finder\Iterator; |
|
use Symfony\Component\Finder\Comparator\NumberComparator; |
|
/** |
* SizeRangeFilterIterator filters out files that are not in the given size range. |
* |
* @author Fabien Potencier <fabien@symfony.com> |
*/ |
class SizeRangeFilterIterator extends FilterIterator |
{ |
private $comparators = array(); |
|
/** |
* Constructor. |
* |
* @param \Iterator $iterator The Iterator to filter |
* @param NumberComparator[] $comparators An array of NumberComparator instances |
*/ |
public function __construct(\Iterator $iterator, array $comparators) |
{ |
$this->comparators = $comparators; |
|
parent::__construct($iterator); |
} |
|
/** |
* Filters the iterator values. |
* |
* @return bool true if the value should be kept, false otherwise |
*/ |
public function accept() |
{ |
$fileinfo = $this->current(); |
if (!$fileinfo->isFile()) { |
return true; |
} |
|
$filesize = $fileinfo->getSize(); |
foreach ($this->comparators as $compare) { |
if (!$compare->test($filesize)) { |
return false; |
} |
} |
|
return true; |
} |
} |
/vendor/symfony/finder/Iterator/SortableIterator.php |
@@ -0,0 +1,82 @@ |
<?php |
|
/* |
* This file is part of the Symfony package. |
* |
* (c) Fabien Potencier <fabien@symfony.com> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace Symfony\Component\Finder\Iterator; |
|
/** |
* SortableIterator applies a sort on a given Iterator. |
* |
* @author Fabien Potencier <fabien@symfony.com> |
*/ |
class SortableIterator implements \IteratorAggregate |
{ |
const SORT_BY_NAME = 1; |
const SORT_BY_TYPE = 2; |
const SORT_BY_ACCESSED_TIME = 3; |
const SORT_BY_CHANGED_TIME = 4; |
const SORT_BY_MODIFIED_TIME = 5; |
|
private $iterator; |
private $sort; |
|
/** |
* Constructor. |
* |
* @param \Traversable $iterator The Iterator to filter |
* @param int|callable $sort The sort type (SORT_BY_NAME, SORT_BY_TYPE, or a PHP callback) |
* |
* @throws \InvalidArgumentException |
*/ |
public function __construct(\Traversable $iterator, $sort) |
{ |
$this->iterator = $iterator; |
|
if (self::SORT_BY_NAME === $sort) { |
$this->sort = function ($a, $b) { |
return strcmp($a->getRealpath() ?: $a->getPathname(), $b->getRealpath() ?: $b->getPathname()); |
}; |
} elseif (self::SORT_BY_TYPE === $sort) { |
$this->sort = function ($a, $b) { |
if ($a->isDir() && $b->isFile()) { |
return -1; |
} elseif ($a->isFile() && $b->isDir()) { |
return 1; |
} |
|
return strcmp($a->getRealpath() ?: $a->getPathname(), $b->getRealpath() ?: $b->getPathname()); |
}; |
} elseif (self::SORT_BY_ACCESSED_TIME === $sort) { |
$this->sort = function ($a, $b) { |
return $a->getATime() - $b->getATime(); |
}; |
} elseif (self::SORT_BY_CHANGED_TIME === $sort) { |
$this->sort = function ($a, $b) { |
return $a->getCTime() - $b->getCTime(); |
}; |
} elseif (self::SORT_BY_MODIFIED_TIME === $sort) { |
$this->sort = function ($a, $b) { |
return $a->getMTime() - $b->getMTime(); |
}; |
} elseif (is_callable($sort)) { |
$this->sort = $sort; |
} else { |
throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.'); |
} |
} |
|
public function getIterator() |
{ |
$array = iterator_to_array($this->iterator, true); |
uasort($array, $this->sort); |
|
return new \ArrayIterator($array); |
} |
} |