Passed
Pull Request — master (#167)
by Daniel
50:15 queued 22:39
created

StorageFolder::getBasePath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 2
nc 2
nop 1
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
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\NotPermittedException;
34
use OCP\IDBConnection;
35
use OCP\ILogger;
36
use OCP\ITempManager;
37
38
class StorageFolder extends AbstractStorageNode implements FolderInterface
39
{
40
	use FolderTrait;
41
42
	/** @var array<string,string> */
43
	private static $localPathCache = [];
44
45
	/** @var OCFolder */
46
	protected $node;
47
48
	/** @var ITempManager */
49
	private $tempManager;
50
51
	/** @var IDBConnection */
52
	private $connection;
53
54
	/** @var ILogger */
55
	private $logger;
56
57
	/** @var IEventDispatcher */
58
	private $eventDispatcher;
59
60
	/** @var StorageFolder|null */
61
	protected $rootFolder;
62
63
	/**
64
	 * StorageFolder constructor.
65
	 *
66
	 * @param OCFolder    $folder
67
	 * @param string|null $parentPath
68
	 *
69
	 * @throws InvalidPathException
70
	 */
71 29
	public function __construct(OCFolder $folder, string $parentPath = null)
72
	{
73 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

73
		$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...
74 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

74
		$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...
75 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

75
		$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...
76 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

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