ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
SortableIterator.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
23use ArrayIterator;
26use InvalidArgumentException;
27use IteratorAggregate;
28use Traversable;
29use Closure;
30
36class SortableIterator implements IteratorAggregate
37{
38 public const SORT_BY_NONE = 0;
39 public const SORT_BY_NAME = 1;
40 public const SORT_BY_TYPE = 2;
41 public const SORT_BY_NAME_NATURAL = 4;
42 public const SORT_BY_TIME = 5;
43
45 private $sort;
46
52 public function __construct(
53 private Filesystem $filesystem,
54 private Traversable $iterator,
55 $sort,
56 $reverseOrder = false
57 ) {
58 $order = $reverseOrder ? -1 : 1;
59
60 if (self::SORT_BY_NAME === $sort) {
61 $this->sort = static function (Metadata $left, Metadata $right) use ($order): int {
62 $leftRealPath = $left->getPath();
63 $rightRealPath = $right->getPath();
64
65 return $order * strcmp($leftRealPath, $rightRealPath);
66 };
67 } elseif (self::SORT_BY_NAME_NATURAL === $sort) {
68 $this->sort = static function (Metadata $left, Metadata $right) use ($order): int {
69 $leftRealPath = $left->getPath();
70 $rightRealPath = $right->getPath();
71
72 return $order * strnatcmp($leftRealPath, $rightRealPath);
73 };
74 } elseif (self::SORT_BY_TYPE === $sort) {
75 $this->sort = static function (Metadata $left, Metadata $right) use ($order): int {
76 if ($left->isDir() && $right->isFile()) {
77 return -$order;
78 }
79 if ($left->isFile() && $right->isDir()) {
80 return $order;
81 }
82
83 $leftRealPath = $left->getPath();
84 $rightRealPath = $right->getPath();
85
86 return $order * strcmp($leftRealPath, $rightRealPath);
87 };
88 } elseif (self::SORT_BY_TIME === $sort) {
89 $this->sort = function (Metadata $left, Metadata $right) use ($order): int {
90 $leftTimestamp = $this->filesystem->getTimestamp($left->getPath());
91 $rightTimestamp = $this->filesystem->getTimestamp($right->getPath());
92
93 return $order * ($leftTimestamp->getTimestamp() - $rightTimestamp->getTimestamp());
94 };
95 } elseif (self::SORT_BY_NONE === $sort) {
96 $this->sort = $order;
97 } elseif (is_callable($sort)) {
98 $this->sort = $sort;
99 if ($reverseOrder) {
100 $this->sort = static fn(Metadata $left, Metadata $right): int|float => -$sort($left, $right);
101 }
102 } else {
103 throw new InvalidArgumentException(
104 'The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.'
105 );
106 }
107 }
108
112 public function getIterator(): \Traversable
113 {
114 if (1 === $this->sort) {
115 return $this->iterator;
116 }
117
118 $array = iterator_to_array($this->iterator, true);
119 if (-1 === $this->sort) {
120 $array = array_reverse($array);
121 } else {
122 uasort($array, $this->sort);
123 }
124
125 return new ArrayIterator($array);
126 }
127}
This class holds all default metadata send by the filesystem adapters.
Definition: Metadata.php:33
getPath()
The path to the file or directory.
Definition: Metadata.php:63
isFile()
The path is a file.
Definition: Metadata.php:95
isDir()
The path is a directory.
Definition: Metadata.php:86
sort(Closure $closure)
Sorts files and directories by an anonymous function.
Definition: Finder.php:262
__construct(private Filesystem $filesystem, private Traversable $iterator, $sort, $reverseOrder=false)
Sortable constructor.
The filesystem interface provides the public interface for the Filesystem service API consumer.
Definition: Filesystem.php:37