18
18
*/
19
19
class SortableIterator implements \IteratorAggregate
20
20
{
21
+ const SORT_BY_NONE = 0 ;
21
22
const SORT_BY_NAME = 1 ;
22
23
const SORT_BY_TYPE = 2 ;
23
24
const SORT_BY_ACCESSED_TIME = 3 ;
@@ -34,40 +35,43 @@ class SortableIterator implements \IteratorAggregate
34
35
*
35
36
* @throws \InvalidArgumentException
36
37
*/
37
- public function __construct (\Traversable $ iterator , $ sort )
38
+ public function __construct (\Traversable $ iterator , $ sort, bool $ reverseOrder = false )
38
39
{
39
40
$ this ->iterator = $ iterator ;
41
+ $ order = $ reverseOrder ? -1 : 1 ;
40
42
41
43
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 ());
44
46
};
45
47
} 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 ());
48
50
};
49
51
} elseif (self ::SORT_BY_TYPE === $ sort ) {
50
- $ this ->sort = function ($ a , $ b ) {
52
+ $ this ->sort = function ($ a , $ b ) use ( $ order ) {
51
53
if ($ a ->isDir () && $ b ->isFile ()) {
52
- return -1 ;
54
+ return -$ order ;
53
55
} elseif ($ a ->isFile () && $ b ->isDir ()) {
54
- return 1 ;
56
+ return $ order ;
55
57
}
56
58
57
- return strcmp ($ a ->getRealpath () ?: $ a ->getPathname (), $ b ->getRealpath () ?: $ b ->getPathname ());
59
+ return $ order * strcmp ($ a ->getRealpath () ?: $ a ->getPathname (), $ b ->getRealpath () ?: $ b ->getPathname ());
58
60
};
59
61
} 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 () );
62
64
};
63
65
} 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 () );
66
68
};
67
69
} 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 () );
70
72
};
73
+ } elseif (self ::SORT_BY_NONE === $ sort ) {
74
+ $ this ->sort = $ order ;
71
75
} elseif (\is_callable ($ sort )) {
72
76
$ this ->sort = $ sort ;
73
77
} else {
@@ -77,8 +81,17 @@ public function __construct(\Traversable $iterator, $sort)
77
81
78
82
public function getIterator ()
79
83
{
84
+ if (1 === $ this ->sort ) {
85
+ return $ this ->iterator ;
86
+ }
87
+
80
88
$ 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
+ }
82
95
83
96
return new \ArrayIterator ($ array );
84
97
}
0 commit comments