Passed
Push — master ( 4bdb47...6c7738 )
by Daniel
25:23 queued 10s
created

AbstractStorageNode::getParentPath()   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 0
Metric Value
eloc 1
c 0
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 OCP\Files\File as OCFile;
28
use OCP\Files\Folder as OCFolder;
29
use OCP\Files\InvalidPathException;
30
use OCP\Files\Node as OCNode;
31
use OCP\Files\NotFoundException;
32
33
abstract class AbstractStorageNode extends AbstractNode implements NodeInterface
34
{
35
	/** @var OCNode */
36
	protected $node;
37
38
	/** @var string|null */
39
	protected $path;
40
41
	/** @var StorageFolder|null */
42
	protected $parentFolder;
43
44
	/**
45
	 * StorageNode constructor.
46
	 *
47
	 * @param OCNode      $node
48
	 * @param string|null $parentPath
49
	 *
50
	 * @throws InvalidPathException
51
	 */
52 29
	public function __construct(OCNode $node, string $parentPath = null)
53
	{
54 29
		parent::__construct();
55
56 29
		$this->node = $node;
57
58 29
		if ($parentPath !== null) {
59 29
			$parentPath = $this->normalizePath($parentPath);
60 29
			$nodePath = $this->normalizePath($node->getPath());
61
62 29
			$path = (($parentPath !== '/') ? $parentPath : '') . '/' . basename($nodePath);
63 29
			if (substr_compare($nodePath, $path, -strlen($path)) !== 0) {
64
				throw new InvalidPathException();
65
			}
66
67 29
			$this->path = $path;
68
		}
69 29
	}
70
71
	/**
72
	 * {@inheritDoc}
73
	 */
74
	public function rename(string $name): NodeInterface
75
	{
76
		return $this->move($this->getParentFolder(), $name);
77
	}
78
79
	/**
80
	 * {@inheritDoc}
81
	 */
82 7
	public function copy(FolderInterface $targetPath, string $name = null): NodeInterface
83
	{
84 7
		if ($targetPath instanceof StorageFolder) {
85
			if ($name !== null) {
86
				$this->assertValidFileName($name);
87
			}
88
89
			/** @var OCFolder $ocNode */
90
			$ocNode = $this->node->copy($targetPath->getOCNode()->getPath() . '/' . ($name ?? $this->getName()));
91
			return $this->repackNode($ocNode, $targetPath->getPath());
92
		} else {
93 7
			return parent::copy($targetPath, $name);
94
		}
95
	}
96
97
	/**
98
	 * {@inheritDoc}
99
	 */
100
	public function move(FolderInterface $targetPath, string $name = null): NodeInterface
101
	{
102
		if ($targetPath instanceof StorageFolder) {
103
			if ($name !== null) {
104
				$this->assertValidFileName($name);
105
			}
106
107
			/** @var OCFolder $ocNode */
108
			$ocNode = $this->node->move($targetPath->getOCNode()->getPath() . '/' . ($name ?? $this->getName()));
109
			return $this->repackNode($ocNode, $targetPath->getPath());
110
		} else {
111
			return parent::move($targetPath, $name);
112
		}
113
	}
114
115
	/**
116
	 * {@inheritDoc}
117
	 */
118
	public function delete(): void
119
	{
120
		$this->node->delete();
121
	}
122
123
	/**
124
	 * @return OCNode
125
	 */
126 29
	public function getOCNode(): OCNode
127
	{
128 29
		return $this->node;
129
	}
130
131
	/**
132
	 * {@inheritDoc}
133
	 */
134 29
	public function getPath(): string
135
	{
136 29
		return $this->path ?? ($this->isFolder() ? '/' : '/' . $this->getName());
137
	}
138
139
	/**
140
	 * {@inheritDoc}
141
	 */
142 5
	public function getLocalPath(): string
143
	{
144
		try {
145 5
			$storage = $this->node->getStorage();
146 5
			$internalPath = $this->node->getInternalPath();
147 5
			$localPath = $storage->getLocalFile($internalPath);
148
		} catch (\Exception $e) {
149
			$localPath = null;
150
		}
151
152 5
		if ($localPath && file_exists($localPath)) {
153 5
			if ($this->isFolder() ? is_dir($localPath) : is_file($localPath)) {
154 5
				return $localPath;
155
			}
156
157
			throw new InvalidPathException();
158
		}
159
160
		throw new NotFoundException();
161
	}
162
163
	/**
164
	 * {@inheritDoc}
165
	 */
166 18
	public function getName(): string
167
	{
168 18
		return $this->node->getName();
169
	}
170
171
	/**
172
	 * {@inheritDoc}
173
	 */
174
	public function getParentPath(): string
175
	{
176
		return $this->getParentFolder()->getPath();
177
	}
178
179
	/**
180
	 * {@inheritDoc}
181
	 */
182
	public function getParentFolder(): FolderInterface
183
	{
184
		if ($this->parentFolder === null) {
185
			if ($this->path === null) {
186
				throw new InvalidPathException();
187
			}
188
189
			try {
190
				$ocNode = $this->node->getParent();
191
			} catch (NotFoundException $e) {
192
				throw new InvalidPathException();
193
			}
194
195
			$grandParentPath = dirname($this->path);
196
			$grandParentPath = ($grandParentPath !== '/') ? dirname($grandParentPath) : null;
197
			$this->parentFolder = new StorageFolder($ocNode, $grandParentPath);
198
		}
199
200
		return $this->parentFolder;
201
	}
202
203
	/**
204
	 * {@inheritDoc}
205
	 */
206 8
	public function isFile(): bool
207
	{
208 8
		return ($this->node instanceof OCFile);
209
	}
210
211
	/**
212
	 * {@inheritDoc}
213
	 */
214 29
	public function isFolder(): bool
215
	{
216 29
		return ($this->node instanceof OCFolder);
217
	}
218
219
	/**
220
	 * {@inheritDoc}
221
	 */
222 12
	public function isLocal(): bool
223
	{
224
		try {
225 12
			return $this->getOCNode()->getStorage()->isLocal();
226
		} catch (\Exception $e) {
227
			return false;
228
		}
229
	}
230
231
	/**
232
	 * {@inheritDoc}
233
	 */
234 3
	public function getPermissions(): int
235
	{
236
		try {
237 3
			return $this->node->getPermissions();
238
		} catch (\Exception $e) {
239
			return 0;
240
		}
241
	}
242
243
	/**
244
	 * @param OCNode      $node
245
	 * @param string|null $parentPath
246
	 *
247
	 * @return AbstractStorageNode
248
	 * @throws InvalidPathException
249
	 */
250 29
	protected function repackNode(OCNode $node, string $parentPath = null): AbstractStorageNode
251
	{
252 29
		if ($node instanceof OCFile) {
253 15
			return new StorageFile($node, $parentPath);
254 29
		} elseif ($node instanceof OCFolder) {
255 29
			return new StorageFolder($node, $parentPath);
256
		} else {
257
			throw new \UnexpectedValueException();
258
		}
259
	}
260
}
261