Passed
Push — master ( 6c7738...4000eb )
by Daniel
26:30
created

StorageFolder::exists()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 2
c 3
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
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
declare(strict_types=1);
24
25
namespace OCA\CMSPico\Files;
26
27
use OC\Files\Utils\Scanner;
28
use OC\ForbiddenException;
29
use OCP\EventDispatcher\IEventDispatcher;
30
use OCP\Files\AlreadyExistsException;
31
use OCP\Files\Folder as OCFolder;
32
use OCP\Files\InvalidPathException;
33
use OCP\Files\NotFoundException;
34
use OCP\Files\NotPermittedException;
35
use OCP\IDBConnection;
36
use OCP\ILogger;
37
use OCP\ITempManager;
38
39
class StorageFolder extends AbstractStorageNode implements FolderInterface
40
{
41
	use FolderTrait;
42
43
	/** @var array<string,string> */
44
	private static $localPathCache = [];
45
46
	/** @var OCFolder */
47
	protected $node;
48
49
	/** @var ITempManager */
50
	private $tempManager;
51
52
	/** @var IDBConnection */
53
	private $connection;
54
55
	/** @var ILogger */
56
	private $logger;
57
58
	/** @var IEventDispatcher */
59
	private $eventDispatcher;
60
61
	/** @var StorageFolder|null */
62
	protected $rootFolder;
63
64
	/**
65
	 * StorageFolder constructor.
66
	 *
67
	 * @param OCFolder    $folder
68
	 * @param string|null $parentPath
69
	 *
70
	 * @throws InvalidPathException
71
	 */
72 29
	public function __construct(OCFolder $folder, string $parentPath = null)
73
	{
74 29
		$this->tempManager = \OC::$server->getTempManager();
0 ignored issues
show
Deprecated Code introduced by
The function OC\Server::getTempManager() has been deprecated: 20.0.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

74
		$this->tempManager = /** @scrutinizer ignore-deprecated */ \OC::$server->getTempManager();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
75 29
		$this->connection = \OC::$server->query(IDBConnection::class);
0 ignored issues
show
Deprecated Code introduced by
The function OC\ServerContainer::query() has been deprecated: 20.0.0 use \Psr\Container\ContainerInterface::get ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

75
		$this->connection = /** @scrutinizer ignore-deprecated */ \OC::$server->query(IDBConnection::class);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
76 29
		$this->logger = \OC::$server->query(ILogger::class);
0 ignored issues
show
Deprecated Code introduced by
The function OC\ServerContainer::query() has been deprecated: 20.0.0 use \Psr\Container\ContainerInterface::get ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

76
		$this->logger = /** @scrutinizer ignore-deprecated */ \OC::$server->query(ILogger::class);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
77 29
		$this->eventDispatcher = \OC::$server->query(IEventDispatcher::class);
0 ignored issues
show
Deprecated Code introduced by
The function OC\ServerContainer::query() has been deprecated: 20.0.0 use \Psr\Container\ContainerInterface::get ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

77
		$this->eventDispatcher = /** @scrutinizer ignore-deprecated */ \OC::$server->query(IEventDispatcher::class);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
78
79 29
		parent::__construct($folder, $parentPath);
80 29
	}
81
82
	/**
83
	 * {@inheritDoc}
84
	 */
85 5
	public function getLocalPath(): string
86
	{
87 5
		if ($this->isLocal()) {
88 5
			return parent::getLocalPath();
89
		}
90
91
		$cachePath = $this->getOCNode()->getPath();
92
		if (!isset(self::$localPathCache[$cachePath])) {
93
			self::$localPathCache[$cachePath] = $this->tempManager->getTemporaryFolder();
94
		}
95
96
		return self::$localPathCache[$cachePath];
97
	}
98
99
	/**
100
	 * {@inheritDoc}
101
	 */
102
	public function listing(): array
103
	{
104
		return iterator_to_array($this->getGenerator());
105
	}
106
107
	/**
108
	 * {@inheritDoc}
109
	 */
110 18
	protected function getGenerator(): \Generator
111
	{
112 18
		$parentPath = $this->getPath();
113 18
		foreach ($this->node->getDirectoryListing() as $node) {
114 15
			yield $this->repackNode($node, $parentPath);
115
		}
116 18
	}
117
118
	/**
119
	 * {@inheritDoc}
120
	 */
121 5
	public function exists(string $path): bool
122
	{
123 5
		$path = $this->normalizePath($this->getPath() . '/' . $path);
124 5
		return $this->getRootFolder()->getOCNode()->nodeExists($path);
125
	}
126
127
	/**
128
	 * {@inheritDoc}
129
	 */
130 29
	public function get(string $path): NodeInterface
131
	{
132 29
		$path = $this->normalizePath($this->getPath() . '/' . $path);
133 29
		$parentPath = ($path !== '/') ? dirname($path) : null;
134 29
		return $this->repackNode($this->getRootFolder()->getOCNode()->get($path), $parentPath);
135
	}
136
137
	/**
138
	 * {@inheritDoc}
139
	 */
140 5
	public function newFolder(string $path): FolderInterface
141
	{
142 5
		if ($this->exists($path)) {
143
			throw new AlreadyExistsException();
144
		}
145
146 5
		$path = $this->normalizePath($this->getPath() . '/' . $path);
147
148 5
		$name = basename($path);
149 5
		$parentPath = dirname($path);
150
151
		/** @var StorageFolder $parentFolder */
152 5
		$parentFolder = $this->newFolderRecursive($parentPath);
153
154 5
		if (!$parentFolder->isCreatable()) {
155
			throw new NotPermittedException();
156
		}
157
158 5
		return new StorageFolder(
159 5
			$parentFolder->getOCNode()->newFolder($name),
160 5
			($path !== '/') ? $parentPath : null
161
		);
162
	}
163
164
	/**
165
	 * {@inheritDoc}
166
	 */
167 5
	public function newFile(string $path): FileInterface
168
	{
169 5
		if ($this->exists($path)) {
170
			throw new AlreadyExistsException();
171
		}
172
173 5
		$path = $this->normalizePath($this->getPath() . '/' . $path);
174
175 5
		$name = basename($path);
176 5
		$parentPath = dirname($path);
177
178
		/** @var StorageFolder $parentFolder */
179 5
		$parentFolder = $this->newFolderRecursive($parentPath);
180
181 5
		if (!$parentFolder->isCreatable()) {
182
			throw new NotPermittedException();
183
		}
184
185 5
		return new StorageFile(
186 5
			$parentFolder->getOCNode()->newFile($name),
187 5
			($path !== '/') ? $parentPath : null
188
		);
189
	}
190
191
	/**
192
	 * {@inheritDoc}
193
	 */
194 9
	public function fakeRoot(): FolderInterface
195
	{
196 9
		return new StorageFolder($this->node);
197
	}
198
199
	/**
200
	 * {@inheritDoc}
201
	 */
202 21
	public function sync(bool $recursive = FolderInterface::SYNC_RECURSIVE): void
203
	{
204 21
		$scanner = new Scanner(null, $this->connection, $this->eventDispatcher, $this->logger);
205
206
		try {
207 21
			$scanner->scan($this->node->getPath(), $recursive);
208
		} catch (ForbiddenException $e) {
209
			throw new NotPermittedException();
210
		}
211 21
	}
212
213
	/**
214
	 * {@inheritDoc}
215
	 */
216 5
	public function isCreatable(): bool
217
	{
218 5
		return $this->node->isCreatable();
219
	}
220
221
	/**
222
	 * {@inheritDoc}
223
	 */
224 29
	protected function getRootFolder(): self
225
	{
226 29
		if ($this->getPath() === '/') {
227 29
			return $this;
228
		}
229
230 12
		if ($this->rootFolder === null) {
231 12
			$ocFolder = $this->node;
232 12
			for ($i = 0; $i < substr_count($this->getPath(), '/'); $i++) {
233
				try {
234 12
					$ocFolder = $ocFolder->getParent();
235
				} catch (NotFoundException $e) {
236
					throw new InvalidPathException();
237
				}
238
			}
239
240 12
			$this->rootFolder = new StorageFolder($ocFolder);
241
		}
242
243 12
		return $this->rootFolder;
244
	}
245
}
246