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; |
16
|
|
|
|
17
|
|
|
use Phossa2\Storage\Message\Message; |
18
|
|
|
use Phossa2\Shared\Base\ObjectAbstract; |
19
|
|
|
use Phossa2\Shared\Error\ErrorAwareTrait; |
20
|
|
|
use Phossa2\Shared\Error\ErrorAwareInterface; |
21
|
|
|
use Phossa2\Storage\Interfaces\PathInterface; |
22
|
|
|
use Phossa2\Storage\Interfaces\DriverInterface; |
23
|
|
|
use Phossa2\Storage\Traits\FilesystemAwareTrait; |
24
|
|
|
use Phossa2\Shared\Extension\ExtensionAwareTrait; |
25
|
|
|
use Phossa2\Storage\Interfaces\FilesystemInterface; |
26
|
|
|
use Phossa2\Shared\Extension\ExtensionAwareInterface; |
27
|
|
|
use Phossa2\Storage\Interfaces\FilesystemAwareInterface; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Path |
31
|
|
|
* |
32
|
|
|
* @package Phossa2\Storage |
33
|
|
|
* @author Hong Zhang <[email protected]> |
34
|
|
|
* @see ObjectAbstract |
35
|
|
|
* @see PathInterface |
36
|
|
|
* @see ErrorAwareInterface |
37
|
|
|
* @see FilesystemAwareInterface |
38
|
|
|
* @see ExtensionAwareInterface |
39
|
|
|
* @version 2.0.0 |
40
|
|
|
* @since 2.0.0 added |
41
|
|
|
*/ |
42
|
|
|
class Path extends ObjectAbstract implements PathInterface, ErrorAwareInterface, FilesystemAwareInterface, ExtensionAwareInterface |
43
|
|
|
{ |
44
|
|
|
use FilesystemAwareTrait, ErrorAwareTrait, ExtensionAwareTrait; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Full path with mount point |
48
|
|
|
* |
49
|
|
|
* @var string |
50
|
|
|
* @access protected |
51
|
|
|
*/ |
52
|
|
|
protected $full; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* relative path without mount point prefix |
56
|
|
|
* |
57
|
|
|
* @var string |
58
|
|
|
* @access protected |
59
|
|
|
*/ |
60
|
|
|
protected $path; |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Instantiate the path object |
64
|
|
|
* |
65
|
|
|
* @param string $full full path |
66
|
|
|
* @param string $path relative path without mount point |
67
|
|
|
* @param FilesystemInterface $filesystem |
68
|
|
|
* @access public |
69
|
|
|
* @api |
70
|
|
|
*/ |
71
|
|
|
public function __construct( |
72
|
|
|
/*# string */ $full, |
73
|
|
|
/*# string */ $path, |
74
|
|
|
FilesystemInterface $filesystem |
75
|
|
|
) { |
76
|
|
|
$this->setFilesystem($filesystem); |
77
|
|
|
$this->full = $full; |
78
|
|
|
$this->path = $path; |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* {@inheritDoc} |
83
|
|
|
*/ |
84
|
|
|
public function exists()/*# : bool */ |
85
|
|
|
{ |
86
|
|
|
if (!$this->getDriver()->exists($this->path)) { |
87
|
|
|
return $this->setError( |
88
|
|
|
Message::get(Message::MSG_PATH_NOTFOUND, $this->full), |
89
|
|
|
Message::MSG_PATH_NOTFOUND |
90
|
|
|
); |
91
|
|
|
} |
92
|
|
|
return true; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* {@inheritDoc} |
97
|
|
|
*/ |
98
|
|
View Code Duplication |
public function getContent(/*# bool */ $stream = false) |
|
|
|
|
99
|
|
|
{ |
100
|
|
|
if ($this->exists() && $this->isFilesystemReadable($this->full)) { |
101
|
|
|
$res = $this->getDriver()->getContent($this->path, $stream); |
102
|
|
|
$this->resetError(); |
103
|
|
|
return $res; |
104
|
|
|
} |
105
|
|
|
return null; |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* {@inheritDoc} |
110
|
|
|
*/ |
111
|
|
|
public function getMeta()/*# : array */ |
112
|
|
|
{ |
113
|
|
|
if (!$this->exists()) { |
114
|
|
|
return []; |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
$res = $this->getDriver()->getMeta($this->path); |
118
|
|
|
$this->resetError(); |
119
|
|
|
return $res; |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* {@inheritDoc} |
124
|
|
|
*/ |
125
|
|
|
public function getPath()/*# : string */ |
126
|
|
|
{ |
127
|
|
|
return $this->path; |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* {@inheritDoc} |
132
|
|
|
*/ |
133
|
|
|
public function getFullPath()/*# : string */ |
134
|
|
|
{ |
135
|
|
|
return $this->full; |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* {@inheritDoc} |
140
|
|
|
*/ |
141
|
|
|
public function setContent($content)/*# : bool */ |
142
|
|
|
{ |
143
|
|
|
if ($this->isFilesystemWritable($this->full) && |
144
|
|
|
!$this->hasTrailingSlash($this->path) |
145
|
|
|
) { |
146
|
|
|
$res = $this->getDriver()->setContent($this->path, $content); |
147
|
|
|
$this->resetError(); |
148
|
|
|
return $res; |
149
|
|
|
} |
150
|
|
|
return false; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* {@inheritDoc} |
155
|
|
|
*/ |
156
|
|
|
public function setMeta(array $meta)/*# : bool */ |
157
|
|
|
{ |
158
|
|
|
if (!$this->exists()) { |
159
|
|
|
return false; |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
if (!empty($meta)) { |
163
|
|
|
$res = $this->getDriver()->setMeta($this->path, $meta); |
164
|
|
|
$this->resetError(); |
165
|
|
|
return $res; |
166
|
|
|
} |
167
|
|
|
return true; |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* {@inheritDoc} |
172
|
|
|
*/ |
173
|
|
|
public function isDir(/*# string */ $path = '')/*# : bool */ |
174
|
|
|
{ |
175
|
|
|
$p = $path ?: $this->path; |
176
|
|
|
if ($this->hasTrailingSlash($p) || $this->getDriver()->isDir($p)) { |
177
|
|
|
return true; |
178
|
|
|
} |
179
|
|
|
return false; |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
/** |
183
|
|
|
* {@inheritDoc} |
184
|
|
|
*/ |
185
|
|
|
public function rename(/*# string */ $destination)/*# : bool */ |
186
|
|
|
{ |
187
|
|
|
return $this->alterAction($destination, 'rename'); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* {@inheritDoc} |
192
|
|
|
*/ |
193
|
|
|
public function copy(/*# string */ $destination)/*# : bool */ |
194
|
|
|
{ |
195
|
|
|
return $this->alterAction($destination, 'copy'); |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
/** |
199
|
|
|
* {@inheritDoc} |
200
|
|
|
*/ |
201
|
|
View Code Duplication |
public function delete()/*# : bool */ |
|
|
|
|
202
|
|
|
{ |
203
|
|
|
if ($this->exists()) { |
204
|
|
|
if (!$this->isFilesystemDeletable($this->full)) { |
205
|
|
|
return false; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
$res = $this->getDriver()->delete($this->path); |
209
|
|
|
$this->resetError(); |
210
|
|
|
return $res; |
211
|
|
|
} |
212
|
|
|
return true; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* Get the driver |
217
|
|
|
* |
218
|
|
|
* @return DriverInterface |
219
|
|
|
* @access protected |
220
|
|
|
*/ |
221
|
|
|
protected function getDriver()/*# : DriverInterface */ |
222
|
|
|
{ |
223
|
|
|
return $this->getFilesystem()->getDriver(); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* Do copy or rename in same filesystem |
228
|
|
|
* |
229
|
|
|
* @param string $destination |
230
|
|
|
* @param string $action 'copy' or 'rename' |
231
|
|
|
* @return bool |
232
|
|
|
* @access protected |
233
|
|
|
*/ |
234
|
|
|
protected function alterAction( |
235
|
|
|
/*# string */ $destination, |
236
|
|
|
/*# string */ $action |
237
|
|
|
)/*# : bool */ { |
238
|
|
|
if (!$this->exists() || !$this->isFilesystemWritable($this->full)) { |
239
|
|
|
return false; |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
if ($this->isDir($destination)) { |
243
|
|
|
$destination = rtrim($destination, '/') . '/' . basename($this->path); |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
$res = $this->getDriver()->{$action}($this->path, $destination); |
247
|
|
|
$this->resetError(); |
248
|
|
|
return (bool) $res; |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
/** |
252
|
|
|
* Is current path has trailing '/' |
253
|
|
|
* |
254
|
|
|
* @param string $path |
255
|
|
|
* @return bool |
256
|
|
|
* @access protected |
257
|
|
|
*/ |
258
|
|
|
protected function hasTrailingSlash(/*# string */ $path)/*# : bool */ |
259
|
|
|
{ |
260
|
|
|
if ($path && '/' == $path[strlen($path)-1]) { |
261
|
|
|
return true; |
262
|
|
|
} else { |
263
|
|
|
return false; |
264
|
|
|
} |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
/** |
268
|
|
|
* Reset error to driver's error |
269
|
|
|
* |
270
|
|
|
* @access protected |
271
|
|
|
*/ |
272
|
|
|
protected function resetError() |
273
|
|
|
{ |
274
|
|
|
$this->copyError($this->getFilesystem()->getDriver()); |
275
|
|
|
} |
276
|
|
|
} |
277
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.