From 3cd0dcaaeee4b9e019b223567c1061bfbbfa2501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Mon, 16 Jul 2018 16:10:04 +0200 Subject: [PATCH] [Finder] Added a way to inverse a previous sorting Sometimes, it's useful to inverse the previous sorting. For exemple when you want to display the most recent uploaded files --- src/Symfony/Component/Finder/CHANGELOG.md | 1 + src/Symfony/Component/Finder/Finder.php | 18 +++++++++++ .../Iterator/ReverseSortingIterator.php | 32 +++++++++++++++++++ .../Component/Finder/Tests/FinderTest.php | 24 ++++++++++++++ .../Iterator/ReverseSortingIteratorTest.php | 32 +++++++++++++++++++ 5 files changed, 107 insertions(+) create mode 100644 src/Symfony/Component/Finder/Iterator/ReverseSortingIterator.php create 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 13bc98c65dd92..be9e85b31c7f2 100644 --- a/src/Symfony/Component/Finder/CHANGELOG.md +++ b/src/Symfony/Component/Finder/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG ----- * added $useNaturalSort option to Finder::sortByName() method + * 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 a01f7f4e377ca..3cdef54567c86 100644 --- a/src/Symfony/Component/Finder/Finder.php +++ b/src/Symfony/Component/Finder/Finder.php @@ -48,6 +48,7 @@ class Finder implements \IteratorAggregate, \Countable private $depths = array(); private $sizes = array(); private $followLinks = false; + private $reverseSorting = false; private $sort = false; private $ignore = 0; private $dirs = array(); @@ -460,6 +461,18 @@ public function sortByAccessedTime() return $this; } + /** + * Reverses the sorting. + * + * @return $this + */ + public function reverseSorting() + { + $this->reverseSorting = true; + + return $this; + } + /** * Sorts files and directories by the last inode changed time. * @@ -739,6 +752,11 @@ private function searchInDirectory(string $dir): \Iterator $iterator = $iteratorAggregate->getIterator(); } + if ($this->reverseSorting) { + $iteratorAggregate = new Iterator\ReverseSortingIterator($iterator); + $iterator = $iteratorAggregate->getIterator(); + } + return $iterator; } diff --git a/src/Symfony/Component/Finder/Iterator/ReverseSortingIterator.php b/src/Symfony/Component/Finder/Iterator/ReverseSortingIterator.php new file mode 100644 index 0000000000000..ba37c2604ec37 --- /dev/null +++ b/src/Symfony/Component/Finder/Iterator/ReverseSortingIterator.php @@ -0,0 +1,32 @@ + + * + * 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/Tests/FinderTest.php b/src/Symfony/Component/Finder/Tests/FinderTest.php index 35a71acffebbc..7b98d5e1b2c04 100644 --- a/src/Symfony/Component/Finder/Tests/FinderTest.php +++ b/src/Symfony/Component/Finder/Tests/FinderTest.php @@ -611,6 +611,30 @@ public function testSortByModifiedTime() )), $finder->in(self::$tmpDir)->getIterator()); } + public function testReverseSorting() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->sortByName()); + $this->assertSame($finder, $finder->reverseSorting()); + $this->assertOrderedIteratorInForeach($this->toAbsolute(array( + 'toto', + 'test.py', + 'test.php', + 'qux_2_0.php', + 'qux_12_0.php', + 'qux_10_2.php', + 'qux_1002_0.php', + 'qux_1000_1.php', + 'qux_0_1.php', + 'qux/baz_1_2.py', + 'qux/baz_100_1.py', + 'qux', + 'foo/bar.tmp', + 'foo bar', + 'foo', + )), $finder->in(self::$tmpDir)->getIterator()); + } + public function testSortByNameNatural() { $finder = $this->buildFinder(); diff --git a/src/Symfony/Component/Finder/Tests/Iterator/ReverseSortingIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/ReverseSortingIteratorTest.php new file mode 100644 index 0000000000000..4cd309909912d --- /dev/null +++ b/src/Symfony/Component/Finder/Tests/Iterator/ReverseSortingIteratorTest.php @@ -0,0 +1,32 @@ + + * + * 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()); + } +}