1
<?php
2
/**
3
* FTP Class
4
*
5
* @package CodeIgniter
6
* @subpackage Libraries
7
* @category Libraries
8
* @author ExpressionEngine Dev Team
9
* @link http://codeigniter.com/user_guide/libraries/ftp.html
10
*/
11
class FTP_Library {
12
13
protected $hostname = '';
14
protected $username = '';
15
protected $password = '';
16
protected $port = 21;
17
protected $passive = TRUE;
18
19
/**
20
* Whether to enable debugging to display error messages
21
*
22
* @var bollean
23
*/
24
protected $debug = FALSE;
25
26
/**
27
* Whether to use passive mode. Passive is set automatically by default
28
*
29
* @var bollean
30
*/
31
protected $conn_id = FALSE;
32
33
private $_error_messages = array();
34
35
36
/**
37
* Constructor
38
*/
39
public function __construct(array $config = NULL) {
40
$this->_error_messages = array(
41
'ftp_no_connection' => 'Unable to locate a valid connection ID. Please make sure you are connected before peforming any file routines.',
42
'ftp_unable_to_connect' => 'Unable to connect to your FTP server using the supplied hostname.',
43
'ftp_unable_to_login' => 'Unable to login to your FTP server. Please check your username and password.',
44
'ftp_unable_to_makdir' => 'Unable to create the directory you have specified.',
45
'ftp_unable_to_changedir' => 'Unable to change directories.',
46
'ftp_unable_to_chmod' => 'Unable to set file permissions. Please check your path. Note: This feature is only available in PHP 5 or higher.',
47
'ftp_unable_to_upload' => 'Unable to upload the specified file. Please check your path.',
48
'ftp_unable_to_download' => 'Unable to download the specified file. Please check your path.',
49
'ftp_no_source_file' => 'Unable to locate the source file. Please check your path.',
50
'ftp_unable_to_rename' => 'Unable to rename the file.',
51
'ftp_unable_to_delete' => 'Unable to delete the file.',
52
'ftp_unable_to_move' => 'Unable to move the file. Please make sure the destination directory exists.',
53
);
54
55
if (isset($config['hostname'])) {
56
$this->hostname = $config['hostname'];
57
// Prep the hostname
58
$this->hostname = preg_replace('|.+?://|', '', $this->hostname);
59
}
60
61
if (isset($config['username'])) {
62
$this->username = $config['username'];
63
}
64
65
if (isset($config['password'])) {
66
$this->password = $config['password'];
67
}
68
69
if (isset($config['port'])) {
70
$this->port = $config['port'];
71
}
72
73
if (isset($config['passive'])) {
74
$this->passive = $config['passive'];
75
}
76
77
if (isset($config['debug'])) {
78
$this->debug = $config['debug'];
79
}
80
81
if (($this->conn_id = @ftp_connect($this->hostname, $this->port)) === FALSE) {
82
if ($this->debug == TRUE) {
83
$this->_error('ftp_unable_to_connect');
84
}
85
}
86
87
if ( ! $this->_login()) {
88
if ($this->debug == TRUE) {
89
$this->_error('ftp_unable_to_login');
90
}
91
}
92
93
// Set passive mode if needed
94
if ($this->passive == TRUE) {
95
ftp_pasv($this->conn_id, TRUE);
96
}
97
}
98
99
100
/**
101
* FTP Login
102
*
103
* @return bool
104
*/
105
private function _login() {
106
return @ftp_login($this->conn_id, $this->username, $this->password);
107
}
108
109
110
/**
111
* Validates the connection ID
112
*
113
* @return bool
114
*/
115
private function _is_conn() {
116
if ( ! is_resource($this->conn_id)) {
117
if ($this->debug == TRUE) {
118
$this->_error('ftp_no_connection');
119
}
120
return FALSE;
121
}
122
return TRUE;
123
}
124
125
126
/**
127
* Change directory
128
*
129
* The second parameter lets us momentarily turn off debugging so that
130
* this function can be used to test for the existence of a folder
131
* without throwing an error. There's no FTP equivalent to is_dir()
132
* so we do it by trying to change to a particular directory.
133
* Internally, this parameter is only used by the "mirror" function below.
134
*
135
* @param string
136
* @param bool
137
* @return bool
138
*/
139
public function changedir($path = '', $supress_debug = FALSE) {
140
if ($path == '' || ! $this->_is_conn()) {
141
return FALSE;
142
}
143
144
$result = @ftp_chdir($this->conn_id, $path);
145
146
if ($result === FALSE) {
147
if ($this->debug == TRUE && $supress_debug == FALSE) {
148
$this->_error('ftp_unable_to_changedir');
149
}
150
return FALSE;
151
}
152
153
return TRUE;
154
}
155
156
157
/**
158
* Create a directory
159
*
160
* @param string
161
* @return bool
162
*/
163
public function mkdir($path = '', $permissions = NULL) {
164
if ($path == '' || ! $this->_is_conn()) {
165
return FALSE;
166
}
167
168
$result = @ftp_mkdir($this->conn_id, $path);
169
170
if ($result === FALSE) {
171
if ($this->debug == TRUE) {
172
$this->_error('ftp_unable_to_makdir');
173
}
174
return FALSE;
175
}
176
177
// Set file permissions if needed
178
if ( ! is_null($permissions)) {
179
$this->chmod($path, (int)$permissions);
180
}
181
182
return TRUE;
183
}
184
185
186
/**
187
* Upload a file to the server
188
*
189
* @param string
190
* @param string
191
* @param string
192
* @return bool
193
*/
194
public function upload($locpath, $rempath, $mode = 'auto', $permissions = NULL) {
195
if ( ! $this->_is_conn()) {
196
return FALSE;
197
}
198
199
if ( ! file_exists($locpath)) {
200
$this->_error('ftp_no_source_file');
201
return FALSE;
202
}
203
204
// Set the mode if not specified
205
if ($mode == 'auto') {
206
// Get the file extension so we can set the upload type
207
$ext = $this->_getext($locpath);
208
$mode = $this->_settype($ext);
209
}
210
211
$mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;
212
213
$result = @ftp_put($this->conn_id, $rempath, $locpath, $mode);
214
215
if ($result === FALSE) {
216
if ($this->debug == TRUE) {
217
$this->_error('ftp_unable_to_upload');
218
}
219
return FALSE;
220
}
221
222
// Set file permissions if needed
223
if ( ! is_null($permissions)) {
224
$this->chmod($rempath, (int)$permissions);
225
}
226
227
return TRUE;
228
}
229
230
231
/**
232
* Download a file from a remote server to the local server
233
*
234
* @param string
235
* @param string
236
* @param string
237
* @return bool
238
*/
239
public function download($rempath, $locpath, $mode = 'auto') {
240
if ( ! $this->_is_conn()) {
241
return FALSE;
242
}
243
244
// Set the mode if not specified
245
if ($mode == 'auto') {
246
// Get the file extension so we can set the upload type
247
$ext = $this->_getext($rempath);
248
$mode = $this->_settype($ext);
249
}
250
251
$mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;
252
253
$result = @ftp_get($this->conn_id, $locpath, $rempath, $mode);
254
255
if ($result === FALSE) {
256
if ($this->debug == TRUE) {
257
$this->_error('ftp_unable_to_download');
258
}
259
return FALSE;
260
}
261
262
return TRUE;
263
}
264
265
266
/**
267
* Rename (or move) a file
268
*
269
* @param string
270
* @param string
271
* @param bool
272
* @return bool
273
*/
274
public function rename($old_file, $new_file, $move = FALSE) {
275
if ( ! $this->_is_conn()) {
276
return FALSE;
277
}
278
279
$result = @ftp_rename($this->conn_id, $old_file, $new_file);
280
281
if ($result === FALSE) {
282
if ($this->debug == TRUE) {
283
$msg = ($move == FALSE) ? 'ftp_unable_to_rename' : 'ftp_unable_to_move';
284
285
$this->_error($msg);
286
}
287
return FALSE;
288
}
289
290
return TRUE;
291
}
292
293
294
/**
295
* Move a file
296
*
297
* @param string
298
* @param string
299
* @return bool
300
*/
301
public function move($old_file, $new_file) {
302
return $this->rename($old_file, $new_file, TRUE);
303
}
304
305
306
/**
307
* Rename (or move) a file
308
*
309
* @param string
310
* @return bool
311
*/
312
public function delete_file($filepath) {
313
if ( ! $this->_is_conn()) {
314
return FALSE;
315
}
316
317
$result = @ftp_delete($this->conn_id, $filepath);
318
319
if ($result === FALSE) {
320
if ($this->debug == TRUE) {
321
$this->_error('ftp_unable_to_delete');
322
}
323
return FALSE;
324
}
325
326
return TRUE;
327
}
328
329
330
/**
331
* Delete a folder and recursively delete everything (including sub-folders)
332
* containted within it.
333
*
334
* @param string
335
* @return bool
336
*/
337
public function delete_dir($filepath) {
338
if ( ! $this->_is_conn()) {
339
return FALSE;
340
}
341
342
// Add a trailing slash to the file path if needed
343
$filepath = preg_replace("/(.+?)\/*$/", "\\1/", $filepath);
344
345
$list = $this->list_files($filepath);
346
347
if ($list !== FALSE && count($list) > 0) {
348
foreach ($list as $item) {
349
// If we can't delete the item it's probaly a folder so
350
// we'll recursively call delete_dir()
351
if ( ! @ftp_delete($this->conn_id, $item)) {
352
$this->delete_dir($item);
353
}
354
}
355
}
356
357
$result = @ftp_rmdir($this->conn_id, $filepath);
358
359
if ($result === FALSE) {
360
if ($this->debug == TRUE) {
361
$this->_error('ftp_unable_to_delete');
362
}
363
return FALSE;
364
}
365
366
return TRUE;
367
}
368
369
370
/**
371
* Set file permissions
372
*
373
* @param string the file path
374
* @param string the permissions
375
* @return bool
376
*/
377
public function chmod($path, $perm) {
378
if ( ! $this->_is_conn()) {
379
return FALSE;
380
}
381
382
// Permissions can only be set when running PHP 5
383
if ( ! function_exists('ftp_chmod')) {
384
if ($this->debug == TRUE) {
385
$this->_error('ftp_unable_to_chmod');
386
}
387
return FALSE;
388
}
389
390
$result = @ftp_chmod($this->conn_id, $perm, $path);
391
392
if ($result === FALSE) {
393
if ($this->debug == TRUE) {
394
$this->_error('ftp_unable_to_chmod');
395
}
396
return FALSE;
397
}
398
399
return TRUE;
400
}
401
402
403
/**
404
* FTP List files in the specified directory
405
*
406
* @return array
407
*/
408
public function list_files($path = '.') {
409
if ( ! $this->_is_conn()) {
410
return FALSE;
411
}
412
413
return ftp_nlist($this->conn_id, $path);
414
}
415
416
417
/**
418
* Read a directory and recreate it remotely
419
*
420
* This function recursively reads a local folder and everything it contains (including
421
* sub-folders) and creates a mirror via FTP based on it. Whatever the directory structure
422
* of the original file path will be recreated on the server.
423
*
424
* @param string path to source with trailing slash
425
* @param string path to destination - include the base folder with trailing slash
426
* @return bool
427
*/
428
public function mirror($locpath, $rempath) {
429
if ( ! $this->_is_conn()) {
430
return FALSE;
431
}
432
433
// Open the local file path
434
if ($fp = @opendir($locpath)) {
435
// Attempt to open the remote file path.
436
if ( ! $this->changedir($rempath, TRUE)) {
437
// If it doesn't exist we'll attempt to create the direcotory
438
if ( ! $this->mkdir($rempath) || ! $this->changedir($rempath)) {
439
return FALSE;
440
}
441
}
442
443
// Recursively read the local directory
444
while (($file = readdir($fp)) !== FALSE) {
445
if (@is_dir($locpath.$file) && substr($file, 0, 1) != '.') {
446
$this->mirror($locpath.$file."/", $rempath.$file."/");
447
} elseif (substr($file, 0, 1) != ".") {
448
// Get the file extension so we can se the upload type
449
$ext = $this->_getext($file);
450
$mode = $this->_settype($ext);
451
452
$this->upload($locpath.$file, $rempath.$file, $mode);
453
}
454
}
455
return TRUE;
456
}
457
458
return FALSE;
459
}
460
461
462
/**
463
* Extract the file extension
464
*
465
* @param string
466
* @return string
467
*/
468
private function _getext($filename) {
469
if (strpos($filename, '.') === FALSE) {
470
return 'txt';
471
}
472
473
$x = explode('.', $filename);
474
return end($x);
475
}
476
477
478
/**
479
* Set the upload type
480
*
481
* @param string
482
* @return string
483
*/
484
private function _settype($ext) {
485
$text_types = array(
486
'txt',
487
'text',
488
'php',
489
'phps',
490
'php4',
491
'js',
492
'css',
493
'htm',
494
'html',
495
'phtml',
496
'shtml',
497
'log',
498
'xml'
499
);
500
501
return (in_array($ext, $text_types)) ? 'ascii' : 'binary';
502
}
503
504
505
/**
506
* Close the connection
507
*
508
* @param string path to source
509
* @param string path to destination
510
* @return bool
511
*/
512
public function close() {
513
if ( ! $this->_is_conn()) {
514
return FALSE;
515
}
516
517
@ftp_close($this->conn_id);
518
}
519
520
521
/**
522
* Display error message
523
*
524
* @param string
525
* @return bool
526
*/
527
private function _error($msg) {
528
echo isset($this->_error_messages[$msg]) ? $this->_error_messages[$msg] : $msg;
529
}
530
531
}
532
533
/* End of file: ./system/libraries/ftp/ftp_library.php */
Page URI: http://www.infopotato.com/index.php/code/library/ftp/
