1818 */
1919class SortableIterator implements \IteratorAggregate
2020{
21+ const SORT_BY_NONE = 0 ;
2122 const SORT_BY_NAME = 1 ;
2223 const SORT_BY_TYPE = 2 ;
2324 const SORT_BY_ACCESSED_TIME = 3 ;
@@ -34,40 +35,43 @@ class SortableIterator implements \IteratorAggregate
3435 *
3536 * @throws \InvalidArgumentException
3637 */
37- public function __construct (\Traversable $ iterator , $ sort )
38+ public function __construct (\Traversable $ iterator , $ sort, bool $ reverseOrder = false )
3839 {
3940 $ this ->iterator = $ iterator ;
41+ $ order = $ reverseOrder ? -1 : 1 ;
4042
4143 if (self ::SORT_BY_NAME === $ sort ) {
42- $ this ->sort = function ($ a , $ b ) {
43- return strcmp ($ a ->getRealpath () ?: $ a ->getPathname (), $ b ->getRealpath () ?: $ b ->getPathname ());
44+ $ this ->sort = function ($ a , $ b ) use ( $ order ) {
45+ return $ order * strcmp ($ a ->getRealpath () ?: $ a ->getPathname (), $ b ->getRealpath () ?: $ b ->getPathname ());
4446 };
4547 } elseif (self ::SORT_BY_NAME_NATURAL === $ sort ) {
46- $ this ->sort = function ($ a , $ b ) {
47- return strnatcmp ($ a ->getRealPath () ?: $ a ->getPathname (), $ b ->getRealPath () ?: $ b ->getPathname ());
48+ $ this ->sort = function ($ a , $ b ) use ( $ order ) {
49+ return $ order * strnatcmp ($ a ->getRealPath () ?: $ a ->getPathname (), $ b ->getRealPath () ?: $ b ->getPathname ());
4850 };
4951 } elseif (self ::SORT_BY_TYPE === $ sort ) {
50- $ this ->sort = function ($ a , $ b ) {
52+ $ this ->sort = function ($ a , $ b ) use ( $ order ) {
5153 if ($ a ->isDir () && $ b ->isFile ()) {
52- return -1 ;
54+ return -$ order ;
5355 } elseif ($ a ->isFile () && $ b ->isDir ()) {
54- return 1 ;
56+ return $ order ;
5557 }
5658
57- return strcmp ($ a ->getRealpath () ?: $ a ->getPathname (), $ b ->getRealpath () ?: $ b ->getPathname ());
59+ return $ order * strcmp ($ a ->getRealpath () ?: $ a ->getPathname (), $ b ->getRealpath () ?: $ b ->getPathname ());
5860 };
5961 } elseif (self ::SORT_BY_ACCESSED_TIME === $ sort ) {
60- $ this ->sort = function ($ a , $ b ) {
61- return $ a ->getATime () - $ b ->getATime ();
62+ $ this ->sort = function ($ a , $ b ) use ( $ order ) {
63+ return $ order * ( $ a ->getATime () - $ b ->getATime () );
6264 };
6365 } elseif (self ::SORT_BY_CHANGED_TIME === $ sort ) {
64- $ this ->sort = function ($ a , $ b ) {
65- return $ a ->getCTime () - $ b ->getCTime ();
66+ $ this ->sort = function ($ a , $ b ) use ( $ order ) {
67+ return $ order * ( $ a ->getCTime () - $ b ->getCTime () );
6668 };
6769 } elseif (self ::SORT_BY_MODIFIED_TIME === $ sort ) {
68- $ this ->sort = function ($ a , $ b ) {
69- return $ a ->getMTime () - $ b ->getMTime ();
70+ $ this ->sort = function ($ a , $ b ) use ( $ order ) {
71+ return $ order * ( $ a ->getMTime () - $ b ->getMTime () );
7072 };
73+ } elseif (self ::SORT_BY_NONE === $ sort ) {
74+ $ this ->sort = $ order ;
7175 } elseif (\is_callable ($ sort )) {
7276 $ this ->sort = $ sort ;
7377 } else {
@@ -77,8 +81,17 @@ public function __construct(\Traversable $iterator, $sort)
7781
7882 public function getIterator ()
7983 {
84+ if (1 === $ this ->sort ) {
85+ return $ this ->iterator ;
86+ }
87+
8088 $ array = iterator_to_array ($ this ->iterator , true );
81- uasort ($ array , $ this ->sort );
89+
90+ if (-1 === $ this ->sort ) {
91+ $ array = array_reverse ($ array );
92+ } else {
93+ uasort ($ array , $ this ->sort );
94+ }
8295
8396 return new \ArrayIterator ($ array );
8497 }
0 commit comments