|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace JellyBool\Flysystem\Upyun; |
|
4
|
|
|
|
|
5
|
|
|
use Upyun\Upyun; |
|
6
|
|
|
use League\Flysystem\Config; |
|
7
|
|
|
use League\Flysystem\Adapter\AbstractAdapter; |
|
8
|
|
|
|
|
9
|
|
|
/** |
|
10
|
|
|
* Class UpyunAdapter |
|
11
|
|
|
* @package JellyBool\Flysystem\Upyun |
|
12
|
|
|
*/ |
|
13
|
|
|
class UpyunAdapter extends AbstractAdapter |
|
14
|
|
|
{ |
|
15
|
|
|
/** |
|
16
|
|
|
* @var |
|
17
|
|
|
*/ |
|
18
|
|
|
protected $bucket; |
|
19
|
|
|
/** |
|
20
|
|
|
* @var |
|
21
|
|
|
*/ |
|
22
|
|
|
protected $operator; |
|
23
|
|
|
/** |
|
24
|
|
|
* @var |
|
25
|
|
|
*/ |
|
26
|
|
|
protected $password; |
|
27
|
|
|
|
|
28
|
|
|
/** |
|
29
|
|
|
* @var |
|
30
|
|
|
*/ |
|
31
|
|
|
protected $domain; |
|
32
|
|
|
|
|
33
|
|
|
/** |
|
34
|
|
|
* @var |
|
35
|
|
|
*/ |
|
36
|
|
|
protected $protocol; |
|
37
|
|
|
/** |
|
38
|
|
|
* UpyunAdapter constructor. |
|
39
|
|
|
* @param $bucket |
|
40
|
|
|
* @param $operator |
|
41
|
|
|
* @param $password |
|
42
|
|
|
* @param mixed $domain |
|
43
|
|
|
* @param mixed $protocol |
|
44
|
|
|
*/ |
|
45
|
|
|
public function __construct($bucket, $operator, $password, $domain, $protocol = 'http') |
|
46
|
|
|
{ |
|
47
|
|
|
$this->bucket = $bucket; |
|
48
|
|
|
$this->operator = $operator; |
|
49
|
|
|
$this->password = $password; |
|
50
|
|
|
$this->domain = $domain; |
|
51
|
|
|
$this->protocol = $protocol; |
|
52
|
|
|
} |
|
53
|
|
|
|
|
54
|
|
|
/** |
|
55
|
|
|
* @param string $path |
|
56
|
|
|
* @param string $contents |
|
57
|
|
|
* @param Config $config |
|
58
|
|
|
*/ |
|
59
|
|
|
public function write($path, $contents, Config $config) |
|
60
|
|
|
{ |
|
61
|
|
|
return $this->client()->write($path, $contents); |
|
|
|
|
|
|
62
|
|
|
} |
|
63
|
|
|
|
|
64
|
|
|
/** |
|
65
|
|
|
* @param string $path |
|
66
|
|
|
* @param resource $resource |
|
67
|
|
|
* @param Config $config |
|
68
|
|
|
*/ |
|
69
|
|
|
public function writeStream($path, $resource, Config $config) |
|
70
|
|
|
{ |
|
71
|
|
|
return $this->client()->write($path, $resource); |
|
|
|
|
|
|
72
|
|
|
} |
|
73
|
|
|
|
|
74
|
|
|
/** |
|
75
|
|
|
* @param string $path |
|
76
|
|
|
* @param string $contents |
|
77
|
|
|
* @param Config $config |
|
78
|
|
|
*/ |
|
79
|
|
|
public function update($path, $contents, Config $config) |
|
80
|
|
|
{ |
|
81
|
|
|
return $this->write($path, $contents, $config); |
|
|
|
|
|
|
82
|
|
|
} |
|
83
|
|
|
|
|
84
|
|
|
/** |
|
85
|
|
|
* @param string $path |
|
86
|
|
|
* @param resource $resource |
|
87
|
|
|
* @param Config $config |
|
88
|
|
|
*/ |
|
89
|
|
|
public function updateStream($path, $resource, Config $config) |
|
90
|
|
|
{ |
|
91
|
|
|
return $this->writeStream($path, $resource, $config); |
|
|
|
|
|
|
92
|
|
|
} |
|
93
|
|
|
|
|
94
|
|
|
/** |
|
95
|
|
|
* @param string $path |
|
96
|
|
|
* @param string $newpath |
|
97
|
|
|
*/ |
|
98
|
|
|
public function rename($path, $newpath) |
|
99
|
|
|
{ |
|
100
|
|
|
$this->copy($path,$newpath); |
|
101
|
|
|
return $this->delete($path); |
|
102
|
|
|
} |
|
103
|
|
|
|
|
104
|
|
|
/** |
|
105
|
|
|
* @param string $path |
|
106
|
|
|
* @param string $newpath |
|
107
|
|
|
*/ |
|
108
|
|
|
public function copy($path, $newpath) |
|
109
|
|
|
{ |
|
110
|
|
|
$this->writeStream($newpath, fopen($this->getUrl($path), 'r'), new Config()); |
|
111
|
|
|
return true; |
|
112
|
|
|
} |
|
113
|
|
|
|
|
114
|
|
|
/** |
|
115
|
|
|
* @param string $path |
|
116
|
|
|
*/ |
|
117
|
|
|
public function delete($path) |
|
118
|
|
|
{ |
|
119
|
|
|
return $this->client()->delete($path); |
|
120
|
|
|
} |
|
121
|
|
|
|
|
122
|
|
|
/** |
|
123
|
|
|
* @param string $dirname |
|
124
|
|
|
*/ |
|
125
|
|
|
public function deleteDir($dirname) |
|
126
|
|
|
{ |
|
127
|
|
|
return $this->client()->deleteDir($dirname); |
|
128
|
|
|
} |
|
129
|
|
|
|
|
130
|
|
|
/** |
|
131
|
|
|
* @param string $dirname |
|
132
|
|
|
* @param Config $config |
|
133
|
|
|
*/ |
|
134
|
|
|
public function createDir($dirname, Config $config) |
|
135
|
|
|
{ |
|
136
|
|
|
return $this->client()->createDir($dirname); |
|
|
|
|
|
|
137
|
|
|
} |
|
138
|
|
|
|
|
139
|
|
|
/** |
|
140
|
|
|
* @param string $path |
|
141
|
|
|
* @param string $visibility |
|
142
|
|
|
*/ |
|
143
|
|
|
public function setVisibility($path, $visibility) |
|
144
|
|
|
{ |
|
145
|
|
|
return true; |
|
|
|
|
|
|
146
|
|
|
} |
|
147
|
|
|
|
|
148
|
|
|
/** |
|
149
|
|
|
* @param string $path |
|
150
|
|
|
*/ |
|
151
|
|
|
public function has($path) |
|
152
|
|
|
{ |
|
153
|
|
|
return $this->client()->has($path); |
|
154
|
|
|
} |
|
155
|
|
|
|
|
156
|
|
|
/** |
|
157
|
|
|
* @param string $path |
|
158
|
|
|
*/ |
|
159
|
|
|
public function read($path) |
|
160
|
|
|
{ |
|
161
|
|
|
$contents = file_get_contents($this->getUrl($path)); |
|
162
|
|
|
return compact('contents', 'path'); |
|
163
|
|
|
} |
|
164
|
|
|
|
|
165
|
|
|
/** |
|
166
|
|
|
* @param string $path |
|
167
|
|
|
*/ |
|
168
|
|
|
public function readStream($path) |
|
169
|
|
|
{ |
|
170
|
|
|
$stream = fopen($this->getUrl($path), 'r'); |
|
171
|
|
|
return compact('stream', 'path'); |
|
172
|
|
|
} |
|
173
|
|
|
|
|
174
|
|
|
/** |
|
175
|
|
|
* @param string $directory |
|
176
|
|
|
* @param bool $recursive |
|
177
|
|
|
*/ |
|
178
|
|
|
public function listContents($directory = '', $recursive = false) |
|
179
|
|
|
{ |
|
180
|
|
|
$list = []; |
|
181
|
|
|
|
|
182
|
|
|
$result = $this->client()->read($directory, null, [ 'X-List-Limit' => 100, 'X-List-Iter' => null]); |
|
183
|
|
|
|
|
184
|
|
|
foreach ($result['files'] as $files) { |
|
185
|
|
|
$list[] = $this->normalizeFileInfo($files, $directory); |
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
|
|
return $list; |
|
189
|
|
|
} |
|
190
|
|
|
|
|
191
|
|
|
/** |
|
192
|
|
|
* @param string $path |
|
193
|
|
|
*/ |
|
194
|
|
|
public function getMetadata($path) |
|
195
|
|
|
{ |
|
196
|
|
|
return $this->client()->info($path); |
|
197
|
|
|
} |
|
198
|
|
|
|
|
199
|
|
|
/** |
|
200
|
|
|
* @param string $path |
|
201
|
|
|
*/ |
|
202
|
|
|
public function getType($path) |
|
203
|
|
|
{ |
|
204
|
|
|
$response = $this->getMetadata($path); |
|
205
|
|
|
|
|
206
|
|
|
return ['type' => $response['x-upyun-file-type']]; |
|
207
|
|
|
} |
|
208
|
|
|
|
|
209
|
|
|
/** |
|
210
|
|
|
* @param string $path |
|
211
|
|
|
*/ |
|
212
|
|
|
public function getSize($path) |
|
213
|
|
|
{ |
|
214
|
|
|
$response = $this->getMetadata($path); |
|
215
|
|
|
|
|
216
|
|
|
return ['size' => $response['x-upyun-file-size']]; |
|
217
|
|
|
} |
|
218
|
|
|
|
|
219
|
|
|
/** |
|
220
|
|
|
* @param string $path |
|
221
|
|
|
*/ |
|
222
|
|
|
public function getMimetype($path) |
|
223
|
|
|
{ |
|
224
|
|
|
$headers = get_headers($this->getUrl($path), 1); |
|
225
|
|
|
$mimetype = $headers['Content-Type']; |
|
226
|
|
|
return compact('mimetype'); |
|
227
|
|
|
} |
|
228
|
|
|
|
|
229
|
|
|
/** |
|
230
|
|
|
* @param string $path |
|
231
|
|
|
*/ |
|
232
|
|
|
public function getTimestamp($path) |
|
233
|
|
|
{ |
|
234
|
|
|
$response = $this->getMetadata($path); |
|
235
|
|
|
|
|
236
|
|
|
return ['timestamp' => $response['x-upyun-file-date']]; |
|
237
|
|
|
} |
|
238
|
|
|
|
|
239
|
|
|
/** |
|
240
|
|
|
* @param string $path |
|
241
|
|
|
*/ |
|
242
|
|
|
public function getVisibility($path) |
|
243
|
|
|
{ |
|
244
|
|
|
return true; |
|
|
|
|
|
|
245
|
|
|
} |
|
246
|
|
|
|
|
247
|
|
|
/** |
|
248
|
|
|
* @param $path |
|
249
|
|
|
* @return string |
|
250
|
|
|
*/ |
|
251
|
|
|
public function getUrl($path) |
|
252
|
|
|
{ |
|
253
|
|
|
return $this->normalizeHost($this->domain).$path; |
|
254
|
|
|
} |
|
255
|
|
|
|
|
256
|
|
|
/** |
|
257
|
|
|
* @return Upyun |
|
258
|
|
|
*/ |
|
259
|
|
|
protected function client() |
|
260
|
|
|
{ |
|
261
|
|
|
$config = new \Upyun\Config($this->bucket, $this->operator, $this->password); |
|
262
|
|
|
$config->useSsl = config('filesystems.disks.upyun.protocol') === 'https' ? true : false; |
|
263
|
|
|
return new Upyun($config); |
|
264
|
|
|
} |
|
265
|
|
|
|
|
266
|
|
|
/** |
|
267
|
|
|
* Normalize the file info. |
|
268
|
|
|
* |
|
269
|
|
|
* @param array $stats |
|
270
|
|
|
* @param string $directory |
|
271
|
|
|
* |
|
272
|
|
|
* @return array |
|
273
|
|
|
*/ |
|
274
|
|
|
protected function normalizeFileInfo(array $stats, string $directory) |
|
275
|
|
|
{ |
|
276
|
|
|
$filePath = ltrim($directory . '/' . $stats['name'], '/'); |
|
277
|
|
|
|
|
278
|
|
|
return [ |
|
279
|
|
|
'type' => $this->getType($filePath)['type'], |
|
280
|
|
|
'path' => $filePath, |
|
281
|
|
|
'timestamp' => $stats['time'], |
|
282
|
|
|
'size' => $stats['size'], |
|
283
|
|
|
]; |
|
284
|
|
|
} |
|
285
|
|
|
|
|
286
|
|
|
/** |
|
287
|
|
|
* @param $domain |
|
288
|
|
|
* @return string |
|
289
|
|
|
*/ |
|
290
|
|
|
protected function normalizeHost($domain) |
|
291
|
|
|
{ |
|
292
|
|
|
if (0 !== stripos($domain, 'https://') && 0 !== stripos($domain, 'http://')) { |
|
293
|
|
|
$domain = $this->protocol."://{$domain}"; |
|
294
|
|
|
} |
|
295
|
|
|
|
|
296
|
|
|
return rtrim($domain, '/').'/'; |
|
297
|
|
|
} |
|
298
|
|
|
} |
|
299
|
|
|
|
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_functionexpects aPostobject, and outputs the author of the post. The base classPostreturns a simple string and outputting a simple string will work just fine. However, the child classBlogPostwhich is a sub-type ofPostinstead decided to return anobject, and is therefore violating the SOLID principles. If aBlogPostwere passed tomy_function, PHP would not complain, but ultimately fail when executing thestrtouppercall in its body.