ILIAS  release_8 Revision v8.24
SortableIterator.php
Go to the documentation of this file.
1<?php
2
3declare(strict_types=1);
4
6
7use ArrayIterator;
10use InvalidArgumentException;
11use IteratorAggregate;
12use Traversable;
13use Closure;
14
15/******************************************************************************
16 *
17 * This file is part of ILIAS, a powerful learning management system.
18 *
19 * ILIAS is licensed with the GPL-3.0, you should have received a copy
20 * of said license along with the source code.
21 *
22 * If this is not the case or you just want to try ILIAS, you'll find
23 * us at:
24 * https://www.ilias.de
25 * https://github.com/ILIAS-eLearning
26 *
27 *****************************************************************************/
28
34class SortableIterator implements IteratorAggregate
35{
36 public const SORT_BY_NONE = 0;
37 public const SORT_BY_NAME = 1;
38 public const SORT_BY_TYPE = 2;
39 public const SORT_BY_NAME_NATURAL = 4;
40 public const SORT_BY_TIME = 5;
41
42 private FileSystem $filesystem;
43
44 private \Traversable $iterator;
45
47 private $sort;
48
56 public function __construct(Filesystem $filesystem, Traversable $iterator, $sort, $reverseOrder = false)
57 {
58 $this->filesystem = $filesystem;
59 $this->iterator = $iterator;
60 $order = $reverseOrder ? -1 : 1;
61
62 if (self::SORT_BY_NAME === $sort) {
63 $this->sort = static function (Metadata $left, Metadata $right) use ($order): int {
64 $leftRealPath = $left->getPath();
65 $rightRealPath = $right->getPath();
66
67 return $order * strcmp($leftRealPath, $rightRealPath);
68 };
69 } elseif (self::SORT_BY_NAME_NATURAL === $sort) {
70 $this->sort = static function (Metadata $left, Metadata $right) use ($order): int {
71 $leftRealPath = $left->getPath();
72 $rightRealPath = $right->getPath();
73
74 return $order * strnatcmp($leftRealPath, $rightRealPath);
75 };
76 } elseif (self::SORT_BY_TYPE === $sort) {
77 $this->sort = static function (Metadata $left, Metadata $right) use ($order): int {
78 if ($left->isDir() && $right->isFile()) {
79 return -$order;
80 } elseif ($left->isFile() && $right->isDir()) {
81 return $order;
82 }
83
84 $leftRealPath = $left->getPath();
85 $rightRealPath = $right->getPath();
86
87 return $order * strcmp($leftRealPath, $rightRealPath);
88 };
89 } elseif (self::SORT_BY_TIME === $sort) {
90 $this->sort = function (Metadata $left, Metadata $right) use ($order): int {
91 $leftTimestamp = $this->filesystem->getTimestamp($left->getPath());
92 $rightTimestamp = $this->filesystem->getTimestamp($right->getPath());
93
94 return $order * ($leftTimestamp->getTimestamp() - $rightTimestamp->getTimestamp());
95 };
96 } elseif (self::SORT_BY_NONE === $sort) {
97 $this->sort = $order;
98 } elseif (is_callable($sort)) {
99 $this->sort = $sort;
100 if ($reverseOrder) {
101 $this->sort = static fn (Metadata $left, Metadata $right) => -$sort($left, $right);
102 }
103 } else {
104 throw new InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.');
105 }
106 }
107
111 public function getIterator(): \Traversable
112 {
113 if (1 === $this->sort) {
114 return $this->iterator;
115 }
116
117 $array = iterator_to_array($this->iterator, true);
118 if (-1 === $this->sort) {
119 $array = array_reverse($array);
120 } else {
121 uasort($array, $this->sort);
122 }
123
124 return new ArrayIterator($array);
125 }
126}
getPath()
The path to the file or directory.
Definition: Metadata.php:56
isFile()
The path is a file.
Definition: Metadata.php:98
isDir()
The path is a directory.
Definition: Metadata.php:86
sort(Closure $closure)
Sorts files and directories by an anonymous function.
Definition: Finder.php:273
__construct(Filesystem $filesystem, Traversable $iterator, $sort, $reverseOrder=false)
Sortable constructor.
Interface Filesystem.
Definition: Filesystem.php:40
Class FlySystemFileAccessTest \Provider\FlySystem @runTestsInSeparateProcesses @preserveGlobalState d...