1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* @package Cadmium\System\Modules\Filemanager |
5
|
|
|
* @author Anton Romanov |
6
|
|
|
* @copyright Copyright (c) 2015-2017, Anton Romanov |
7
|
|
|
* @link http://cadmium-cms.com |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
namespace Modules\Filemanager\Utils { |
11
|
|
|
|
12
|
|
|
use Explorer; |
13
|
|
|
|
14
|
|
|
class Entity { |
15
|
|
|
|
16
|
|
|
private $parent = null, $name = '', $path = '', $path_full = '', $type = ''; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Get entity prototype data |
20
|
|
|
* |
21
|
|
|
* @return array|false : the data array or false if the name is invalid |
22
|
|
|
*/ |
23
|
|
|
|
24
|
|
|
private function getPrototype(string $name) { |
25
|
|
|
|
26
|
|
|
if (('' === $name) || preg_match('/[\/\\\\]/', $name)) return false; |
27
|
|
|
|
28
|
|
|
if ($this->parent->isIgnoreHidden() && preg_match('/^\./', $name)) return false; |
29
|
|
|
|
30
|
|
|
$path = (($this->parent->getPath() ? ($this->parent->getPath() . '/') : '') . $name); |
31
|
|
|
|
32
|
|
|
$path_full = ($this->parent->getPathFull() . $name); |
33
|
|
|
|
34
|
|
|
# ------------------------ |
35
|
|
|
|
36
|
|
|
return ['name' => $name, 'path' => $path, 'path_full' => $path_full]; |
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* Constructor |
41
|
|
|
*/ |
42
|
|
|
|
43
|
|
|
public function __construct(Container $parent, string $name = '') { |
44
|
|
|
|
45
|
|
|
$this->parent = $parent; $this->init($name); |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* Initialize the entity by a directory/file name |
50
|
|
|
* |
51
|
|
|
* @return bool : true on success or false if a corresponding directory/file does not exist |
52
|
|
|
*/ |
53
|
|
|
|
54
|
|
|
public function init(string $name) : bool { |
55
|
|
|
|
56
|
|
|
if (false === ($prototype = $this->getPrototype($name))) return false; |
57
|
|
|
|
58
|
|
|
# Check type |
59
|
|
|
|
60
|
|
|
$type = Explorer::getType($prototype['path_full']); |
61
|
|
|
|
62
|
|
|
if (!in_array($type, ['dir', 'file'], true)) return false; |
63
|
|
|
|
64
|
|
|
# Set data |
65
|
|
|
|
66
|
|
|
foreach ($prototype as $var => $value) $this->$var = $value; |
67
|
|
|
|
68
|
|
|
$this->type = $type; |
|
|
|
|
69
|
|
|
|
70
|
|
|
# ------------------------ |
71
|
|
|
|
72
|
|
|
return true; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Check whether another entity with a given name exists in the same parent directory. |
77
|
|
|
* This method is useful to find out is it possible to create or rename the entity |
78
|
|
|
* |
79
|
|
|
* @return bool : true if the check has been successful and no other items with the given name found, otherwise false |
80
|
|
|
*/ |
81
|
|
|
|
82
|
|
|
public function check(string $name) : bool { |
83
|
|
|
|
84
|
|
|
if (false === ($prototype = $this->getPrototype($name))) return false; |
85
|
|
|
|
86
|
|
|
if (($name !== $this->name) && Explorer::exists($prototype['path_full'])) return false; |
87
|
|
|
|
88
|
|
|
# ------------------------ |
89
|
|
|
|
90
|
|
|
return true; |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Create the entity |
95
|
|
|
* |
96
|
|
|
* @return bool : true on success or false on failure |
97
|
|
|
*/ |
98
|
|
|
|
99
|
|
|
public function create(string $name, string $type) : bool { |
100
|
|
|
|
101
|
|
|
if (('' !== $this->name) || (false === ($prototype = $this->getPrototype($name)))) return false; |
102
|
|
|
|
103
|
|
|
if (!in_array($type, ['dir', 'file'], true)) return false; |
104
|
|
|
|
105
|
|
|
# Create entity |
106
|
|
|
|
107
|
|
|
$create = (($type === 'dir') ? 'createDir' : 'createFile'); |
108
|
|
|
|
109
|
|
|
if (!Explorer::$create($prototype['path_full'])) return false; |
110
|
|
|
|
111
|
|
|
# Set data |
112
|
|
|
|
113
|
|
|
foreach ($prototype as $var => $value) $this->$var = $value; |
114
|
|
|
|
115
|
|
|
$this->type = $type; |
116
|
|
|
|
117
|
|
|
# ------------------------ |
118
|
|
|
|
119
|
|
|
return true; |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* Rename the entity |
124
|
|
|
* |
125
|
|
|
* @return bool : true on success or false on failure |
126
|
|
|
*/ |
127
|
|
|
|
128
|
|
|
public function rename(string $name) : bool { |
129
|
|
|
|
130
|
|
|
if (('' === $this->name) || (false === ($prototype = $this->getPrototype($name)))) return false; |
131
|
|
|
|
132
|
|
|
# Rename entity |
133
|
|
|
|
134
|
|
|
if (!Explorer::rename($this->path_full, $prototype['path_full'])) return false; |
135
|
|
|
|
136
|
|
|
# Set data |
137
|
|
|
|
138
|
|
|
foreach ($prototype as $var => $value) $this->$var = $value; |
139
|
|
|
|
140
|
|
|
# ------------------------ |
141
|
|
|
|
142
|
|
|
return true; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* Remove the entity |
147
|
|
|
* |
148
|
|
|
* @return bool : true on success or false on failure |
149
|
|
|
*/ |
150
|
|
|
|
151
|
|
|
public function remove() : bool { |
152
|
|
|
|
153
|
|
|
if ('' === $this->name) return false; |
154
|
|
|
|
155
|
|
|
# Remove entity |
156
|
|
|
|
157
|
|
|
$remove = (($this->type === 'dir') ? 'removeDir' : 'removeFile'); |
158
|
|
|
|
159
|
|
|
if (!Explorer::$remove($this->path_full, true)) return false; |
160
|
|
|
|
161
|
|
|
# Reset data |
162
|
|
|
|
163
|
|
|
$this->name = ''; $this->path = ''; $this->path_full = ''; $this->type = ''; |
164
|
|
|
|
165
|
|
|
# ------------------------ |
166
|
|
|
|
167
|
|
|
return true; |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* Get the entity extension in lower case |
172
|
|
|
* |
173
|
|
|
* @return string|false : the extension or false on failure |
174
|
|
|
*/ |
175
|
|
|
|
176
|
|
|
public function getExtension() { |
177
|
|
|
|
178
|
|
|
if ('' === $this->name) return false; |
179
|
|
|
|
180
|
|
|
return strtolower(Explorer::getExtension($this->name, false)); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* Get the entity creation time |
185
|
|
|
* |
186
|
|
|
* @return int|false : the time or false on failure |
187
|
|
|
*/ |
188
|
|
|
|
189
|
|
|
public function getCreated() { |
190
|
|
|
|
191
|
|
|
if ('' === $this->name) return false; |
192
|
|
|
|
193
|
|
|
return Explorer::getCreated($this->path_full); |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* Get the entity access time |
198
|
|
|
* |
199
|
|
|
* @return int|false : the time or false on failure |
200
|
|
|
*/ |
201
|
|
|
|
202
|
|
|
public function getAccessed() { |
203
|
|
|
|
204
|
|
|
if ('' === $this->name) return false; |
205
|
|
|
|
206
|
|
|
return Explorer::getAccessed($this->path_full); |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* Get the entity modification time |
211
|
|
|
* |
212
|
|
|
* @return int|false : the time or false on failure |
213
|
|
|
*/ |
214
|
|
|
|
215
|
|
|
public function getModified() { |
216
|
|
|
|
217
|
|
|
if ('' === $this->name) return false; |
218
|
|
|
|
219
|
|
|
return Explorer::getModified($this->path_full); |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* Get the entity permissions |
224
|
|
|
* |
225
|
|
|
* @return int|false : the permissions or false on failure |
226
|
|
|
*/ |
227
|
|
|
|
228
|
|
|
public function getPermissions() { |
229
|
|
|
|
230
|
|
|
if ('' === $this->name) return false; |
231
|
|
|
|
232
|
|
|
return Explorer::getPermissions($this->path_full); |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
/** |
236
|
|
|
* Get the entity size |
237
|
|
|
* |
238
|
|
|
* @return int|false : the size or false on failure |
239
|
|
|
*/ |
240
|
|
|
|
241
|
|
|
public function getSize() { |
242
|
|
|
|
243
|
|
|
if ('' === $this->name) return false; |
244
|
|
|
|
245
|
|
|
return Explorer::getSize($this->path_full); |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
/** |
249
|
|
|
* Get the file contents |
250
|
|
|
* |
251
|
|
|
* @return string|false : the read data or false on failure |
252
|
|
|
*/ |
253
|
|
|
|
254
|
|
|
public function getContents() { |
255
|
|
|
|
256
|
|
|
if ('' === $this->name) return false; |
257
|
|
|
|
258
|
|
|
return Explorer::getContents($this->path_full); |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* Save data into the file |
263
|
|
|
* |
264
|
|
|
* @return int|false : the number of bytes that were written to the file or false on failure |
265
|
|
|
*/ |
266
|
|
|
|
267
|
|
|
public function putContents(string $contents) { |
268
|
|
|
|
269
|
|
|
if ('' === $this->name) return false; |
270
|
|
|
|
271
|
|
|
return Explorer::putContents($this->path_full, $contents); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
/** |
275
|
|
|
* Check if the entity has been successfully initialized |
276
|
|
|
*/ |
277
|
|
|
|
278
|
|
|
public function isInited() : bool { |
279
|
|
|
|
280
|
|
|
return ('' !== $this->name); |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
/** |
284
|
|
|
* Check if the entity is a directory |
285
|
|
|
*/ |
286
|
|
|
|
287
|
|
|
public function isDir() : bool { |
288
|
|
|
|
289
|
|
|
return ($this->type === 'dir'); |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
/** |
293
|
|
|
* Check if the entity is a file |
294
|
|
|
*/ |
295
|
|
|
|
296
|
|
|
public function isFile() : bool { |
297
|
|
|
|
298
|
|
|
return ($this->type === 'file'); |
299
|
|
|
} |
300
|
|
|
|
301
|
|
|
/** |
302
|
|
|
* Get the entity parent |
303
|
|
|
*/ |
304
|
|
|
|
305
|
|
|
public function getParent() : Container { |
306
|
|
|
|
307
|
|
|
return $this->parent; |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
/** |
311
|
|
|
* Get the entity name |
312
|
|
|
*/ |
313
|
|
|
|
314
|
|
|
public function getName() : string { |
315
|
|
|
|
316
|
|
|
return $this->name; |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
/** |
320
|
|
|
* Get the entity relative path |
321
|
|
|
*/ |
322
|
|
|
|
323
|
|
|
public function getPath() : string { |
324
|
|
|
|
325
|
|
|
return $this->path; |
326
|
|
|
} |
327
|
|
|
|
328
|
|
|
/** |
329
|
|
|
* Get the entity full path |
330
|
|
|
*/ |
331
|
|
|
|
332
|
|
|
public function getPathFull() : string { |
333
|
|
|
|
334
|
|
|
return $this->path_full; |
335
|
|
|
} |
336
|
|
|
|
337
|
|
|
/** |
338
|
|
|
* Get the entity type |
339
|
|
|
*/ |
340
|
|
|
|
341
|
|
|
public function getType() : string { |
342
|
|
|
|
343
|
|
|
return $this->type; |
344
|
|
|
} |
345
|
|
|
} |
346
|
|
|
} |
347
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.