GlobIterator::key()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
c 0
b 0
f 0
ccs 0
cts 3
cp 0
rs 10
cc 1
nc 1
nop 0
crap 2
1
<?php
2
/**
3
 * CMS Pico - Create websites using Pico CMS for Nextcloud.
4
 *
5
 * @copyright Copyright (c) 2019, Daniel Rudolf (<[email protected]>)
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License as
11
 * published by the Free Software Foundation, either version 3 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
23
namespace OCA\CMSPico\Files\Glob;
24
25
use OCA\CMSPico\Files\FileInterface;
26
use OCA\CMSPico\Files\FolderInterface;
27
use OCA\CMSPico\Files\NodeInterface;
28
use OCP\Files\GenericFileException;
29
use OCP\Files\NotPermittedException;
30
31
class GlobIterator implements \Iterator
32
{
33
	/** @var FolderInterface */
34
	private $folder;
35
36
	/** @var GlobPattern */
37
	private $pattern;
38
39
	/** @var FolderInterface[] */
40
	private $folders;
41
42
	/** @var FolderInterface */
43
	private $current;
44
45
	/** @var int */
46
	private $depth;
47
48
	/** @var FileInterface */
49
	private $currentValue;
50
51
	/** @var int */
52
	private $currentKey;
53
54
	/**
55
	 * GlobIterator constructor.
56
	 *
57
	 * @param FolderInterface $folder
58
	 * @param string          $pattern
59
	 */
60
	public function __construct(FolderInterface $folder, string $pattern)
61
	{
62
		$this->folder = $folder;
63
		$this->pattern = new GlobPattern($pattern);
64
65
		$this->init();
66
	}
67
68
	/**
69
	 * @return void
70
	 */
71
	private function init(): void
72
	{
73
		$this->folders = [ $this->folder ];
74
		$this->current = $this->folder;
75
		$this->depth = 0;
76
77
		$this->currentValue = null;
78
		$this->currentKey = -1;
79
	}
80
81
	/**
82
	 * @throws NotPermittedException
83
	 * @throws GenericFileException
84
	 */
85
	public function rewind(): void
86
	{
87
		$this->init();
88
89
		$this->current->rewind();
90
	}
91
92
	/**
93
	 * @return void
94
	 */
95
	public function next(): void
96
	{
97
		$this->current->next();
98
	}
99
100
	/**
101
	 * @return bool
102
	 */
103
	public function valid(): bool
104
	{
105
		do {
106
			if ($this->current->valid()) {
107
				/** @var NodeInterface $file */
108
				$file = $this->current->current();
109
110
				if (!$this->pattern->compare($this->depth, $file->getName())) {
111
					$this->next();
112
					continue;
113
				}
114
115
				if ($file->isFolder()) {
116
					/** @var FolderInterface $file */
117
					$this->descend($file);
118
					continue;
119
				}
120
121
				/** @var FileInterface $file */
122
				$this->set($file);
123
				return true;
124
			} elseif ($this->depth > 0) {
125
				$this->ascend();
126
				continue;
127
			}
128
129
			return false;
130
		} while (true);
131
	}
132
133
	/**
134
	 * @return FileInterface
135
	 */
136
	public function current(): FileInterface
137
	{
138
		return $this->currentValue;
139
	}
140
141
	/**
142
	 * @return int
143
	 */
144
	public function key(): int
145
	{
146
		return $this->currentKey;
147
	}
148
149
	/**
150
	 * @param FolderInterface $folder
151
	 */
152
	private function descend(FolderInterface $folder): void
153
	{
154
		$this->folders[] = $folder;
155
		$this->depth++;
156
157
		$this->current = $this->folders[$this->depth];
158
		$this->current->rewind();
159
	}
160
161
	/**
162
	 * @return void
163
	 */
164
	private function ascend(): void
165
	{
166
		array_pop($this->folders);
167
		$this->depth--;
168
169
		$this->current = $this->folders[$this->depth];
170
		$this->current->next();
171
	}
172
173
	/**
174
	 * @param FileInterface $file
175
	 */
176
	private function set(FileInterface $file): void
177
	{
178
		$this->currentValue = $file;
179
		$this->currentKey++;
180
	}
181
}
182