Passed
Push — master ( 0f08ac...de3478 )
by Roeland
18:05 queued 13s
created

NewSimpleFile::getMTime()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 5
rs 10
1
<?php declare(strict_types=1);
2
/**
3
 * @copyright Copyright (c) 2020 Robin Appelman <[email protected]>
4
 *
5
 * @license GNU AGPL version 3 or any later version
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Affero General Public License as
9
 * published by the Free Software Foundation, either version 3 of the
10
 * License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 */
21
22
namespace OC\Files\SimpleFS;
23
24
use Icewind\Streams\CallbackWrapper;
25
use OCP\Files\File;
26
use OCP\Files\Folder;
27
use OCP\Files\NotFoundException;
28
use OCP\Files\NotPermittedException;
29
use OCP\Files\SimpleFS\ISimpleFile;
30
31
class NewSimpleFile implements ISimpleFile {
32
	private $parentFolder;
33
	private $name;
34
	/** @var File|null */
35
	private $file = null;
36
37
	/**
38
	 * File constructor.
39
	 *
40
	 * @param File $file
41
	 */
42
	public function __construct(Folder $parentFolder, string $name) {
43
		$this->parentFolder = $parentFolder;
44
		$this->name = $name;
45
	}
46
47
	/**
48
	 * Get the name
49
	 *
50
	 * @return string
51
	 */
52
	public function getName() {
53
		return $this->name;
54
	}
55
56
	/**
57
	 * Get the size in bytes
58
	 *
59
	 * @return int
60
	 */
61
	public function getSize() {
62
		if ($this->file) {
63
			return $this->file->getSize();
64
		} else {
65
			return 0;
66
		}
67
	}
68
69
	/**
70
	 * Get the ETag
71
	 *
72
	 * @return string
73
	 */
74
	public function getETag() {
75
		if ($this->file) {
76
			return $this->file->getEtag();
77
		} else {
78
			return '';
79
		}
80
	}
81
82
	/**
83
	 * Get the last modification time
84
	 *
85
	 * @return int
86
	 */
87
	public function getMTime() {
88
		if ($this->file) {
89
			return $this->file->getMTime();
90
		} else {
91
			return time();
92
		}
93
	}
94
95
	/**
96
	 * Get the content
97
	 *
98
	 * @return string
99
	 * @throws NotFoundException
100
	 * @throws NotPermittedException
101
	 */
102
	public function getContent() {
103
		if ($this->file) {
104
			$result = $this->file->getContent();
105
106
			if ($result === false) {
0 ignored issues
show
introduced by
The condition $result === false is always false.
Loading history...
107
				$this->checkFile();
108
			}
109
110
			return $result;
111
		} else {
112
			return '';
113
		}
114
	}
115
116
	/**
117
	 * Overwrite the file
118
	 *
119
	 * @param string|resource $data
120
	 * @throws NotPermittedException
121
	 * @throws NotFoundException
122
	 */
123
	public function putContent($data) {
124
		try {
125
			if ($this->file) {
126
				$this->file->putContent($data);
127
			} else {
128
				$this->file = $this->parentFolder->newFile($this->name, $data);
129
			}
130
		} catch (NotFoundException $e) {
131
			$this->checkFile();
132
		}
133
	}
134
135
	/**
136
	 * Sometimes there are some issues with the AppData. Most of them are from
137
	 * user error. But we should handle them gracefull anyway.
138
	 *
139
	 * If for some reason the current file can't be found. We remove it.
140
	 * Then traverse up and check all folders if they exists. This so that the
141
	 * next request will have a valid appdata structure again.
142
	 *
143
	 * @throws NotFoundException
144
	 */
145
	private function checkFile() {
146
		$cur = $this->file;
147
148
		while ($cur->stat() === false) {
0 ignored issues
show
Bug introduced by
The method stat() does not exist on null. ( Ignorable by Annotation )

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

148
		while ($cur->/** @scrutinizer ignore-call */ stat() === false) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
149
			$parent = $cur->getParent();
150
			try {
151
				$cur->delete();
152
			} catch (NotFoundException $e) {
153
				// Just continue then
154
			}
155
			$cur = $parent;
156
		}
157
158
		if ($cur !== $this->file) {
159
			throw new NotFoundException('File does not exist');
160
		}
161
	}
162
163
164
	/**
165
	 * Delete the file
166
	 *
167
	 * @throws NotPermittedException
168
	 */
169
	public function delete() {
170
		if ($this->file) {
171
			$this->file->delete();
172
		}
173
	}
174
175
	/**
176
	 * Get the MimeType
177
	 *
178
	 * @return string
179
	 */
180
	public function getMimeType() {
181
		if ($this->file) {
182
			return $this->file->getMimeType();
183
		} else {
184
			return 'text/plain';
185
		}
186
	}
187
188
	/**
189
	 * Open the file as stream for reading, resulting resource can be operated as stream like the result from php's own fopen
190
	 *
191
	 * @return resource
192
	 * @throws \OCP\Files\NotPermittedException
193
	 * @since 14.0.0
194
	 */
195
	public function read() {
196
		if ($this->file) {
197
			return $this->file->fopen('r');
198
		} else {
199
			return fopen('php://temp', 'r');
0 ignored issues
show
Bug Best Practice introduced by
The expression return fopen('php://temp', 'r') could also return false which is incompatible with the documented return type resource. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
200
		}
201
	}
202
203
	/**
204
	 * Open the file as stream for writing, resulting resource can be operated as stream like the result from php's own fopen
205
	 *
206
	 * @return resource
207
	 * @throws \OCP\Files\NotPermittedException
208
	 * @since 14.0.0
209
	 */
210
	public function write() {
211
		if ($this->file) {
212
			return $this->file->fopen('w');
213
		} else {
214
			$source = fopen('php://temp', 'w+');
215
			return CallbackWrapper::wrap($source, null, null, null, null, function () use ($source) {
216
				rewind($source);
217
				$this->putContent($source);
218
			});
219
		}
220
	}
221
}
222