Passed
Push — master ( 235c52...927bab )
by Daniel
30:30 queued 10s
created

GlobIterator::descend()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 4
c 1
b 0
f 1
dl 0
loc 7
ccs 0
cts 6
cp 0
rs 10
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
namespace OCA\CMSPico\Files\Glob;
4
5
use OCA\CMSPico\Files\FileInterface;
6
use OCA\CMSPico\Files\FolderInterface;
7
use OCA\CMSPico\Files\NodeInterface;
8
use OCP\Files\GenericFileException;
9
use OCP\Files\NotPermittedException;
10
11
class GlobIterator implements \Iterator
12
{
13
	/** @var FolderInterface */
14
	private $folder;
15
16
	/** @var GlobPattern */
17
	private $pattern;
18
19
	/** @var FolderInterface[] */
20
	private $folders;
21
22
	/** @var FolderInterface */
23
	private $current;
24
25
	/** @var int */
26
	private $depth;
27
28
	/** @var FileInterface */
29
	private $currentValue;
30
31
	/** @var int */
32
	private $currentKey;
33
34
	/**
35
	 * GlobIterator constructor.
36
	 *
37
	 * @param FolderInterface $folder
38
	 * @param string          $pattern
39
	 */
40
	public function __construct(FolderInterface $folder, string $pattern)
41
	{
42
		$this->folder = $folder;
43
		$this->pattern = new GlobPattern($pattern);
44
45
		$this->init();
46
	}
47
48
	/**
49
	 * @return void
50
	 */
51
	private function init()
52
	{
53
		$this->folders = [ $this->folder ];
54
		$this->current = $this->folder;
55
		$this->depth = 0;
56
57
		$this->currentValue = null;
58
		$this->currentKey = -1;
59
	}
60
61
	/**
62
	 * @throws NotPermittedException
63
	 * @throws GenericFileException
64
	 */
65
	public function rewind()
66
	{
67
		$this->init();
68
69
		$this->current->rewind();
70
	}
71
72
	/**
73
	 * @return void
74
	 */
75
	public function next()
76
	{
77
		$this->current->next();
78
	}
79
80
	/**
81
	 * @return bool
82
	 */
83
	public function valid(): bool
84
	{
85
		do {
86
			if ($this->current->valid()) {
87
				/** @var NodeInterface $file */
88
				$file = $this->current->current();
89
90
				if (!$this->pattern->compare($this->depth, $file->getName())) {
91
					$this->next();
92
					continue;
93
				}
94
95
				if ($file->isFolder()) {
96
					/** @var FolderInterface $file */
97
					$this->descend($file);
98
					continue;
99
				}
100
101
				/** @var FileInterface $file */
102
				$this->set($file);
103
				return true;
104
			} elseif ($this->depth > 0) {
105
				$this->ascend();
106
				continue;
107
			}
108
109
			return false;
110
		} while (true);
111
	}
112
113
	/**
114
	 * @return FileInterface
115
	 */
116
	public function current(): FileInterface
117
	{
118
		return $this->currentValue;
119
	}
120
121
	/**
122
	 * @return int
123
	 */
124
	public function key(): int
125
	{
126
		return $this->currentKey;
127
	}
128
129
	/**
130
	 * @param FolderInterface $folder
131
	 */
132
	private function descend(FolderInterface $folder)
133
	{
134
		$this->folders[] = $folder;
135
		$this->depth++;
136
137
		$this->current = $this->folders[$this->depth];
138
		$this->current->rewind();
139
	}
140
141
	/**
142
	 * @return void
143
	 */
144
	private function ascend()
145
	{
146
		array_pop($this->folders);
147
		$this->depth--;
148
149
		$this->current = $this->folders[$this->depth];
150
		$this->current->next();
151
	}
152
153
	/**
154
	 * @param FileInterface $file
155
	 */
156
	private function set(FileInterface $file)
157
	{
158
		$this->currentValue = $file;
159
		$this->currentKey++;
160
	}
161
}
162