Passed
Push — master ( bd38b3...6f6d5d )
by Daniel
24:58
created

StorageFolder::listing()   A

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 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 0
cts 2
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
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|null */
58
	private $eventDispatcher;
59
60
	/**
61
	 * StorageFolder constructor.
62
	 *
63
	 * @param OCFolder    $folder
64
	 * @param string|null $basePath
65
	 *
66
	 * @throws InvalidPathException
67
	 */
68 7
	public function __construct(OCFolder $folder, string $basePath = null)
69
	{
70 7
		$this->tempManager = \OC::$server->getTempManager();
71 7
		$this->connection = \OC::$server->query(IDBConnection::class);
72 7
		$this->logger = \OC::$server->query(ILogger::class);
73
74 7
		parent::__construct($folder, $basePath);
75 7
	}
76
77
	/**
78
	 * {@inheritDoc}
79
	 */
80 2
	public function getLocalPath(): string
81
	{
82 2
		if ($this->isLocal()) {
83 2
			return parent::getLocalPath();
84
		}
85
86
		$cachePath = $this->getOCNode()->getPath();
87
		if (!isset(self::$localPathCache[$cachePath])) {
88
			self::$localPathCache[$cachePath] = $this->tempManager->getTemporaryFolder();
89
		}
90
91
		return self::$localPathCache[$cachePath];
92
	}
93
94
	/**
95
	 * {@inheritDoc}
96
	 */
97
	public function listing(): array
98
	{
99
		return iterator_to_array($this->getGenerator());
100
	}
101
102
	/**
103
	 * {@inheritDoc}
104
	 */
105 2
	protected function getGenerator(): \Generator
106
	{
107 2
		$basePath = $this->getPath();
108 2
		foreach ($this->node->getDirectoryListing() as $node) {
109 2
			yield $this->repackNode($node, $basePath);
110
		}
111 2
	}
112
113
	/**
114
	 * {@inheritDoc}
115
	 */
116 5
	public function exists(string $path): bool
117
	{
118
		// check for root path breakouts
119 5
		$this->getBasePath($path);
120
121 5
		return $this->node->nodeExists($path);
122
	}
123
124
	/**
125
	 * {@inheritDoc}
126
	 */
127 7
	public function get(string $path): NodeInterface
128
	{
129 7
		$basePath = $this->getBasePath($path);
130 7
		return $this->repackNode($this->node->get($path), $basePath);
131
	}
132
133
	/**
134
	 * {@inheritDoc}
135
	 */
136 5
	public function newFolder(string $path): FolderInterface
137
	{
138 5
		if ($this->exists($path)) {
139
			throw new AlreadyExistsException();
140
		}
141
142 5
		$basePath = $this->getBasePath($path);
143 5
		return new StorageFolder($this->node->newFolder($path), $basePath);
144
	}
145
146
	/**
147
	 * {@inheritDoc}
148
	 */
149 4
	public function newFile(string $path): FileInterface
150
	{
151 4
		if ($this->exists($path)) {
152
			throw new AlreadyExistsException();
153
		}
154
155 4
		$basePath = $this->getBasePath($path);
156 4
		return new StorageFile($this->node->newFile($path), $basePath);
157
	}
158
159
	/**
160
	 * {@inheritDoc}
161
	 */
162 3
	public function fakeRoot(): FolderInterface
163
	{
164 3
		return new StorageFolder($this->node);
165
	}
166
167
	/**
168
	 * {@inheritDoc}
169
	 */
170 5
	public function sync(bool $recursive = FolderInterface::SYNC_RECURSIVE)
171
	{
172
		// TODO >= NC 18: Remove version switch
173 5
		list($majorVersion) = \OC_Util::getVersion();
174 5
		if ($majorVersion >= 18) {
175 5
			if ($this->eventDispatcher === null) {
176 5
				$this->eventDispatcher = \OC::$server->query(IEventDispatcher::class);
177
			}
178
179 5
			$scanner = new Scanner(null, $this->connection, $this->eventDispatcher, $this->logger);
180
		} else {
181
			$scanner = new Scanner(null, $this->connection, $this->logger);
0 ignored issues
show
Bug introduced by
$this->logger of type OCP\ILogger is incompatible with the type OCP\EventDispatcher\IEventDispatcher expected by parameter $dispatcher of OC\Files\Utils\Scanner::__construct(). ( Ignorable by Annotation )

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

181
			$scanner = new Scanner(null, $this->connection, /** @scrutinizer ignore-type */ $this->logger);
Loading history...
Bug introduced by
The call to OC\Files\Utils\Scanner::__construct() has too few arguments starting with logger. ( Ignorable by Annotation )

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

181
			$scanner = /** @scrutinizer ignore-call */ new Scanner(null, $this->connection, $this->logger);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
182
		}
183
184
		try {
185 5
			$scanner->scan($this->node->getPath(), $recursive);
186
		} catch (ForbiddenException $e) {
187
			throw new NotPermittedException();
188
		}
189 5
	}
190
191
	/**
192
	 * {@inheritDoc}
193
	 */
194
	public function isCreatable(): bool
195
	{
196
		return $this->node->isCreatable();
197
	}
198
199
	/**
200
	 * @param string $path
201
	 *
202
	 * @return string|null
203
	 * @throws InvalidPathException
204
	 */
205 7
	private function getBasePath(string $path)
206
	{
207 7
		$path = $this->normalizePath($this->getPath() . '/' . $path);
208 7
		return ($path !== '/') ? dirname($path) : null;
209
	}
210
}
211