depage-fs
Toggle main menu visibility
Loading...
Searching...
No Matches
FtpCurl.php
Go to the documentation of this file.
1
<?php
2
3
namespace
Depage\Fs\Streams
;
4
5
use
Depage\Fs\Exceptions\FsException
;
6
use
Depage\Fs\Fs
;
7
8
class
FtpCurl
9
{
10
public
$context
;
11
12
protected
$path
;
13
protected
$mode
;
14
protected
$buffer
;
15
protected
$pos
;
16
protected
$dirPos
;
17
protected
$files
;
18
protected
$url
;
19
protected
$translation
= [
'dev'
,
'ino'
,
'mode'
,
'nlink'
,
'uid'
,
'gid'
,
'rdev'
,
'size'
,
'atime'
,
'mtime'
,
'ctime'
,
'blksize'
,
'blocks'
];
20
21
static
protected
$parameters
;
22
static
protected
$handle
;
23
public
static
function
registerStream
($protocol, array
$parameters
= [])
24
{
25
$class = get_called_class();
26
static::$parameters =
$parameters
;
27
28
if
(in_array($protocol, stream_get_wrappers())) {
29
stream_wrapper_unregister($protocol);
30
}
31
stream_wrapper_register($protocol, $class);
32
}
33
34
protected
function
getParameter
($parameter)
35
{
36
return
isset(static::$parameters[$parameter]) ? static::$parameters[$parameter] :
null
;
37
}
38
protected
function
createHandle
(
$url
, $hostOnly =
false
)
39
{
40
$parsed =
Fs::parseUrl
(
$url
);
41
$parsed[
'path'
] = str_replace(
" "
,
"%20"
, $parsed[
'path'
]);
42
$host = preg_replace(
'#'
. preg_quote($parsed[
'path'
]) .
'(/)?$#'
,
''
,
$url
);
43
$path
= (isset($parsed[
'path'
])) ? $parsed[
'path'
] :
'/'
;
44
$url
= str_replace(
" "
,
"%20"
,
$url
);
45
46
if
(static::$handle) {
47
curl_reset(static::$handle);
48
$this->
curlSet
(CURLOPT_URL, ($hostOnly) ? $host :
$url
);
49
}
else
{
50
static::$handle = ($hostOnly) ? curl_init($host) : curl_init(
$url
);
51
}
52
53
if
(!static::$handle) {
54
throw
new
FsException
(
'Could not initialize cURL.'
);
55
}
56
57
$username = $parsed[
'user'
];
58
$password = (isset($parsed[
'pass'
])) ? $parsed[
'pass'
] :
''
;
59
60
$options = [
61
CURLOPT_USERNAME => rawurldecode($username),
62
CURLOPT_PASSWORD => rawurldecode($password),
63
CURLOPT_RETURNTRANSFER =>
true
,
64
CURLOPT_PORT => (isset($parsed[
'port'
])) ? $parsed[
'port'
] : 21,
65
CURLOPT_FOLLOWLOCATION =>
true
,
66
//CURLOPT_VERBOSE => true,
67
];
68
69
if
($parsed[
'scheme'
] ==
"ftps"
) {
70
$options += [
71
CURLOPT_FTP_SSL => CURLFTPSSL_TRY,
// require SSL For both control and data connections
72
CURLOPT_FTPSSLAUTH => CURLFTPAUTH_DEFAULT,
// let cURL choose the FTP authentication method (either SSL or TLS)
73
];
74
}
75
76
if
($this->
getParameter
(
'timeout'
)) {
77
$options[CURLOPT_TIMEOUT] = $this->
getParameter
(
'timeout'
);
78
}
79
80
if
($this->
getParameter
(
'caCert'
)) {
81
$options += [
82
CURLOPT_SSL_VERIFYPEER =>
true
,
83
CURLOPT_SSL_VERIFYHOST => 2,
84
CURLOPT_CAINFO => $this->
getParameter
(
'caCert'
),
85
];
86
}
87
88
// cURL FTP enables passive mode by default, so disable it by enabling the PORT command and allowing cURL to select the IP address for the data connection
89
if
(!$this->
getParameter
(
'passive'
) ===
false
) {
90
$options[CURLOPT_FTPPORT] =
'-'
;
91
}
92
93
foreach
($options as $option => $value) {
94
$this->
curlSet
($option, $value);
95
}
96
97
return
$path
;
98
}
99
public
static
function
disconnect
()
100
{
101
static::$handle =
null
;
102
}
103
protected
function
curlSet
($option, $value)
104
{
105
if
(!curl_setopt(static::$handle, $option, $value)) {
106
throw
new
FsException
(sprintf(
'Could not set cURL option: %s'
, $option));
107
}
108
}
109
protected
function
execute
()
110
{
111
$result = curl_exec(static::$handle);
112
113
if
(
114
$result ===
false
115
&& $this->
getParameter
(
'ssl'
) ===
false
116
) {
117
$this->
curlSet
(CURLOPT_SSL_VERIFYPEER,
false
);
118
$this->
curlSet
(CURLOPT_SSL_VERIFYHOST,
false
);
119
120
$result = curl_exec(static::$handle);
121
}
122
123
if
(
124
$result ===
false
125
&& curl_errno(static::$handle) !== 9
126
&& curl_errno(static::$handle) !== 21
127
) {
128
throw
new
FsException
(curl_error(static::$handle) ?:
'cURL request failed.'
);
129
}
130
131
return
$result;
132
}
133
protected
function
executeFtpCommand
($command,
$url
)
134
{
135
$path
= $this->
createHandle
(
$url
,
true
);
136
$this->
curlSet
(CURLOPT_QUOTE, [$command .
' '
.
$path
]);
137
$this->
curlSet
(CURLOPT_NOBODY,
true
);
138
139
$result = $this->
execute
();
140
141
return
($result ===
false
) ? false :
true
;
142
}
143
144
protected
function
isDir
(
$url
)
145
{
146
return
$this->
executeFtpCommand
(
'CWD'
,
$url
);
147
}
148
protected
function
mkdirRecursive
(
$url
)
149
{
150
$result =
true
;
151
152
if
(!$this->
isDir
(
$url
)) {
153
$path
= explode(
'/'
,
$url
);
154
array_pop(
$path
);
155
$prev = implode(
'/'
,
$path
);
156
if
(!$this->
isDir
($prev)) {
157
$result = $this->
mkdirRecursive
($prev);
158
}
159
$result = $result && $result = $this->
executeFtpCommand
(
'MKD'
,
$url
);
160
}
161
162
return
$result;
163
}
164
165
public
function
stream_open
(
$url
,
$mode
, $options, &$openedPath)
166
{
167
$this->url =
$url
;
168
$this->mode =
$mode
;
169
$this->pos = 0;
170
171
$this->
createHandle
(
$url
);
172
173
if
($this->mode ==
'wb'
) {
174
$this->
curlSet
(CURLOPT_UPLOAD,
true
);
175
$this->buffer = fopen(
'php://temp'
,
'w+b'
);
176
}
else
{
177
$this->buffer = $this->
execute
();
178
}
179
180
return
true
;
181
}
182
public
function
stream_close
()
183
{
184
}
185
public
function
stream_read
($count)
186
{
187
$read =
false
;
188
189
if
(strlen($this->buffer) > 0) {
190
$read = substr($this->buffer, $this->pos, $count);
191
$this->pos += $count;
192
}
193
194
return
$read;
195
}
196
public
function
stream_write
($data)
197
{
198
$bytesWritten = fwrite($this->buffer, $data);
199
$this->pos += $bytesWritten;
200
201
return
$bytesWritten;
202
}
203
public
function
stream_eof
()
204
{
205
$eof =
false
;
206
207
if
($this->pos >= strlen($this->buffer)) {
208
$eof =
true
;
209
}
210
211
return
$eof;
212
}
213
public
function
stream_tell
()
214
{
215
return
$this->pos
;
216
}
217
public
function
stream_flush
()
218
{
219
$result =
true
;
220
221
if
($this->mode ==
'wb'
) {
222
rewind($this->buffer);
223
224
$this->
curlSet
(CURLOPT_INFILE, $this->buffer);
225
$this->
curlSet
(CURLOPT_INFILESIZE, $this->pos);
226
227
$result = ($this->
execute
() ===
false
) ?
false
:
true
;
228
}
229
230
$this->buffer =
null
;
231
$this->pos =
null
;
232
233
return
$result;
234
}
235
public
function
stream_stat
()
236
{
237
$this->
createHandle
($this->url);
238
239
$stat = $this->
createStat
();
240
$this->
setStat
($stat,
'size'
, strlen($this->buffer));
241
242
return
$stat;
243
}
244
public
function
url_stat
(
$url
, $flags)
245
{
246
$urlArray = explode(
'/'
,
$url
);
247
$nodeName = array_pop($urlArray);
248
$url
= implode(
'/'
, $urlArray) .
'/'
;
249
250
$stat =
false
;
251
$this->
createHandle
(
$url
,
false
);
252
$this->
curlSet
(CURLOPT_CUSTOMREQUEST,
'LIST -a'
);
253
$result = $this->
execute
();
254
255
if
($result) {
256
$nodes = $this->
parseLs
($result);
257
258
if
(isset($nodes[$nodeName])) {
259
$stat = $this->
createStat
();
260
$node = $nodes[$nodeName];
261
262
$this->
setStat
(
263
$stat,
264
'mode'
,
265
octdec($this->
translateFileType
($node[
'type'
]) . $this->
translatePermissions
($node[
'permissions'
]))
266
);
267
}
268
}
269
270
return
$stat;
271
}
272
public
function
dir_opendir
(
$url
, $options)
273
{
274
$this->dirPos = 0;
275
276
$path
= $this->
createHandle
(
$url
,
true
);
277
$this->
curlSet
(CURLOPT_CUSTOMREQUEST,
'LIST -a '
.
$path
);
278
$result = $this->
execute
();
279
280
$this->files = ($result) ? array_keys($this->
parseLs
($result)) : [];
281
282
return
(
bool
) $result;
283
}
284
public
function
dir_readdir
()
285
{
286
$result =
false
;
287
288
if
(isset($this->files[$this->dirPos])) {
289
$result = $this->files[
$this->dirPos
];
290
$this->dirPos++;
291
}
292
293
return
$result;
294
}
295
public
function
mkdir
(
$url
,
$mode
, $options)
296
{
297
if
($options & STREAM_MKDIR_RECURSIVE) {
298
$result = $this->
mkdirRecursive
(
$url
);
299
}
else
{
300
$result = $this->
executeFtpCommand
(
'MKD'
,
$url
);
301
}
302
303
return
$result;
304
}
305
public
function
unlink
(
$url
)
306
{
307
return
$this->
executeFtpCommand
(
'DELE'
,
$url
);
308
}
309
public
function
rmdir
(
$url
)
310
{
311
return
$this->
executeFtpCommand
(
'RMD'
,
$url
);
312
}
313
public
function
rename
($urlFrom, $urlTo)
314
{
315
$pathFrom = $this->
createHandle
($urlFrom,
true
);
316
$pathTo = $this->
createHandle
($urlTo,
true
);
317
318
$this->
curlSet
(CURLOPT_QUOTE, [
'RNFR '
. $pathFrom,
'RNTO '
. $pathTo]);
319
320
return
($this->
execute
() ===
false
) ? false :
true
;
321
}
322
323
protected
function
createStat
()
324
{
325
$stat = [];
326
327
foreach
($this->translation as $index => $name) {
328
$stat[$index] = 0;
329
$stat[$name] = 0;
330
}
331
332
return
$stat;
333
}
334
protected
function
setStat
(&$stat, $name, $value)
335
{
336
$stat[$name] = $value;
337
$stat[array_search($name, $this->translation)] = $value;
338
}
339
protected
function
parseLs
($ls)
340
{
341
$list = explode(PHP_EOL, trim($ls));
342
343
$nodes = [];
344
foreach
($list as $line) {
345
if
($line) {
346
$split = preg_split(
'/\s+/'
, $line);
347
348
$info[
'type'
] = $split[0][0];
349
$info[
'permissions'
] = substr(array_shift($split),1);
350
$info[
'hardlinks'
] = array_shift($split);
351
$info[
'user'
] = array_shift($split);
352
$info[
'group'
] = array_shift($split);
353
$info[
'size'
] = array_shift($split);
354
$name = implode(
' '
, array_splice($split, 3));
355
$info[
'mtime'
] = strtotime(implode(
' '
, $split));
356
357
$nodes[$name] = $info;
358
}
359
}
360
361
return
$nodes;
362
}
363
364
protected
function
translateFileType
($char)
365
{
366
$type =
false
;
367
368
switch
($char) {
369
case
'-'
: $type = 100;
break
;
370
case
'd'
: $type = 40;
break
;
371
}
372
373
return
$type;
374
}
375
protected
function
translatePermissions
($permissions)
376
{
377
$result =
''
;
378
379
foreach
(str_split($permissions, 3) as $operator) {
380
$numerical = 0;
381
382
for
($i = 0; $i < 2; $i++) {
383
if
($operator[$i] !==
'-'
) {
384
$numerical += pow(2, (2 - $i));
385
}
386
}
387
388
$result .= $numerical;
389
}
390
391
return
$result;
392
}
393
}
394
395
// vim:set ft=php sw=4 sts=4 fdm=marker :
Depage\Fs\Exceptions\FsException
Definition
FsException.php:5
Depage\Fs\Fs
Definition
Fs.php:6
Depage\Fs\Fs\parseUrl
static parseUrl($url)
Definition
Fs.php:355
Depage\Fs\Streams\FtpCurl
Definition
FtpCurl.php:9
Depage\Fs\Streams\FtpCurl\$path
$path
Definition
FtpCurl.php:12
Depage\Fs\Streams\FtpCurl\createHandle
createHandle($url, $hostOnly=false)
Definition
FtpCurl.php:38
Depage\Fs\Streams\FtpCurl\stream_write
stream_write($data)
Definition
FtpCurl.php:196
Depage\Fs\Streams\FtpCurl\execute
execute()
Definition
FtpCurl.php:109
Depage\Fs\Streams\FtpCurl\$translation
$translation
Definition
FtpCurl.php:19
Depage\Fs\Streams\FtpCurl\url_stat
url_stat($url, $flags)
Definition
FtpCurl.php:244
Depage\Fs\Streams\FtpCurl\translateFileType
translateFileType($char)
Definition
FtpCurl.php:364
Depage\Fs\Streams\FtpCurl\$mode
$mode
Definition
FtpCurl.php:13
Depage\Fs\Streams\FtpCurl\isDir
isDir($url)
Definition
FtpCurl.php:144
Depage\Fs\Streams\FtpCurl\stream_eof
stream_eof()
Definition
FtpCurl.php:203
Depage\Fs\Streams\FtpCurl\mkdir
mkdir($url, $mode, $options)
Definition
FtpCurl.php:295
Depage\Fs\Streams\FtpCurl\unlink
unlink($url)
Definition
FtpCurl.php:305
Depage\Fs\Streams\FtpCurl\$dirPos
$dirPos
Definition
FtpCurl.php:16
Depage\Fs\Streams\FtpCurl\parseLs
parseLs($ls)
Definition
FtpCurl.php:339
Depage\Fs\Streams\FtpCurl\$pos
$pos
Definition
FtpCurl.php:15
Depage\Fs\Streams\FtpCurl\setStat
setStat(&$stat, $name, $value)
Definition
FtpCurl.php:334
Depage\Fs\Streams\FtpCurl\createStat
createStat()
Definition
FtpCurl.php:323
Depage\Fs\Streams\FtpCurl\rmdir
rmdir($url)
Definition
FtpCurl.php:309
Depage\Fs\Streams\FtpCurl\dir_opendir
dir_opendir($url, $options)
Definition
FtpCurl.php:272
Depage\Fs\Streams\FtpCurl\stream_flush
stream_flush()
Definition
FtpCurl.php:217
Depage\Fs\Streams\FtpCurl\translatePermissions
translatePermissions($permissions)
Definition
FtpCurl.php:375
Depage\Fs\Streams\FtpCurl\$files
$files
Definition
FtpCurl.php:17
Depage\Fs\Streams\FtpCurl\rename
rename($urlFrom, $urlTo)
Definition
FtpCurl.php:313
Depage\Fs\Streams\FtpCurl\stream_tell
stream_tell()
Definition
FtpCurl.php:213
Depage\Fs\Streams\FtpCurl\dir_readdir
dir_readdir()
Definition
FtpCurl.php:284
Depage\Fs\Streams\FtpCurl\executeFtpCommand
executeFtpCommand($command, $url)
Definition
FtpCurl.php:133
Depage\Fs\Streams\FtpCurl\$parameters
static $parameters
Definition
FtpCurl.php:21
Depage\Fs\Streams\FtpCurl\curlSet
curlSet($option, $value)
Definition
FtpCurl.php:103
Depage\Fs\Streams\FtpCurl\getParameter
getParameter($parameter)
Definition
FtpCurl.php:34
Depage\Fs\Streams\FtpCurl\disconnect
static disconnect()
Definition
FtpCurl.php:99
Depage\Fs\Streams\FtpCurl\stream_open
stream_open($url, $mode, $options, &$openedPath)
Definition
FtpCurl.php:165
Depage\Fs\Streams\FtpCurl\$url
$url
Definition
FtpCurl.php:18
Depage\Fs\Streams\FtpCurl\stream_read
stream_read($count)
Definition
FtpCurl.php:185
Depage\Fs\Streams\FtpCurl\stream_stat
stream_stat()
Definition
FtpCurl.php:235
Depage\Fs\Streams\FtpCurl\mkdirRecursive
mkdirRecursive($url)
Definition
FtpCurl.php:148
Depage\Fs\Streams\FtpCurl\$handle
static $handle
Definition
FtpCurl.php:22
Depage\Fs\Streams\FtpCurl\$context
$context
Definition
FtpCurl.php:10
Depage\Fs\Streams\FtpCurl\$buffer
$buffer
Definition
FtpCurl.php:14
Depage\Fs\Streams\FtpCurl\registerStream
static registerStream($protocol, array $parameters=[])
Definition
FtpCurl.php:23
Depage\Fs\Streams\FtpCurl\stream_close
stream_close()
Definition
FtpCurl.php:182
Depage\Fs\Streams
Definition
FtpCurl.php:3
Streams
FtpCurl.php
Generated on
for depage-fs by
doxygen
1.18.0
For an overview of all docs, go to
docs.depage.net