summaryrefslogtreecommitdiffstats
path: root/vendor/symfony/finder/Symfony/Component/Finder/Adapter
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/symfony/finder/Symfony/Component/Finder/Adapter')
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php236
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php327
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php144
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php103
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php104
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php98
6 files changed, 1012 insertions, 0 deletions
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php
new file mode 100644
index 0000000..4ddd913
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php
@@ -0,0 +1,236 @@
+<?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\Adapter;
+
+/**
+ * Interface for finder engine implementations.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+abstract class AbstractAdapter implements AdapterInterface
+{
+ protected $followLinks = false;
+ protected $mode = 0;
+ protected $minDepth = 0;
+ protected $maxDepth = PHP_INT_MAX;
+ protected $exclude = array();
+ protected $names = array();
+ protected $notNames = array();
+ protected $contains = array();
+ protected $notContains = array();
+ protected $sizes = array();
+ protected $dates = array();
+ protected $filters = array();
+ protected $sort = false;
+ protected $paths = array();
+ protected $notPaths = array();
+ protected $ignoreUnreadableDirs = false;
+
+ private static $areSupported = array();
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isSupported()
+ {
+ $name = $this->getName();
+
+ if (!array_key_exists($name, self::$areSupported)) {
+ self::$areSupported[$name] = $this->canBeUsed();
+ }
+
+ return self::$areSupported[$name];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setFollowLinks($followLinks)
+ {
+ $this->followLinks = $followLinks;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMode($mode)
+ {
+ $this->mode = $mode;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDepths(array $depths)
+ {
+ $this->minDepth = 0;
+ $this->maxDepth = PHP_INT_MAX;
+
+ foreach ($depths as $comparator) {
+ switch ($comparator->getOperator()) {
+ case '>':
+ $this->minDepth = $comparator->getTarget() + 1;
+ break;
+ case '>=':
+ $this->minDepth = $comparator->getTarget();
+ break;
+ case '<':
+ $this->maxDepth = $comparator->getTarget() - 1;
+ break;
+ case '<=':
+ $this->maxDepth = $comparator->getTarget();
+ break;
+ default:
+ $this->minDepth = $this->maxDepth = $comparator->getTarget();
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setExclude(array $exclude)
+ {
+ $this->exclude = $exclude;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setNames(array $names)
+ {
+ $this->names = $names;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setNotNames(array $notNames)
+ {
+ $this->notNames = $notNames;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setContains(array $contains)
+ {
+ $this->contains = $contains;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setNotContains(array $notContains)
+ {
+ $this->notContains = $notContains;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setSizes(array $sizes)
+ {
+ $this->sizes = $sizes;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDates(array $dates)
+ {
+ $this->dates = $dates;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setFilters(array $filters)
+ {
+ $this->filters = $filters;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setSort($sort)
+ {
+ $this->sort = $sort;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setPath(array $paths)
+ {
+ $this->paths = $paths;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setNotPath(array $notPaths)
+ {
+ $this->notPaths = $notPaths;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function ignoreUnreadableDirs($ignore = true)
+ {
+ $this->ignoreUnreadableDirs = (bool) $ignore;
+
+ return $this;
+ }
+
+ /**
+ * Returns whether the adapter is supported in the current environment.
+ *
+ * This method should be implemented in all adapters. Do not implement
+ * isSupported in the adapters as the generic implementation provides a cache
+ * layer.
+ *
+ * @see isSupported()
+ *
+ * @return bool Whether the adapter is supported
+ */
+ abstract protected function canBeUsed();
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php
new file mode 100644
index 0000000..244301a
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php
@@ -0,0 +1,327 @@
+<?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\Adapter;
+
+use Symfony\Component\Finder\Exception\AccessDeniedException;
+use Symfony\Component\Finder\Iterator;
+use Symfony\Component\Finder\Shell\Shell;
+use Symfony\Component\Finder\Expression\Expression;
+use Symfony\Component\Finder\Shell\Command;
+use Symfony\Component\Finder\Comparator\NumberComparator;
+use Symfony\Component\Finder\Comparator\DateComparator;
+
+/**
+ * Shell engine implementation using GNU find command.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+abstract class AbstractFindAdapter extends AbstractAdapter
+{
+ /**
+ * @var Shell
+ */
+ protected $shell;
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ $this->shell = new Shell();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function searchInDirectory($dir)
+ {
+ // having "/../" in path make find fail
+ $dir = realpath($dir);
+
+ // searching directories containing or not containing strings leads to no result
+ if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode && ($this->contains || $this->notContains)) {
+ return new Iterator\FilePathsIterator(array(), $dir);
+ }
+
+ $command = Command::create();
+ $find = $this->buildFindCommand($command, $dir);
+
+ if ($this->followLinks) {
+ $find->add('-follow');
+ }
+
+ $find->add('-mindepth')->add($this->minDepth + 1);
+
+ if (PHP_INT_MAX !== $this->maxDepth) {
+ $find->add('-maxdepth')->add($this->maxDepth + 1);
+ }
+
+ if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode) {
+ $find->add('-type d');
+ } elseif (Iterator\FileTypeFilterIterator::ONLY_FILES === $this->mode) {
+ $find->add('-type f');
+ }
+
+ $this->buildNamesFiltering($find, $this->names);
+ $this->buildNamesFiltering($find, $this->notNames, true);
+ $this->buildPathsFiltering($find, $dir, $this->paths);
+ $this->buildPathsFiltering($find, $dir, $this->notPaths, true);
+ $this->buildSizesFiltering($find, $this->sizes);
+ $this->buildDatesFiltering($find, $this->dates);
+
+ $useGrep = $this->shell->testCommand('grep') && $this->shell->testCommand('xargs');
+ $useSort = is_int($this->sort) && $this->shell->testCommand('sort') && $this->shell->testCommand('cut');
+
+ if ($useGrep && ($this->contains || $this->notContains)) {
+ $grep = $command->ins('grep');
+ $this->buildContentFiltering($grep, $this->contains);
+ $this->buildContentFiltering($grep, $this->notContains, true);
+ }
+
+ if ($useSort) {
+ $this->buildSorting($command, $this->sort);
+ }
+
+ $command->setErrorHandler(
+ $this->ignoreUnreadableDirs
+ // If directory is unreadable and finder is set to ignore it, `stderr` is ignored.
+ ? function ($stderr) { return; }
+ : function ($stderr) { throw new AccessDeniedException($stderr); }
+ );
+
+ $paths = $this->shell->testCommand('uniq') ? $command->add('| uniq')->execute() : array_unique($command->execute());
+ $iterator = new Iterator\FilePathsIterator($paths, $dir);
+
+ if ($this->exclude) {
+ $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
+ }
+
+ if (!$useGrep && ($this->contains || $this->notContains)) {
+ $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
+ }
+
+ if ($this->filters) {
+ $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
+ }
+
+ if (!$useSort && $this->sort) {
+ $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
+ $iterator = $iteratorAggregate->getIterator();
+ }
+
+ return $iterator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return $this->shell->testCommand('find');
+ }
+
+ /**
+ * @param Command $command
+ * @param string $dir
+ *
+ * @return Command
+ */
+ protected function buildFindCommand(Command $command, $dir)
+ {
+ return $command
+ ->ins('find')
+ ->add('find ')
+ ->arg($dir)
+ ->add('-noleaf'); // the -noleaf option is required for filesystems that don't follow the '.' and '..' conventions
+ }
+
+ /**
+ * @param Command $command
+ * @param string[] $names
+ * @param bool $not
+ */
+ private function buildNamesFiltering(Command $command, array $names, $not = false)
+ {
+ if (0 === count($names)) {
+ return;
+ }
+
+ $command->add($not ? '-not' : null)->cmd('(');
+
+ foreach ($names as $i => $name) {
+ $expr = Expression::create($name);
+
+ // Find does not support expandable globs ("*.{a,b}" syntax).
+ if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
+ $expr = Expression::create($expr->getGlob()->toRegex(false));
+ }
+
+ // Fixes 'not search' and 'full path matching' regex problems.
+ // - Jokers '.' are replaced by [^/].
+ // - We add '[^/]*' before and after regex (if no ^|$ flags are present).
+ if ($expr->isRegex()) {
+ $regex = $expr->getRegex();
+ $regex->prepend($regex->hasStartFlag() ? '/' : '/[^/]*')
+ ->setStartFlag(false)
+ ->setStartJoker(true)
+ ->replaceJokers('[^/]');
+ if (!$regex->hasEndFlag() || $regex->hasEndJoker()) {
+ $regex->setEndJoker(false)->append('[^/]*');
+ }
+ }
+
+ $command
+ ->add($i > 0 ? '-or' : null)
+ ->add($expr->isRegex()
+ ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
+ : ($expr->isCaseSensitive() ? '-name' : '-iname')
+ )
+ ->arg($expr->renderPattern());
+ }
+
+ $command->cmd(')');
+ }
+
+ /**
+ * @param Command $command
+ * @param string $dir
+ * @param string[] $paths
+ * @param bool $not
+ */
+ private function buildPathsFiltering(Command $command, $dir, array $paths, $not = false)
+ {
+ if (0 === count($paths)) {
+ return;
+ }
+
+ $command->add($not ? '-not' : null)->cmd('(');
+
+ foreach ($paths as $i => $path) {
+ $expr = Expression::create($path);
+
+ // Find does not support expandable globs ("*.{a,b}" syntax).
+ if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
+ $expr = Expression::create($expr->getGlob()->toRegex(false));
+ }
+
+ // Fixes 'not search' regex problems.
+ if ($expr->isRegex()) {
+ $regex = $expr->getRegex();
+ $regex->prepend($regex->hasStartFlag() ? preg_quote($dir).DIRECTORY_SEPARATOR : '.*')->setEndJoker(!$regex->hasEndFlag());
+ } else {
+ $expr->prepend('*')->append('*');
+ }
+
+ $command
+ ->add($i > 0 ? '-or' : null)
+ ->add($expr->isRegex()
+ ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
+ : ($expr->isCaseSensitive() ? '-path' : '-ipath')
+ )
+ ->arg($expr->renderPattern());
+ }
+
+ $command->cmd(')');
+ }
+
+ /**
+ * @param Command $command
+ * @param NumberComparator[] $sizes
+ */
+ private function buildSizesFiltering(Command $command, array $sizes)
+ {
+ foreach ($sizes as $i => $size) {
+ $command->add($i > 0 ? '-and' : null);
+
+ switch ($size->getOperator()) {
+ case '<=':
+ $command->add('-size -'.($size->getTarget() + 1).'c');
+ break;
+ case '>=':
+ $command->add('-size +'.($size->getTarget() - 1).'c');
+ break;
+ case '>':
+ $command->add('-size +'.$size->getTarget().'c');
+ break;
+ case '!=':
+ $command->add('-size -'.$size->getTarget().'c');
+ $command->add('-size +'.$size->getTarget().'c');
+ break;
+ case '<':
+ default:
+ $command->add('-size -'.$size->getTarget().'c');
+ }
+ }
+ }
+
+ /**
+ * @param Command $command
+ * @param DateComparator[] $dates
+ */
+ private function buildDatesFiltering(Command $command, array $dates)
+ {
+ foreach ($dates as $i => $date) {
+ $command->add($i > 0 ? '-and' : null);
+
+ $mins = (int) round((time() - $date->getTarget()) / 60);
+
+ if (0 > $mins) {
+ // mtime is in the future
+ $command->add(' -mmin -0');
+ // we will have no result so we don't need to continue
+ return;
+ }
+
+ switch ($date->getOperator()) {
+ case '<=':
+ $command->add('-mmin +'.($mins - 1));
+ break;
+ case '>=':
+ $command->add('-mmin -'.($mins + 1));
+ break;
+ case '>':
+ $command->add('-mmin -'.$mins);
+ break;
+ case '!=':
+ $command->add('-mmin +'.$mins.' -or -mmin -'.$mins);
+ break;
+ case '<':
+ default:
+ $command->add('-mmin +'.$mins);
+ }
+ }
+ }
+
+ /**
+ * @param Command $command
+ * @param string $sort
+ *
+ * @throws \InvalidArgumentException
+ */
+ private function buildSorting(Command $command, $sort)
+ {
+ $this->buildFormatSorting($command, $sort);
+ }
+
+ /**
+ * @param Command $command
+ * @param string $sort
+ */
+ abstract protected function buildFormatSorting(Command $command, $sort);
+
+ /**
+ * @param Command $command
+ * @param array $contains
+ * @param bool $not
+ */
+ abstract protected function buildContentFiltering(Command $command, array $contains, $not = false);
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php
new file mode 100644
index 0000000..bdc3a93
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php
@@ -0,0 +1,144 @@
+<?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\Adapter;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+interface AdapterInterface
+{
+ /**
+ * @param bool $followLinks
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setFollowLinks($followLinks);
+
+ /**
+ * @param int $mode
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setMode($mode);
+
+ /**
+ * @param array $exclude
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setExclude(array $exclude);
+
+ /**
+ * @param array $depths
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setDepths(array $depths);
+
+ /**
+ * @param array $names
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setNames(array $names);
+
+ /**
+ * @param array $notNames
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setNotNames(array $notNames);
+
+ /**
+ * @param array $contains
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setContains(array $contains);
+
+ /**
+ * @param array $notContains
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setNotContains(array $notContains);
+
+ /**
+ * @param array $sizes
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setSizes(array $sizes);
+
+ /**
+ * @param array $dates
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setDates(array $dates);
+
+ /**
+ * @param array $filters
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setFilters(array $filters);
+
+ /**
+ * @param \Closure|int $sort
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setSort($sort);
+
+ /**
+ * @param array $paths
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setPath(array $paths);
+
+ /**
+ * @param array $notPaths
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setNotPath(array $notPaths);
+
+ /**
+ * @param bool $ignore
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function ignoreUnreadableDirs($ignore = true);
+
+ /**
+ * @param string $dir
+ *
+ * @return \Iterator Result iterator
+ */
+ public function searchInDirectory($dir);
+
+ /**
+ * Tests adapter support for current platform.
+ *
+ * @return bool
+ */
+ public function isSupported();
+
+ /**
+ * Returns adapter name.
+ *
+ * @return string
+ */
+ public function getName();
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php
new file mode 100644
index 0000000..4a25bae
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php
@@ -0,0 +1,103 @@
+<?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\Adapter;
+
+use Symfony\Component\Finder\Shell\Shell;
+use Symfony\Component\Finder\Shell\Command;
+use Symfony\Component\Finder\Iterator\SortableIterator;
+use Symfony\Component\Finder\Expression\Expression;
+
+/**
+ * Shell engine implementation using BSD find command.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class BsdFindAdapter extends AbstractFindAdapter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'bsd_find';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return in_array($this->shell->getType(), array(Shell::TYPE_BSD, Shell::TYPE_DARWIN)) && parent::canBeUsed();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildFormatSorting(Command $command, $sort)
+ {
+ switch ($sort) {
+ case SortableIterator::SORT_BY_NAME:
+ $command->ins('sort')->add('| sort');
+
+ return;
+ case SortableIterator::SORT_BY_TYPE:
+ $format = '%HT';
+ break;
+ case SortableIterator::SORT_BY_ACCESSED_TIME:
+ $format = '%a';
+ break;
+ case SortableIterator::SORT_BY_CHANGED_TIME:
+ $format = '%c';
+ break;
+ case SortableIterator::SORT_BY_MODIFIED_TIME:
+ $format = '%m';
+ break;
+ default:
+ throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
+ }
+
+ $command
+ ->add('-print0 | xargs -0 stat -f')
+ ->arg($format.'%t%N')
+ ->add('| sort | cut -f 2');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildFindCommand(Command $command, $dir)
+ {
+ parent::buildFindCommand($command, $dir)->addAtIndex('-E', 1);
+
+ return $command;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildContentFiltering(Command $command, array $contains, $not = false)
+ {
+ foreach ($contains as $contain) {
+ $expr = Expression::create($contain);
+
+ // todo: avoid forking process for each $pattern by using multiple -e options
+ $command
+ ->add('| grep -v \'^$\'')
+ ->add('| xargs -I{} grep -I')
+ ->add($expr->isCaseSensitive() ? null : '-i')
+ ->add($not ? '-L' : '-l')
+ ->add('-Ee')->arg($expr->renderPattern())
+ ->add('{}')
+ ;
+ }
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php
new file mode 100644
index 0000000..0fbf48f
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php
@@ -0,0 +1,104 @@
+<?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\Adapter;
+
+use Symfony\Component\Finder\Shell\Shell;
+use Symfony\Component\Finder\Shell\Command;
+use Symfony\Component\Finder\Iterator\SortableIterator;
+use Symfony\Component\Finder\Expression\Expression;
+
+/**
+ * Shell engine implementation using GNU find command.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class GnuFindAdapter extends AbstractFindAdapter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'gnu_find';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildFormatSorting(Command $command, $sort)
+ {
+ switch ($sort) {
+ case SortableIterator::SORT_BY_NAME:
+ $command->ins('sort')->add('| sort');
+
+ return;
+ case SortableIterator::SORT_BY_TYPE:
+ $format = '%y';
+ break;
+ case SortableIterator::SORT_BY_ACCESSED_TIME:
+ $format = '%A@';
+ break;
+ case SortableIterator::SORT_BY_CHANGED_TIME:
+ $format = '%C@';
+ break;
+ case SortableIterator::SORT_BY_MODIFIED_TIME:
+ $format = '%T@';
+ break;
+ default:
+ throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
+ }
+
+ $command
+ ->get('find')
+ ->add('-printf')
+ ->arg($format.' %h/%f\\n')
+ ->add('| sort | cut')
+ ->arg('-d ')
+ ->arg('-f2-')
+ ;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return $this->shell->getType() === Shell::TYPE_UNIX && parent::canBeUsed();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildFindCommand(Command $command, $dir)
+ {
+ return parent::buildFindCommand($command, $dir)->add('-regextype posix-extended');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildContentFiltering(Command $command, array $contains, $not = false)
+ {
+ foreach ($contains as $contain) {
+ $expr = Expression::create($contain);
+
+ // todo: avoid forking process for each $pattern by using multiple -e options
+ $command
+ ->add('| xargs -I{} -r grep -I')
+ ->add($expr->isCaseSensitive() ? null : '-i')
+ ->add($not ? '-L' : '-l')
+ ->add('-Ee')->arg($expr->renderPattern())
+ ->add('{}')
+ ;
+ }
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php
new file mode 100644
index 0000000..378a26a
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php
@@ -0,0 +1,98 @@
+<?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\Adapter;
+
+use Symfony\Component\Finder\Iterator;
+
+/**
+ * PHP finder engine implementation.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class PhpAdapter extends AbstractAdapter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function searchInDirectory($dir)
+ {
+ $flags = \RecursiveDirectoryIterator::SKIP_DOTS;
+
+ if ($this->followLinks) {
+ $flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS;
+ }
+
+ $iterator = new \RecursiveIteratorIterator(
+ new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs),
+ \RecursiveIteratorIterator::SELF_FIRST
+ );
+
+ if ($this->minDepth > 0 || $this->maxDepth < PHP_INT_MAX) {
+ $iterator = new Iterator\DepthRangeFilterIterator($iterator, $this->minDepth, $this->maxDepth);
+ }
+
+ if ($this->mode) {
+ $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
+ }
+
+ if ($this->exclude) {
+ $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
+ }
+
+ if ($this->names || $this->notNames) {
+ $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames);
+ }
+
+ if ($this->contains || $this->notContains) {
+ $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
+ }
+
+ if ($this->sizes) {
+ $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes);
+ }
+
+ if ($this->dates) {
+ $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates);
+ }
+
+ if ($this->filters) {
+ $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
+ }
+
+ if ($this->sort) {
+ $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
+ $iterator = $iteratorAggregate->getIterator();
+ }
+
+ if ($this->paths || $this->notPaths) {
+ $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths);
+ }
+
+ return $iterator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'php';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return true;
+ }
+}