1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Phossa Project |
4
|
|
|
* |
5
|
|
|
* PHP version 5.4 |
6
|
|
|
* |
7
|
|
|
* @category Library |
8
|
|
|
* @package Phossa2\Storage |
9
|
|
|
* @copyright Copyright (c) 2016 phossa.com |
10
|
|
|
* @license http://mit-license.org/ MIT License |
11
|
|
|
* @link http://www.phossa.com/ |
12
|
|
|
*/ |
13
|
|
|
/*# declare(strict_types=1); */ |
14
|
|
|
|
15
|
|
|
namespace Phossa2\Storage\Driver; |
16
|
|
|
|
17
|
|
|
use Phossa2\Shared\Base\ObjectAbstract; |
18
|
|
|
use Phossa2\Shared\Error\ErrorAwareTrait; |
19
|
|
|
use Phossa2\Shared\Error\ErrorAwareInterface; |
20
|
|
|
use Phossa2\Storage\Interfaces\DriverInterface; |
21
|
|
|
use Phossa2\Shared\Extension\ExtensionAwareTrait; |
22
|
|
|
use Phossa2\Shared\Extension\ExtensionAwareInterface; |
23
|
|
|
use Phossa2\Storage\Message\Message; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* DriverAbstract |
27
|
|
|
* |
28
|
|
|
* @package Phossa2\Storage |
29
|
|
|
* @author Hong Zhang <[email protected]> |
30
|
|
|
* @see ObjectAbstract |
31
|
|
|
* @see DriverInterface |
32
|
|
|
* @see ErrorAwareInterface |
33
|
|
|
* @see ExtensionAwareInterface |
34
|
|
|
* @version 2.0.0 |
35
|
|
|
* @since 2.0.0 added |
36
|
|
|
*/ |
37
|
|
|
abstract class DriverAbstract extends ObjectAbstract implements DriverInterface, ErrorAwareInterface, ExtensionAwareInterface |
38
|
|
|
{ |
39
|
|
|
use ErrorAwareTrait, ExtensionAwareTrait; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Store meta data in a seperate file |
43
|
|
|
* |
44
|
|
|
* @var bool |
45
|
|
|
* @access protected |
46
|
|
|
*/ |
47
|
|
|
protected $use_metafile = false; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* {@inheritDoc} |
51
|
|
|
*/ |
52
|
|
|
public function exists(/*# string */ $path)/*# : bool */ |
53
|
|
|
{ |
54
|
|
|
$real = $this->realPath($path); |
55
|
|
|
return $this->realExists($real); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* {@inheritDoc} |
60
|
|
|
*/ |
61
|
|
|
public function getContent(/*# string */ $path, /*# bool */ $stream = false) |
62
|
|
|
{ |
63
|
|
|
$real = $this->realPath($path); |
64
|
|
|
|
65
|
|
|
if ($this->isDir($real)) { |
66
|
|
|
return $this->readDir($real, rtrim($path, '/\\') . '/'); |
67
|
|
|
|
68
|
|
|
} elseif ($stream) { |
69
|
|
|
return $this->openReadStream($real); |
70
|
|
|
|
71
|
|
|
} else { |
72
|
|
|
return $this->readFile($real); |
73
|
|
|
} |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* {@inheritDoc} |
78
|
|
|
*/ |
79
|
|
|
public function getMeta(/*# string */ $path)/*# : array */ |
80
|
|
|
{ |
81
|
|
|
$real = $this->realPath($path); |
82
|
|
|
|
83
|
|
|
if ($this->isDir($real)) { |
84
|
|
|
return ['type' => 'dir']; |
85
|
|
|
|
86
|
|
|
} elseif ($this->use_metafile) { |
87
|
|
|
$meta = $this->readFile($real . '.meta'); |
88
|
|
|
return is_string($meta) ? unserialize($meta) : []; |
89
|
|
|
|
90
|
|
|
} else { |
91
|
|
|
return $this->getRealMeta($real); |
92
|
|
|
} |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* {@inheritDoc} |
97
|
|
|
*/ |
98
|
|
|
public function setContent(/*# string */ $path, $content)/*# : bool */ |
99
|
|
|
{ |
100
|
|
|
$real = $this->realPath($path); |
101
|
|
|
|
102
|
|
|
if ($this->fixPath($real)) { |
|
|
|
|
103
|
|
|
if (is_resource($content)) { |
104
|
|
|
$res = $this->writeStream($real, $content); |
105
|
|
|
} else { |
106
|
|
|
$res = $this->writeFile($real, $content); |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
return $res ?: $this->setError( |
110
|
|
|
Message::get(Message::STR_WRITEFILE_FAIL, $path), |
111
|
|
|
Message::STR_WRITEFILE_FAIL |
112
|
|
|
); |
113
|
|
|
} |
114
|
|
|
return false; |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* {@inheritDoc} |
119
|
|
|
*/ |
120
|
|
|
public function setMeta(/*# string */ $path, array $meta)/*# : bool */ |
121
|
|
|
{ |
122
|
|
|
$real = $this->realPath($path); |
123
|
|
|
|
124
|
|
|
if ($this->use_metafile) { |
125
|
|
|
$new = array_replace($this->getMeta($path), $meta); |
126
|
|
|
$res = $this->writeFile($real . '.meta', serialize($new)); |
127
|
|
|
} else { |
128
|
|
|
$res = $this->setRealMeta($real, $meta); |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
return $res ?: $this->setError( |
132
|
|
|
Message::get(Message::STR_SETMETA_FAIL, $real), |
133
|
|
|
Message::STR_SETMETA_FAIL |
134
|
|
|
); |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* {@inheritDoc} |
139
|
|
|
*/ |
140
|
|
View Code Duplication |
public function rename(/*# string */ $from, /*# string */ $to)/*# : bool */ |
|
|
|
|
141
|
|
|
{ |
142
|
|
|
$real_from = $this->realPath($from); |
143
|
|
|
$real_to = $this->realPath($to); |
144
|
|
|
|
145
|
|
|
if ($this->fixPath($real_from, $real_to)) { |
|
|
|
|
146
|
|
|
if ($this->isDir($real_from)) { |
147
|
|
|
$res = $this->renameDir($real_from, $real_to); |
148
|
|
|
} else { |
149
|
|
|
$res = $this->renameFile($real_from, $real_to); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
return $res ?: $this->setError( |
153
|
|
|
Message::get(Message::STR_RENAME_FAIL, $real_from, $real_to), |
154
|
|
|
Message::STR_RENAME_FAIL |
155
|
|
|
); |
156
|
|
|
} |
157
|
|
|
return false; |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* {@inheritDoc} |
162
|
|
|
*/ |
163
|
|
View Code Duplication |
public function copy(/*# string */ $from, /*# string */ $to)/*# : bool */ |
|
|
|
|
164
|
|
|
{ |
165
|
|
|
$real_from = $this->realPath($from); |
166
|
|
|
$real_to = $this->realPath($to); |
167
|
|
|
|
168
|
|
|
if ($this->fixPath($real_from, $real_to)) { |
|
|
|
|
169
|
|
|
if ($this->isDir($real_from)) { |
170
|
|
|
$res = $this->copyDir($real_from, $real_to); |
171
|
|
|
} else { |
172
|
|
|
$res = $this->copyFile($real_from, $real_to); |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
return $res ?: $this->setError( |
176
|
|
|
Message::get(Message::STR_COPY_FAIL, $real_from, $real_to), |
177
|
|
|
Message::STR_COPY_FAIL |
178
|
|
|
); |
179
|
|
|
} |
180
|
|
|
return false; |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* {@inheritDoc} |
185
|
|
|
*/ |
186
|
|
|
public function delete(/*# string */ $path)/*# : bool */ |
187
|
|
|
{ |
188
|
|
|
$real = $this->realPath($path); |
189
|
|
|
|
190
|
|
|
if ($this->isDir($real)) { |
191
|
|
|
return $this->deleteDir($real); |
192
|
|
|
} else { |
193
|
|
|
if ($this->use_metafile) { |
194
|
|
|
return $this->deleteFile($real . '.meta'); |
195
|
|
|
} |
196
|
|
|
return $this->deleteFile($real); |
197
|
|
|
} |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
/** |
201
|
|
|
* Returns driver specific real path |
202
|
|
|
* @param string $path |
203
|
|
|
* @return string |
204
|
|
|
* @access protected |
205
|
|
|
*/ |
206
|
|
|
abstract protected function realPath(/*# string */ $path)/*# : string */; |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* Exists of real path |
210
|
|
|
* |
211
|
|
|
* @param string $realPath |
212
|
|
|
* @return bool |
213
|
|
|
* @access protected |
214
|
|
|
*/ |
215
|
|
|
abstract protected function realExists(/*# string */ $realPath)/*# : bool */; |
216
|
|
|
|
217
|
|
|
/** |
218
|
|
|
* Is path a directory |
219
|
|
|
* |
220
|
|
|
* @param string $realPath |
221
|
|
|
* @return bool |
222
|
|
|
* @access protected |
223
|
|
|
*/ |
224
|
|
|
abstract protected function isDir(/*# string */ $realPath)/*# : bool */; |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* Read directory, returns an array of paths in this directory |
228
|
|
|
* |
229
|
|
|
* @param string $realPath |
230
|
|
|
* @param string $prefix prefix to prepend to the results |
231
|
|
|
* @return array |
232
|
|
|
* @access protected |
233
|
|
|
*/ |
234
|
|
|
abstract protected function readDir( |
235
|
|
|
/*# string */ $realPath, |
236
|
|
|
/*# string */ $prefix = '' |
237
|
|
|
)/*# : array */; |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* Open read stream |
241
|
|
|
* |
242
|
|
|
* @param string $realPath |
243
|
|
|
* @return resource|null |
244
|
|
|
* @access protected |
245
|
|
|
*/ |
246
|
|
|
abstract protected function openReadStream(/*# string */ $realPath); |
247
|
|
|
|
248
|
|
|
/** |
249
|
|
|
* Read file and returns all the content |
250
|
|
|
* |
251
|
|
|
* @param string $realPath |
252
|
|
|
* @return string|null |
253
|
|
|
* @access protected |
254
|
|
|
*/ |
255
|
|
|
abstract protected function readFile(/*# string */ $realPath); |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* Get the meta data |
259
|
|
|
* |
260
|
|
|
* @param string $realPath |
261
|
|
|
* @return array |
262
|
|
|
* @access protected |
263
|
|
|
*/ |
264
|
|
|
abstract protected function getRealMeta(/*# string */ $realPath)/*# : array */; |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* Make sure path directory exits. |
268
|
|
|
* |
269
|
|
|
* @return bool |
270
|
|
|
* @access protected |
271
|
|
|
*/ |
272
|
|
|
abstract protected function fixPath()/*# : bool */; |
273
|
|
|
|
274
|
|
|
/** |
275
|
|
|
* Write to file from stream |
276
|
|
|
* |
277
|
|
|
* @param string $realPath |
278
|
|
|
* @param resource $resource |
279
|
|
|
* @return bool |
280
|
|
|
* @access protected |
281
|
|
|
*/ |
282
|
|
|
abstract protected function writeStream( |
283
|
|
|
/*# string */ $realPath, |
284
|
|
|
$resource |
285
|
|
|
)/*# : bool */; |
286
|
|
|
|
287
|
|
|
/** |
288
|
|
|
* Write to file |
289
|
|
|
* |
290
|
|
|
* @param string $realPath |
291
|
|
|
* @param string $content |
292
|
|
|
* @return bool |
293
|
|
|
* @access protected |
294
|
|
|
*/ |
295
|
|
|
abstract protected function writeFile( |
296
|
|
|
/*# string */ $realPath, |
297
|
|
|
/*# string */ $content |
298
|
|
|
)/*# : bool */; |
299
|
|
|
|
300
|
|
|
/** |
301
|
|
|
* Write meta data |
302
|
|
|
* |
303
|
|
|
* @param string $realPath |
304
|
|
|
* @param array $meta |
305
|
|
|
* @return bool |
306
|
|
|
* @access protected |
307
|
|
|
*/ |
308
|
|
|
abstract protected function setRealMeta( |
309
|
|
|
/*# string */ $realPath, |
310
|
|
|
array $meta |
311
|
|
|
)/*# : bool */; |
312
|
|
|
|
313
|
|
|
/** |
314
|
|
|
* Rename directory |
315
|
|
|
* |
316
|
|
|
* @param string $from |
317
|
|
|
* @param string $to |
318
|
|
|
* @return bool |
319
|
|
|
* @access protected |
320
|
|
|
*/ |
321
|
|
|
abstract protected function renameDir( |
322
|
|
|
/*# string */ $from, |
323
|
|
|
/*# string */ $to |
324
|
|
|
)/*# : bool */; |
325
|
|
|
|
326
|
|
|
/** |
327
|
|
|
* Rename file |
328
|
|
|
* |
329
|
|
|
* @param string $from |
330
|
|
|
* @param string $to |
331
|
|
|
* @return bool |
332
|
|
|
* @access protected |
333
|
|
|
*/ |
334
|
|
|
abstract protected function renameFile( |
335
|
|
|
/*# string */ $from, |
336
|
|
|
/*# string */ $to |
337
|
|
|
)/*# : bool */; |
338
|
|
|
|
339
|
|
|
/** |
340
|
|
|
* Copy directory |
341
|
|
|
* |
342
|
|
|
* @param string $from |
343
|
|
|
* @param string $to |
344
|
|
|
* @return bool |
345
|
|
|
* @access protected |
346
|
|
|
*/ |
347
|
|
|
abstract protected function copyDir( |
348
|
|
|
/*# string */ $from, |
349
|
|
|
/*# string */ $to |
350
|
|
|
)/*# : bool */; |
351
|
|
|
|
352
|
|
|
/** |
353
|
|
|
* Copy file |
354
|
|
|
* |
355
|
|
|
* @param string $from |
356
|
|
|
* @param string $to |
357
|
|
|
* @return bool |
358
|
|
|
* @access protected |
359
|
|
|
*/ |
360
|
|
|
abstract protected function copyFile( |
361
|
|
|
/*# string */ $from, |
362
|
|
|
/*# string */ $to |
363
|
|
|
)/*# : bool */; |
364
|
|
|
|
365
|
|
|
/** |
366
|
|
|
* Delete directory |
367
|
|
|
* |
368
|
|
|
* @param string $realPath |
369
|
|
|
* @return bool |
370
|
|
|
* @access protected |
371
|
|
|
*/ |
372
|
|
|
abstract protected function deleteDir(/*# string */ $realPath)/*# : bool */; |
373
|
|
|
|
374
|
|
|
/** |
375
|
|
|
* Delete the file |
376
|
|
|
* |
377
|
|
|
* @param string $realPath |
378
|
|
|
* @return bool |
379
|
|
|
* @access protected |
380
|
|
|
*/ |
381
|
|
|
abstract protected function deleteFile(/*# string */ $realPath)/*# : bool */; |
382
|
|
|
} |
383
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more 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.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.