blob: 2885b550f6dd0033a8eaab072e943fad11f97b67 [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02005 * An open source application development framework for PHP
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +02007 * This content is released under the MIT License (MIT)
Andrey Andreev0a75d6e2011-12-22 19:45:33 +02008 *
Andrey Andreevcce6bd12018-01-09 11:32:02 +02009 * Copyright (c) 2014 - 2018, British Columbia Institute of Technology
Andrey Andreev0a75d6e2011-12-22 19:45:33 +020010 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020011 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
Derek Jonesf4a4bd82011-10-20 12:18:42 -050017 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020018 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
28 *
29 * @package CodeIgniter
30 * @author EllisLab Dev Team
Andrey Andreev1924e872016-01-11 12:55:34 +020031 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
Andrey Andreevcce6bd12018-01-09 11:32:02 +020032 * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020033 * @license http://opensource.org/licenses/MIT MIT License
Andrey Andreevbd202c92016-01-11 12:50:18 +020034 * @link https://codeigniter.com
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020035 * @since Version 1.0.0
Derek Allard2067d1a2008-11-13 22:59:24 +000036 * @filesource
37 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020038defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000039
Derek Allard2067d1a2008-11-13 22:59:24 +000040/**
41 * FTP Class
42 *
43 * @package CodeIgniter
44 * @subpackage Libraries
45 * @category Libraries
Derek Jonesf4a4bd82011-10-20 12:18:42 -050046 * @author EllisLab Dev Team
Andrey Andreevbd202c92016-01-11 12:50:18 +020047 * @link https://codeigniter.com/user_guide/libraries/ftp.html
Derek Allard2067d1a2008-11-13 22:59:24 +000048 */
49class CI_FTP {
50
Andrey Andreev597ea272012-11-01 22:56:26 +020051 /**
52 * FTP Server hostname
53 *
54 * @var string
55 */
Andrey Andreeve52e4262014-02-21 17:11:54 +020056 public $hostname = '';
Andrey Andreev597ea272012-11-01 22:56:26 +020057
58 /**
59 * FTP Username
60 *
61 * @var string
62 */
Andrey Andreeve52e4262014-02-21 17:11:54 +020063 public $username = '';
Andrey Andreev597ea272012-11-01 22:56:26 +020064
65 /**
66 * FTP Password
67 *
68 * @var string
69 */
Andrey Andreeve52e4262014-02-21 17:11:54 +020070 public $password = '';
Andrey Andreev597ea272012-11-01 22:56:26 +020071
72 /**
73 * FTP Server port
74 *
75 * @var int
76 */
Andrey Andreeve52e4262014-02-21 17:11:54 +020077 public $port = 21;
Andrey Andreev597ea272012-11-01 22:56:26 +020078
79 /**
80 * Passive mode flag
81 *
82 * @var bool
83 */
Andrey Andreeve52e4262014-02-21 17:11:54 +020084 public $passive = TRUE;
Andrey Andreev597ea272012-11-01 22:56:26 +020085
86 /**
87 * Debug flag
88 *
89 * Specifies whether to display error messages.
90 *
91 * @var bool
92 */
Andrey Andreeve52e4262014-02-21 17:11:54 +020093 public $debug = FALSE;
94
95 // --------------------------------------------------------------------
Andrey Andreev597ea272012-11-01 22:56:26 +020096
97 /**
Andrey Andreeve52e4262014-02-21 17:11:54 +020098 * Connection ID
Andrey Andreev597ea272012-11-01 22:56:26 +020099 *
100 * @var resource
101 */
Andrey Andreeve52e4262014-02-21 17:11:54 +0200102 protected $conn_id;
Derek Allard2067d1a2008-11-13 22:59:24 +0000103
Andrey Andreev597ea272012-11-01 22:56:26 +0200104 // --------------------------------------------------------------------
105
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300106 /**
107 * Constructor
108 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200109 * @param array $config
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300110 * @return void
111 */
Greg Akera9263282010-11-10 15:26:43 -0600112 public function __construct($config = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000113 {
Andrey Andreeve52e4262014-02-21 17:11:54 +0200114 empty($config) OR $this->initialize($config);
Andrey Andreev90726b82015-01-20 12:39:22 +0200115 log_message('info', 'FTP Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000116 }
117
118 // --------------------------------------------------------------------
119
120 /**
121 * Initialize preferences
122 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200123 * @param array $config
Derek Allard2067d1a2008-11-13 22:59:24 +0000124 * @return void
125 */
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200126 public function initialize($config = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000127 {
128 foreach ($config as $key => $val)
129 {
130 if (isset($this->$key))
131 {
132 $this->$key = $val;
133 }
134 }
135
136 // Prep the hostname
137 $this->hostname = preg_replace('|.+?://|', '', $this->hostname);
138 }
139
140 // --------------------------------------------------------------------
141
142 /**
143 * FTP Connect
144 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200145 * @param array $config Connection values
Derek Allard2067d1a2008-11-13 22:59:24 +0000146 * @return bool
147 */
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200148 public function connect($config = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000149 {
150 if (count($config) > 0)
151 {
152 $this->initialize($config);
153 }
154
155 if (FALSE === ($this->conn_id = @ftp_connect($this->hostname, $this->port)))
156 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100157 if ($this->debug === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000158 {
159 $this->_error('ftp_unable_to_connect');
160 }
Andrey Andreev382b5132014-02-26 18:41:59 +0200161
Derek Allard2067d1a2008-11-13 22:59:24 +0000162 return FALSE;
163 }
164
165 if ( ! $this->_login())
166 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100167 if ($this->debug === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000168 {
169 $this->_error('ftp_unable_to_login');
170 }
Andrey Andreev382b5132014-02-26 18:41:59 +0200171
Derek Allard2067d1a2008-11-13 22:59:24 +0000172 return FALSE;
173 }
174
175 // Set passive mode if needed
Alex Bilbied261b1e2012-06-02 11:12:16 +0100176 if ($this->passive === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000177 {
178 ftp_pasv($this->conn_id, TRUE);
179 }
180
181 return TRUE;
182 }
183
184 // --------------------------------------------------------------------
185
186 /**
187 * FTP Login
188 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000189 * @return bool
190 */
Andrey Andreevc4d979c2012-03-26 14:53:00 +0300191 protected function _login()
Derek Allard2067d1a2008-11-13 22:59:24 +0000192 {
193 return @ftp_login($this->conn_id, $this->username, $this->password);
194 }
195
196 // --------------------------------------------------------------------
197
198 /**
199 * Validates the connection ID
200 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000201 * @return bool
202 */
Andrey Andreevc4d979c2012-03-26 14:53:00 +0300203 protected function _is_conn()
Derek Allard2067d1a2008-11-13 22:59:24 +0000204 {
205 if ( ! is_resource($this->conn_id))
206 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100207 if ($this->debug === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000208 {
209 $this->_error('ftp_no_connection');
210 }
Andrey Andreeve52e4262014-02-21 17:11:54 +0200211
Derek Allard2067d1a2008-11-13 22:59:24 +0000212 return FALSE;
213 }
Andrey Andreeve52e4262014-02-21 17:11:54 +0200214
Derek Allard2067d1a2008-11-13 22:59:24 +0000215 return TRUE;
216 }
217
218 // --------------------------------------------------------------------
219
Derek Allard2067d1a2008-11-13 22:59:24 +0000220 /**
Derek Allarda14ab122009-07-13 12:01:01 +0000221 * Change directory
Derek Allard2067d1a2008-11-13 22:59:24 +0000222 *
223 * The second parameter lets us momentarily turn off debugging so that
Derek Allarda14ab122009-07-13 12:01:01 +0000224 * this function can be used to test for the existence of a folder
Andrey Andreevc4d979c2012-03-26 14:53:00 +0300225 * without throwing an error. There's no FTP equivalent to is_dir()
Derek Allard2067d1a2008-11-13 22:59:24 +0000226 * so we do it by trying to change to a particular directory.
Derek Allarda14ab122009-07-13 12:01:01 +0000227 * Internally, this parameter is only used by the "mirror" function below.
Derek Allard2067d1a2008-11-13 22:59:24 +0000228 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200229 * @param string $path
Andrey Andreevb4c62182014-01-03 17:39:26 +0200230 * @param bool $suppress_debug
Derek Allard2067d1a2008-11-13 22:59:24 +0000231 * @return bool
232 */
Andrey Andreevb4c62182014-01-03 17:39:26 +0200233 public function changedir($path, $suppress_debug = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000234 {
Andrey Andreev45549a22014-01-06 13:55:38 +0200235 if ( ! $this->_is_conn())
Derek Allard2067d1a2008-11-13 22:59:24 +0000236 {
237 return FALSE;
238 }
239
240 $result = @ftp_chdir($this->conn_id, $path);
241
242 if ($result === FALSE)
243 {
Andrey Andreevb4c62182014-01-03 17:39:26 +0200244 if ($this->debug === TRUE && $suppress_debug === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000245 {
246 $this->_error('ftp_unable_to_changedir');
247 }
Andrey Andreeve52e4262014-02-21 17:11:54 +0200248
Derek Allard2067d1a2008-11-13 22:59:24 +0000249 return FALSE;
250 }
251
252 return TRUE;
253 }
254
255 // --------------------------------------------------------------------
256
257 /**
258 * Create a directory
259 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200260 * @param string $path
261 * @param int $permissions
Derek Allard2067d1a2008-11-13 22:59:24 +0000262 * @return bool
263 */
Andrey Andreev430b14c2014-01-03 17:31:26 +0200264 public function mkdir($path, $permissions = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000265 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100266 if ($path === '' OR ! $this->_is_conn())
Derek Allard2067d1a2008-11-13 22:59:24 +0000267 {
268 return FALSE;
269 }
270
271 $result = @ftp_mkdir($this->conn_id, $path);
272
273 if ($result === FALSE)
274 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100275 if ($this->debug === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000276 {
Andrey Andreevb4c62182014-01-03 17:39:26 +0200277 $this->_error('ftp_unable_to_mkdir');
Derek Allard2067d1a2008-11-13 22:59:24 +0000278 }
Andrey Andreeve52e4262014-02-21 17:11:54 +0200279
Derek Allard2067d1a2008-11-13 22:59:24 +0000280 return FALSE;
281 }
282
283 // Set file permissions if needed
vlakoff1228fe22013-01-14 01:30:09 +0100284 if ($permissions !== NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000285 {
Andrey Andreevc4d979c2012-03-26 14:53:00 +0300286 $this->chmod($path, (int) $permissions);
Derek Allard2067d1a2008-11-13 22:59:24 +0000287 }
288
289 return TRUE;
290 }
291
292 // --------------------------------------------------------------------
293
294 /**
295 * Upload a file to the server
296 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200297 * @param string $locpath
298 * @param string $rempath
299 * @param string $mode
300 * @param int $permissions
Derek Allard2067d1a2008-11-13 22:59:24 +0000301 * @return bool
302 */
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200303 public function upload($locpath, $rempath, $mode = 'auto', $permissions = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000304 {
305 if ( ! $this->_is_conn())
306 {
307 return FALSE;
308 }
309
310 if ( ! file_exists($locpath))
311 {
312 $this->_error('ftp_no_source_file');
313 return FALSE;
314 }
315
316 // Set the mode if not specified
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200317 if ($mode === 'auto')
Derek Allard2067d1a2008-11-13 22:59:24 +0000318 {
319 // Get the file extension so we can set the upload type
320 $ext = $this->_getext($locpath);
321 $mode = $this->_settype($ext);
322 }
323
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200324 $mode = ($mode === 'ascii') ? FTP_ASCII : FTP_BINARY;
Derek Allard2067d1a2008-11-13 22:59:24 +0000325
326 $result = @ftp_put($this->conn_id, $rempath, $locpath, $mode);
327
328 if ($result === FALSE)
329 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100330 if ($this->debug === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000331 {
332 $this->_error('ftp_unable_to_upload');
333 }
Andrey Andreeve52e4262014-02-21 17:11:54 +0200334
Derek Allard2067d1a2008-11-13 22:59:24 +0000335 return FALSE;
336 }
337
338 // Set file permissions if needed
vlakoff1228fe22013-01-14 01:30:09 +0100339 if ($permissions !== NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000340 {
Andrey Andreevc4d979c2012-03-26 14:53:00 +0300341 $this->chmod($rempath, (int) $permissions);
Derek Allard2067d1a2008-11-13 22:59:24 +0000342 }
343
344 return TRUE;
345 }
346
347 // --------------------------------------------------------------------
348
349 /**
Phil Sturgeon28b29372010-03-12 00:43:28 +0000350 * Download a file from a remote server to the local server
351 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200352 * @param string $rempath
353 * @param string $locpath
354 * @param string $mode
Phil Sturgeon28b29372010-03-12 00:43:28 +0000355 * @return bool
356 */
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200357 public function download($rempath, $locpath, $mode = 'auto')
Phil Sturgeon28b29372010-03-12 00:43:28 +0000358 {
359 if ( ! $this->_is_conn())
360 {
361 return FALSE;
362 }
Barry Mienydd671972010-10-04 16:33:58 +0200363
Phil Sturgeon28b29372010-03-12 00:43:28 +0000364 // Set the mode if not specified
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200365 if ($mode === 'auto')
Phil Sturgeon28b29372010-03-12 00:43:28 +0000366 {
367 // Get the file extension so we can set the upload type
368 $ext = $this->_getext($rempath);
369 $mode = $this->_settype($ext);
370 }
Barry Mienydd671972010-10-04 16:33:58 +0200371
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200372 $mode = ($mode === 'ascii') ? FTP_ASCII : FTP_BINARY;
Barry Mienydd671972010-10-04 16:33:58 +0200373
Phil Sturgeon28b29372010-03-12 00:43:28 +0000374 $result = @ftp_get($this->conn_id, $locpath, $rempath, $mode);
375
376 if ($result === FALSE)
377 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100378 if ($this->debug === TRUE)
Phil Sturgeon28b29372010-03-12 00:43:28 +0000379 {
380 $this->_error('ftp_unable_to_download');
381 }
Andrey Andreeve52e4262014-02-21 17:11:54 +0200382
Barry Mienydd671972010-10-04 16:33:58 +0200383 return FALSE;
Phil Sturgeon28b29372010-03-12 00:43:28 +0000384 }
Barry Mienydd671972010-10-04 16:33:58 +0200385
Phil Sturgeon28b29372010-03-12 00:43:28 +0000386 return TRUE;
Barry Mienydd671972010-10-04 16:33:58 +0200387 }
Phil Sturgeon28b29372010-03-12 00:43:28 +0000388
389 // --------------------------------------------------------------------
390
391 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000392 * Rename (or move) a file
393 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200394 * @param string $old_file
395 * @param string $new_file
396 * @param bool $move
Derek Allard2067d1a2008-11-13 22:59:24 +0000397 * @return bool
398 */
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200399 public function rename($old_file, $new_file, $move = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000400 {
401 if ( ! $this->_is_conn())
402 {
403 return FALSE;
404 }
405
406 $result = @ftp_rename($this->conn_id, $old_file, $new_file);
407
408 if ($result === FALSE)
409 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100410 if ($this->debug === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000411 {
Andrey Andreev3ca060a2013-11-27 16:30:31 +0200412 $this->_error('ftp_unable_to_'.($move === FALSE ? 'rename' : 'move'));
Derek Allard2067d1a2008-11-13 22:59:24 +0000413 }
Andrey Andreeve52e4262014-02-21 17:11:54 +0200414
Derek Allard2067d1a2008-11-13 22:59:24 +0000415 return FALSE;
416 }
417
418 return TRUE;
419 }
420
421 // --------------------------------------------------------------------
422
423 /**
424 * Move a file
425 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200426 * @param string $old_file
427 * @param string $new_file
Derek Allard2067d1a2008-11-13 22:59:24 +0000428 * @return bool
429 */
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200430 public function move($old_file, $new_file)
Derek Allard2067d1a2008-11-13 22:59:24 +0000431 {
432 return $this->rename($old_file, $new_file, TRUE);
433 }
434
435 // --------------------------------------------------------------------
436
437 /**
438 * Rename (or move) a file
439 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200440 * @param string $filepath
Derek Allard2067d1a2008-11-13 22:59:24 +0000441 * @return bool
442 */
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200443 public function delete_file($filepath)
Derek Allard2067d1a2008-11-13 22:59:24 +0000444 {
445 if ( ! $this->_is_conn())
446 {
447 return FALSE;
448 }
449
450 $result = @ftp_delete($this->conn_id, $filepath);
451
452 if ($result === FALSE)
453 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100454 if ($this->debug === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000455 {
456 $this->_error('ftp_unable_to_delete');
457 }
Andrey Andreeve52e4262014-02-21 17:11:54 +0200458
Derek Allard2067d1a2008-11-13 22:59:24 +0000459 return FALSE;
460 }
461
462 return TRUE;
463 }
464
465 // --------------------------------------------------------------------
466
467 /**
468 * Delete a folder and recursively delete everything (including sub-folders)
Calvin Tam55bc5052015-07-24 02:27:24 -0700469 * contained within it.
Derek Allard2067d1a2008-11-13 22:59:24 +0000470 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200471 * @param string $filepath
Derek Allard2067d1a2008-11-13 22:59:24 +0000472 * @return bool
473 */
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200474 public function delete_dir($filepath)
Derek Allard2067d1a2008-11-13 22:59:24 +0000475 {
476 if ( ! $this->_is_conn())
477 {
478 return FALSE;
479 }
480
481 // Add a trailing slash to the file path if needed
Andrey Andreev838a9d62012-12-03 14:37:47 +0200482 $filepath = preg_replace('/(.+?)\/*$/', '\\1/', $filepath);
Derek Allard2067d1a2008-11-13 22:59:24 +0000483
484 $list = $this->list_files($filepath);
Andrey Andreevffe8ade2014-02-17 18:51:48 +0200485 if ( ! empty($list))
Derek Allard2067d1a2008-11-13 22:59:24 +0000486 {
Andrey Andreevffe8ade2014-02-17 18:51:48 +0200487 for ($i = 0, $c = count($list); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000488 {
Andrey Andreev71d8f722017-01-17 12:01:00 +0200489 // If we can't delete the item it's probably a directory,
Andrey Andreevffe8ade2014-02-17 18:51:48 +0200490 // so we'll recursively call delete_dir()
Andrey Andreev72daa192014-04-09 23:45:02 +0300491 if ( ! preg_match('#/\.\.?$#', $list[$i]) && ! @ftp_delete($this->conn_id, $list[$i]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000492 {
Andrey Andreevd3913f52015-04-20 14:47:00 +0300493 $this->delete_dir($filepath.$list[$i]);
Derek Allard2067d1a2008-11-13 22:59:24 +0000494 }
495 }
496 }
497
Andrey Andreevffe8ade2014-02-17 18:51:48 +0200498 if (@ftp_rmdir($this->conn_id, $filepath) === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000499 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100500 if ($this->debug === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000501 {
502 $this->_error('ftp_unable_to_delete');
503 }
Andrey Andreevffe8ade2014-02-17 18:51:48 +0200504
Derek Allard2067d1a2008-11-13 22:59:24 +0000505 return FALSE;
506 }
507
508 return TRUE;
509 }
510
511 // --------------------------------------------------------------------
512
513 /**
514 * Set file permissions
515 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200516 * @param string $path File path
517 * @param int $perm Permissions
Derek Allard2067d1a2008-11-13 22:59:24 +0000518 * @return bool
519 */
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200520 public function chmod($path, $perm)
Derek Allard2067d1a2008-11-13 22:59:24 +0000521 {
522 if ( ! $this->_is_conn())
523 {
524 return FALSE;
525 }
526
Andrey Andreevffe8ade2014-02-17 18:51:48 +0200527 if (@ftp_chmod($this->conn_id, $perm, $path) === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000528 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100529 if ($this->debug === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000530 {
531 $this->_error('ftp_unable_to_chmod');
532 }
Andrey Andreevffe8ade2014-02-17 18:51:48 +0200533
Derek Allard2067d1a2008-11-13 22:59:24 +0000534 return FALSE;
535 }
536
537 return TRUE;
538 }
539
540 // --------------------------------------------------------------------
541
542 /**
543 * FTP List files in the specified directory
544 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200545 * @param string $path
Derek Allard2067d1a2008-11-13 22:59:24 +0000546 * @return array
547 */
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200548 public function list_files($path = '.')
Derek Allard2067d1a2008-11-13 22:59:24 +0000549 {
Andrey Andreevffe8ade2014-02-17 18:51:48 +0200550 return $this->_is_conn()
551 ? ftp_nlist($this->conn_id, $path)
552 : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000553 }
554
555 // ------------------------------------------------------------------------
556
557 /**
558 * Read a directory and recreate it remotely
559 *
Andrey Andreevc4d979c2012-03-26 14:53:00 +0300560 * This function recursively reads a folder and everything it contains
561 * (including sub-folders) and creates a mirror via FTP based on it.
562 * Whatever the directory structure of the original file path will be
563 * recreated on the server.
Derek Allard2067d1a2008-11-13 22:59:24 +0000564 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200565 * @param string $locpath Path to source with trailing slash
566 * @param string $rempath Path to destination - include the base folder with trailing slash
Derek Allard2067d1a2008-11-13 22:59:24 +0000567 * @return bool
568 */
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200569 public function mirror($locpath, $rempath)
Derek Allard2067d1a2008-11-13 22:59:24 +0000570 {
571 if ( ! $this->_is_conn())
572 {
573 return FALSE;
574 }
575
576 // Open the local file path
577 if ($fp = @opendir($locpath))
578 {
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200579 // Attempt to open the remote file path and try to create it, if it doesn't exist
Andrey Andreevc4d979c2012-03-26 14:53:00 +0300580 if ( ! $this->changedir($rempath, TRUE) && ( ! $this->mkdir($rempath) OR ! $this->changedir($rempath)))
Derek Allard2067d1a2008-11-13 22:59:24 +0000581 {
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200582 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000583 }
584
585 // Recursively read the local directory
586 while (FALSE !== ($file = readdir($fp)))
587 {
Andrey Andreev382b5132014-02-26 18:41:59 +0200588 if (is_dir($locpath.$file) && $file[0] !== '.')
Derek Allard2067d1a2008-11-13 22:59:24 +0000589 {
Andrey Andreevc4d979c2012-03-26 14:53:00 +0300590 $this->mirror($locpath.$file.'/', $rempath.$file.'/');
Derek Allard2067d1a2008-11-13 22:59:24 +0000591 }
Andrey Andreevc4d979c2012-03-26 14:53:00 +0300592 elseif ($file[0] !== '.')
Derek Allard2067d1a2008-11-13 22:59:24 +0000593 {
594 // Get the file extension so we can se the upload type
595 $ext = $this->_getext($file);
596 $mode = $this->_settype($ext);
597
598 $this->upload($locpath.$file, $rempath.$file, $mode);
599 }
600 }
Andrey Andreevffe8ade2014-02-17 18:51:48 +0200601
Derek Allard2067d1a2008-11-13 22:59:24 +0000602 return TRUE;
603 }
604
605 return FALSE;
606 }
607
Derek Allard2067d1a2008-11-13 22:59:24 +0000608 // --------------------------------------------------------------------
609
610 /**
611 * Extract the file extension
612 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200613 * @param string $filename
Derek Allard2067d1a2008-11-13 22:59:24 +0000614 * @return string
615 */
Andrey Andreevc4d979c2012-03-26 14:53:00 +0300616 protected function _getext($filename)
Derek Allard2067d1a2008-11-13 22:59:24 +0000617 {
Andrey Andreeve52e4262014-02-21 17:11:54 +0200618 return (($dot = strrpos($filename, '.')) === FALSE)
619 ? 'txt'
620 : substr($filename, $dot + 1);
Derek Allard2067d1a2008-11-13 22:59:24 +0000621 }
622
Derek Allard2067d1a2008-11-13 22:59:24 +0000623 // --------------------------------------------------------------------
624
625 /**
626 * Set the upload type
627 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200628 * @param string $ext Filename extension
Derek Allard2067d1a2008-11-13 22:59:24 +0000629 * @return string
630 */
Andrey Andreevc4d979c2012-03-26 14:53:00 +0300631 protected function _settype($ext)
Derek Allard2067d1a2008-11-13 22:59:24 +0000632 {
Andrey Andreeve52e4262014-02-21 17:11:54 +0200633 return in_array($ext, array('txt', 'text', 'php', 'phps', 'php4', 'js', 'css', 'htm', 'html', 'phtml', 'shtml', 'log', 'xml'), TRUE)
634 ? 'ascii'
635 : 'binary';
Derek Allard2067d1a2008-11-13 22:59:24 +0000636 }
637
638 // ------------------------------------------------------------------------
639
640 /**
641 * Close the connection
642 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000643 * @return bool
644 */
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200645 public function close()
Derek Allard2067d1a2008-11-13 22:59:24 +0000646 {
Andrey Andreevffe8ade2014-02-17 18:51:48 +0200647 return $this->_is_conn()
648 ? @ftp_close($this->conn_id)
649 : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000650 }
651
652 // ------------------------------------------------------------------------
653
654 /**
655 * Display error message
656 *
Andrey Andreev597ea272012-11-01 22:56:26 +0200657 * @param string $line
Andrey Andreev0a75d6e2011-12-22 19:45:33 +0200658 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000659 */
Andrey Andreevc4d979c2012-03-26 14:53:00 +0300660 protected function _error($line)
Derek Allard2067d1a2008-11-13 22:59:24 +0000661 {
662 $CI =& get_instance();
663 $CI->lang->load('ftp');
664 show_error($CI->lang->line($line));
665 }
666
Derek Allard2067d1a2008-11-13 22:59:24 +0000667}