From ce861d186138d0c3a2ace5ae974ee8f3ac903566 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 10 Oct 2018 05:11:49 -0700 Subject: [PATCH] [Finder] make reverse sorting a bit more generic --- src/Symfony/Component/Finder/CHANGELOG.md | 2 +- src/Symfony/Component/Finder/Finder.php | 9 +--- .../Iterator/ReverseSortingIterator.php | 32 ------------- .../Finder/Iterator/SortableIterator.php | 45 ++++++++++++------- .../Iterator/ReverseSortingIteratorTest.php | 32 ------------- 5 files changed, 32 insertions(+), 88 deletions(-) delete mode 100644 src/Symfony/Component/Finder/Iterator/ReverseSortingIterator.php delete mode 100644 src/Symfony/Component/Finder/Tests/Iterator/ReverseSortingIteratorTest.php diff --git a/src/Symfony/Component/Finder/CHANGELOG.md b/src/Symfony/Component/Finder/CHANGELOG.md index 2431b525b8..9abccfc237 100644 --- a/src/Symfony/Component/Finder/CHANGELOG.md +++ b/src/Symfony/Component/Finder/CHANGELOG.md @@ -7,7 +7,7 @@ CHANGELOG * added $useNaturalSort option to Finder::sortByName() method * the `Finder::sortByName()` method will have a new `$useNaturalSort` argument in version 5.0, not defining it is deprecated - * added `Finder::reverseSorting` to reverse the sorting + * added `Finder::reverseSorting()` to reverse the sorting 4.0.0 ----- diff --git a/src/Symfony/Component/Finder/Finder.php b/src/Symfony/Component/Finder/Finder.php index 0981ca4b56..993f9e3449 100644 --- a/src/Symfony/Component/Finder/Finder.php +++ b/src/Symfony/Component/Finder/Finder.php @@ -750,13 +750,8 @@ class Finder implements \IteratorAggregate, \Countable $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths); } - if ($this->sort) { - $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort); - $iterator = $iteratorAggregate->getIterator(); - } - - if ($this->reverseSorting) { - $iteratorAggregate = new Iterator\ReverseSortingIterator($iterator); + if ($this->sort || $this->reverseSorting) { + $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort, $this->reverseSorting); $iterator = $iteratorAggregate->getIterator(); } diff --git a/src/Symfony/Component/Finder/Iterator/ReverseSortingIterator.php b/src/Symfony/Component/Finder/Iterator/ReverseSortingIterator.php deleted file mode 100644 index ba37c2604e..0000000000 --- a/src/Symfony/Component/Finder/Iterator/ReverseSortingIterator.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Iterator; - -/** - * Reverse the order of a previous iterator. - * - * @author Grégoire Pineau - */ -class ReverseSortingIterator implements \IteratorAggregate -{ - private $iterator; - - public function __construct(\Traversable $iterator) - { - $this->iterator = $iterator; - } - - public function getIterator() - { - return new \ArrayIterator(array_reverse(iterator_to_array($this->iterator, true))); - } -} diff --git a/src/Symfony/Component/Finder/Iterator/SortableIterator.php b/src/Symfony/Component/Finder/Iterator/SortableIterator.php index 00cbab6ee9..c6e2605b41 100644 --- a/src/Symfony/Component/Finder/Iterator/SortableIterator.php +++ b/src/Symfony/Component/Finder/Iterator/SortableIterator.php @@ -18,6 +18,7 @@ namespace Symfony\Component\Finder\Iterator; */ class SortableIterator implements \IteratorAggregate { + const SORT_BY_NONE = 0; const SORT_BY_NAME = 1; const SORT_BY_TYPE = 2; const SORT_BY_ACCESSED_TIME = 3; @@ -34,40 +35,43 @@ class SortableIterator implements \IteratorAggregate * * @throws \InvalidArgumentException */ - public function __construct(\Traversable $iterator, $sort) + public function __construct(\Traversable $iterator, $sort, bool $reverseOrder = false) { $this->iterator = $iterator; + $order = $reverseOrder ? -1 : 1; if (self::SORT_BY_NAME === $sort) { - $this->sort = function ($a, $b) { - return strcmp($a->getRealpath() ?: $a->getPathname(), $b->getRealpath() ?: $b->getPathname()); + $this->sort = function ($a, $b) use ($order) { + return $order * strcmp($a->getRealpath() ?: $a->getPathname(), $b->getRealpath() ?: $b->getPathname()); }; } elseif (self::SORT_BY_NAME_NATURAL === $sort) { - $this->sort = function ($a, $b) { - return strnatcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); + $this->sort = function ($a, $b) use ($order) { + return $order * strnatcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); }; } elseif (self::SORT_BY_TYPE === $sort) { - $this->sort = function ($a, $b) { + $this->sort = function ($a, $b) use ($order) { if ($a->isDir() && $b->isFile()) { - return -1; + return -$order; } elseif ($a->isFile() && $b->isDir()) { - return 1; + return $order; } - return strcmp($a->getRealpath() ?: $a->getPathname(), $b->getRealpath() ?: $b->getPathname()); + return $order * 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(); + $this->sort = function ($a, $b) use ($order) { + return $order * ($a->getATime() - $b->getATime()); }; } elseif (self::SORT_BY_CHANGED_TIME === $sort) { - $this->sort = function ($a, $b) { - return $a->getCTime() - $b->getCTime(); + $this->sort = function ($a, $b) use ($order) { + return $order * ($a->getCTime() - $b->getCTime()); }; } elseif (self::SORT_BY_MODIFIED_TIME === $sort) { - $this->sort = function ($a, $b) { - return $a->getMTime() - $b->getMTime(); + $this->sort = function ($a, $b) use ($order) { + return $order * ($a->getMTime() - $b->getMTime()); }; + } elseif (self::SORT_BY_NONE === $sort) { + $this->sort = $order; } elseif (\is_callable($sort)) { $this->sort = $sort; } else { @@ -77,8 +81,17 @@ class SortableIterator implements \IteratorAggregate public function getIterator() { + if (1 === $this->sort) { + return $this->iterator; + } + $array = iterator_to_array($this->iterator, true); - uasort($array, $this->sort); + + if (-1 === $this->sort) { + $array = array_reverse($array); + } else { + uasort($array, $this->sort); + } return new \ArrayIterator($array); } diff --git a/src/Symfony/Component/Finder/Tests/Iterator/ReverseSortingIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/ReverseSortingIteratorTest.php deleted file mode 100644 index 4cd3099099..0000000000 --- a/src/Symfony/Component/Finder/Tests/Iterator/ReverseSortingIteratorTest.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Finder\Tests\Iterator; - -use Symfony\Component\Finder\Iterator\ReverseSortingIterator; - -class ReverseSortingIteratorTest extends IteratorTestCase -{ - public function test() - { - $iterator = new ReverseSortingIterator(new MockFileListIterator(array( - 'a.txt', - 'b.yaml', - 'c.php', - ))); - - $result = iterator_to_array($iterator); - $this->assertCount(3, $iterator); - $this->assertSame('c.php', $result[0]->getFilename()); - $this->assertSame('b.yaml', $result[1]->getFilename()); - $this->assertSame('a.txt', $result[2]->getFilename()); - } -}