|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
ar_pinp::allow( 'ar_connect_ftp'); |
|
4
|
|
|
ar_pinp::allow( 'ar_connect_ftpClient' ); |
|
5
|
|
|
|
|
6
|
|
|
class ar_connect_ftp extends arBase { |
|
7
|
|
|
|
|
8
|
|
|
public static $timeout = 90; |
|
9
|
|
|
public static $pasv = false; |
|
10
|
|
|
public static $transferMode = FTP_BINARY; |
|
11
|
|
|
|
|
12
|
|
View Code Duplication |
public static function get( $url, $options = array() ) { |
|
13
|
|
|
$path = parse_url($url, PHP_URL_PATH ); |
|
14
|
|
|
if ($path !== false ) { |
|
15
|
|
|
$fileName = basename($path); |
|
16
|
|
|
$client = new ar_connect_ftpClient( $url, $options ); |
|
17
|
|
|
if ( !ar_error::isError( $client) ) { |
|
18
|
|
|
return $client->get( $fileName ); |
|
19
|
|
|
} else { |
|
20
|
|
|
return $client; |
|
21
|
|
|
} |
|
22
|
|
|
} else { |
|
23
|
|
|
return ar::error( "Could not parse url ".(string)$url, 11); |
|
24
|
|
|
} |
|
25
|
|
|
} |
|
26
|
|
|
|
|
27
|
|
View Code Duplication |
public static function put( $url, $contents, $options = array() ) { |
|
28
|
|
|
$path = parse_url( $url, PHP_URL_PATH ); |
|
29
|
|
|
if ($path !== false ) { |
|
30
|
|
|
$fileName = basename($path); |
|
31
|
|
|
$client = new ar_connect_ftpClient($url, $options ); |
|
32
|
|
|
if ( !ar_error::isError( $client ) ) { |
|
33
|
|
|
return $client->put( $contents, $fileName ); |
|
34
|
|
|
} else { |
|
35
|
|
|
return $client; |
|
36
|
|
|
} |
|
37
|
|
|
} else { |
|
38
|
|
|
return ar::error( "Could not parse url ".(string)$url, 11); |
|
39
|
|
|
} |
|
40
|
|
|
} |
|
41
|
|
|
|
|
42
|
|
|
public static function client( $url = null, $options = array() ) { |
|
43
|
|
|
return new ar_connect_ftpClient( $url, $options ); |
|
44
|
|
|
} |
|
45
|
|
|
|
|
46
|
|
|
public static function configure( $option, $value ) { |
|
47
|
|
|
switch ( $option ) { |
|
48
|
|
|
case 'timeout' : |
|
49
|
|
|
self::$timeout = $value; |
|
50
|
|
|
break; |
|
51
|
|
|
case 'pasv' : |
|
52
|
|
|
self::$pasv = $value; |
|
53
|
|
|
break; |
|
54
|
|
|
case 'transferMode' : |
|
55
|
|
|
self::$transferMode = $value; |
|
56
|
|
|
break; |
|
57
|
|
|
} |
|
58
|
|
|
} |
|
59
|
|
|
|
|
60
|
|
|
public function __set( $name, $value ) { |
|
61
|
|
|
ar_connect_ftp::configure( $name, $value ); |
|
62
|
|
|
} |
|
63
|
|
|
|
|
64
|
|
|
public function __get( $name ) { |
|
65
|
|
|
if ( isset( ar_connect_ftp::${$name} ) ) { |
|
66
|
|
|
return ar_connect_ftp::${$name}; |
|
67
|
|
|
} |
|
68
|
|
|
} |
|
69
|
|
|
|
|
70
|
|
|
} |
|
71
|
|
|
|
|
72
|
|
|
interface ar_connect_ftpClientInterface { |
|
73
|
|
|
|
|
74
|
|
|
public function get( $file, $options = array() ); |
|
75
|
|
|
|
|
76
|
|
|
public function put( $contents, $file, $options = array() ); |
|
77
|
|
|
|
|
78
|
|
|
public function login( $username, $password = null); |
|
79
|
|
|
|
|
80
|
|
|
public function connect( $host, $port = 21); |
|
81
|
|
|
|
|
82
|
|
|
public function disconnect(); |
|
83
|
|
|
|
|
84
|
|
|
public function delete( $file, $options = array() ); |
|
85
|
|
|
|
|
86
|
|
|
public function cd( $dir ); |
|
87
|
|
|
|
|
88
|
|
|
public function ls(); |
|
89
|
|
|
|
|
90
|
|
|
public function mkdir( $dirname ); |
|
91
|
|
|
|
|
92
|
|
|
public function rename( $name, $newname ); |
|
93
|
|
|
|
|
94
|
|
|
public function chmod( $mode, $filename ); |
|
95
|
|
|
|
|
96
|
|
|
public function size( $filename ); |
|
97
|
|
|
|
|
98
|
|
|
public function mdtm( $filename ); |
|
99
|
|
|
|
|
100
|
|
|
public function pwd(); |
|
101
|
|
|
|
|
102
|
|
|
public function mode( $mode ); |
|
103
|
|
|
|
|
104
|
|
|
public function pasv( $pasv ); |
|
105
|
|
|
|
|
106
|
|
|
} |
|
107
|
|
|
|
|
108
|
|
|
class ar_connect_ftpClient extends arBase implements ar_connect_ftpClientInterface { |
|
109
|
|
|
//FIXME: change error codes to the ar_exception constants |
|
110
|
|
|
public $options = array(); |
|
111
|
|
|
public $host = null; |
|
112
|
|
|
public $port = null; |
|
113
|
|
|
public $user = null; |
|
114
|
|
|
protected $pass = null; |
|
115
|
|
|
public $path = null; |
|
116
|
|
|
protected $connection = null; |
|
117
|
|
|
|
|
118
|
|
|
public function __construct( $url = null, $options = array() ) { |
|
119
|
|
|
$this->options = $options + array( |
|
120
|
|
|
'mode' => ar_connect_ftp::$transferMode, |
|
121
|
|
|
'pasv' => ar_connect_ftp::$pasv |
|
122
|
|
|
); |
|
123
|
|
|
$parsed = parse_url( $url ); |
|
124
|
|
|
if ($parsed) { |
|
125
|
|
|
$this->host = $parsed['host']; |
|
126
|
|
|
$this->port = $parsed['port'] ? $parsed['port'] : 21; |
|
127
|
|
|
$this->user = $parsed['user'] ? $parsed['user'] : 'anonymous'; |
|
128
|
|
|
$this->pass = $parsed['pass'] ? $parsed['pass'] : 'guest'; |
|
129
|
|
|
$this->path = $parsed['path']; |
|
130
|
|
|
if ($this->path[strlen($this->path)-1] != '/' ) { |
|
131
|
|
|
$this->path = substr(dirname($this->path), 1); // relative path for cd |
|
132
|
|
|
} |
|
133
|
|
|
if ($this->host) { |
|
134
|
|
|
$this->connect( $this->host, $this->port ); |
|
135
|
|
|
$this->login( $this->user, $this->pass ); |
|
136
|
|
|
if ($this->path) { |
|
137
|
|
|
$this->cd( $this->path ); |
|
138
|
|
|
} |
|
139
|
|
|
} |
|
140
|
|
|
} |
|
141
|
|
|
} |
|
142
|
|
|
|
|
143
|
|
|
public function get( $file, $options = array() ) { |
|
144
|
|
|
$this->options = array_merge( $this->options, (array) $options ); |
|
145
|
|
|
$fp = fopen("php://temp/maxmemory:10485760", "w"); |
|
146
|
|
|
$result = @ftp_fget( $this->connection, $fp, $file, $this->options['mode'] ); |
|
147
|
|
|
if( $result ) { |
|
148
|
|
|
fseek( $fp, 0 ); |
|
149
|
|
|
$result = stream_get_contents( $fp ); |
|
150
|
|
|
} else { |
|
151
|
|
|
$result = ar::error( "Failed to get file $file", 12); |
|
152
|
|
|
} |
|
153
|
|
|
fclose( $fp ); |
|
154
|
|
|
return $result; |
|
155
|
|
|
} |
|
156
|
|
|
|
|
157
|
|
|
public function put( $contents, $file, $options = array() ) { |
|
158
|
|
|
$this->options = array_merge( $this->options, (array) $options ); |
|
159
|
|
|
if ($contents instanceof pfile ) { |
|
|
|
|
|
|
160
|
|
|
global $store; |
|
161
|
|
|
$files = $store->get_filestore('files'); |
|
162
|
|
|
$path = $files->make_path($contents->id, 'file'); |
|
163
|
|
|
$fp = fopen($path, 'r'); |
|
164
|
|
|
} else { |
|
165
|
|
|
$fp = fopen("php://temp/maxmemory:10485760", "w+"); |
|
166
|
|
|
fwrite( $fp, (string) $contents ); |
|
167
|
|
|
fseek( $fp, 0); |
|
168
|
|
|
} |
|
169
|
|
|
$result = ftp_fput( $this->connection, $file, $fp, $this->options['mode'] ); |
|
170
|
|
|
fclose($fp); |
|
171
|
|
|
if ( !$result ) { |
|
172
|
|
|
return ar::error( "Could not save file $file.", 10 ); |
|
173
|
|
|
} |
|
174
|
|
|
return $this; |
|
175
|
|
|
} |
|
176
|
|
|
|
|
177
|
|
|
public function login( $username, $password = null) { |
|
178
|
|
|
if (!@ftp_login($this->connection, $username, $password)) { |
|
179
|
|
|
return ar::error( "Could not connect as $username", 1); |
|
180
|
|
|
} |
|
181
|
|
|
return $this; |
|
182
|
|
|
} |
|
183
|
|
|
|
|
184
|
|
|
public function connect( $host, $port = 21) { |
|
185
|
|
|
if ( ! $this->connection = ftp_connect( $host, $port ) ) { // FIXME: add timeout? |
|
186
|
|
|
return ar::error( "Could not connect to $host on port $port", 2); |
|
187
|
|
|
} else if (ar_connect_ftp::$timeout) { |
|
188
|
|
|
ftp_set_option( $this->connection, FTP_TIMEOUT_SEC, ar_connect_ftp::$timeout ); |
|
189
|
|
|
} |
|
190
|
|
|
return $this; |
|
191
|
|
|
} |
|
192
|
|
|
|
|
193
|
|
|
public function cd( $dir ) { |
|
194
|
|
|
$result = ftp_chdir( $this->connection, $dir ); |
|
195
|
|
|
if ( !$result ) { |
|
196
|
|
|
return ar::error( "Could not change to directory $dir.", 9); |
|
197
|
|
|
} |
|
198
|
|
|
return $this; |
|
199
|
|
|
} |
|
200
|
|
|
|
|
201
|
|
|
public function disconnect() { |
|
202
|
|
|
ftp_close( $this->connection ); |
|
203
|
|
|
return $this; |
|
204
|
|
|
} |
|
205
|
|
|
|
|
206
|
|
|
public function delete( $file, $options = array() ) { |
|
207
|
|
|
$result = ftp_delete( $this->connection, $file ); |
|
208
|
|
|
if ( !$result ) { |
|
209
|
|
|
return ar::error( "Could not delete file $file.", 7 ); |
|
210
|
|
|
} |
|
211
|
|
|
return $this; |
|
212
|
|
|
} |
|
213
|
|
|
|
|
214
|
|
|
public function ls($path='.', $verbose=false) { |
|
215
|
|
|
if (!$verbose) { |
|
216
|
|
|
$result = ftp_nlist($this->connection, $path); |
|
217
|
|
|
if ( !$result ) { |
|
|
|
|
|
|
218
|
|
|
return ar::error( "Could not list the current directory.", 8); |
|
219
|
|
|
} |
|
220
|
|
|
} else { |
|
221
|
|
|
if (!$this->connection) { |
|
222
|
|
|
return ar::error("Connection is not active", 42); |
|
223
|
|
|
} |
|
224
|
|
|
$list = ftp_rawlist($this->connection, $path); |
|
225
|
|
|
if ( !$list ) { |
|
|
|
|
|
|
226
|
|
|
return ar::error( "Could not rawlist the current directory.", 9); |
|
227
|
|
|
} |
|
228
|
|
|
$result = array(); |
|
229
|
|
|
foreach($list as $info) { |
|
230
|
|
|
$info = preg_split("/[\s]+/", $info, 9); |
|
231
|
|
|
$entry = array( |
|
232
|
|
|
"permissions" => $info[0], |
|
233
|
|
|
"linkcount" => $info[1], |
|
234
|
|
|
"userid" => $info[2], |
|
235
|
|
|
"groupid" => $info[3], |
|
236
|
|
|
"size" => (int)$info[4], |
|
237
|
|
|
"mtime" => strtotime($info[5] . " " . $info[6] . " " . $info[7]), |
|
238
|
|
|
"name"=> $info[8] |
|
239
|
|
|
); |
|
240
|
|
|
|
|
241
|
|
|
if (substr($info[0], 0, 1) == "d") { |
|
242
|
|
|
$entry['type'] = "dir"; |
|
243
|
|
|
} elseif (substr($info[0], 0, 1) == "l") { |
|
244
|
|
|
$entry['type'] = "shortcut"; |
|
245
|
|
|
$nameinfo = explode(" -> ", $info[8]); |
|
246
|
|
|
$entry['name'] = $nameinfo[0]; |
|
247
|
|
|
$entry['target'] = $nameinfo[1]; |
|
248
|
|
|
} else { |
|
249
|
|
|
$entry['type'] = "file"; |
|
250
|
|
|
} |
|
251
|
|
|
$result[$entry['name']] = $entry; |
|
252
|
|
|
} |
|
253
|
|
|
} |
|
254
|
|
|
return $result; |
|
255
|
|
|
} |
|
256
|
|
|
|
|
257
|
|
|
public function mkdir( $dirname ) { |
|
258
|
|
|
$result = ftp_mkdir( $this->connection, $dirname ); |
|
259
|
|
|
if (!$result) { |
|
260
|
|
|
return ar::error( "Could not make directory $dirname.", 3); |
|
261
|
|
|
} |
|
262
|
|
|
return $this; |
|
263
|
|
|
} |
|
264
|
|
|
|
|
265
|
|
|
public function rename( $name, $newname ) { |
|
266
|
|
|
if (!ftp_rename( $this->connection, $name, $newname ) ) { |
|
267
|
|
|
return ar::error( "Could not rename $name to $newname.", 4); |
|
268
|
|
|
} |
|
269
|
|
|
return $this; |
|
270
|
|
|
} |
|
271
|
|
|
|
|
272
|
|
|
public function chmod( $mode, $filename ) { |
|
273
|
|
|
if (!ftp_chmod( $this->connection, $mode, $filename) ) { |
|
274
|
|
|
return ar::error( "Could not chmod $filename.", 5); |
|
275
|
|
|
} |
|
276
|
|
|
return $this; |
|
277
|
|
|
} |
|
278
|
|
|
|
|
279
|
|
|
public function size( $filename ) { |
|
280
|
|
|
$result = ftp_size($this->connection, $filename); |
|
281
|
|
|
if ( $result == -1 ) { |
|
282
|
|
|
return null; |
|
283
|
|
|
} else { |
|
284
|
|
|
return $result; |
|
285
|
|
|
} |
|
286
|
|
|
} |
|
287
|
|
|
|
|
288
|
|
|
public function mdtm( $filename ) { |
|
289
|
|
|
$result = ftp_mdtm( $this->connection, $filename ); |
|
290
|
|
|
if ($result == -1 ) { |
|
291
|
|
|
return null; |
|
292
|
|
|
} else { |
|
293
|
|
|
return $result; |
|
294
|
|
|
} |
|
295
|
|
|
} |
|
296
|
|
|
|
|
297
|
|
|
public function pwd() { |
|
298
|
|
|
return ftp_pwd( $this->connection ); |
|
299
|
|
|
} |
|
300
|
|
|
|
|
301
|
|
|
public function mode( $mode ) { |
|
302
|
|
|
$this->options['mode'] = $mode; |
|
303
|
|
|
return $this; |
|
304
|
|
|
} |
|
305
|
|
|
|
|
306
|
|
|
public function pasv( $pasv = true ) { |
|
307
|
|
|
$this->options['pasv'] = $pasv; |
|
308
|
|
|
if ( !ftp_pasv( $this->connection, $pasv) ) { |
|
309
|
|
|
return ar::error( "Could not switch passive mode.", 6); |
|
310
|
|
|
} |
|
311
|
|
|
return $this; |
|
312
|
|
|
} |
|
313
|
|
|
|
|
314
|
|
|
} |
|
315
|
|
|
|
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.jsonfile (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.jsonto be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
requireorrequire-devsection?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceofchecks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.