blob: a0c6895bfa2521d87c1c05a166d10d36bfed9c38 [file] [log] [blame]
admin29932c22006-10-26 23:03:43 +00001<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * Code Igniter
4 *
5 * An open source application development framework for PHP 4.3.2 or newer
6 *
7 * @package CodeIgniter
8 * @author Rick Ellis
9 * @copyright Copyright (c) 2006, pMachine, Inc.
10 * @license http://www.codeignitor.com/user_guide/license.html
11 * @link http://www.codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
19 * FTP Class
20 *
21 * @package CodeIgniter
22 * @subpackage Libraries
23 * @category Libraries
24 * @author Rick Ellis
25 * @link http://www.codeigniter.com/user_guide/libraries/encryption.html
26 */
27class CI_FTP {
28
29 var $hostname = '';
30 var $username = '';
31 var $password = '';
32 var $port = 21;
33 var $passive = TRUE;
admin29932c22006-10-26 23:03:43 +000034 var $debug = FALSE;
35 var $conn_id;
36
37
admin29932c22006-10-26 23:03:43 +000038 /**
39 * Constructor - Sets Preferences
40 *
41 * The constructor can be passed an array of config values
42 */
43 function CI_FTP($config = array())
44 {
45 if (count($config) > 0)
46 {
47 $this->initialize($config);
48 }
49
50 log_message('debug', "FTP Class Initialized");
51 }
52
53 // --------------------------------------------------------------------
54
55 /**
56 * Initialize preferences
57 *
58 * @access public
59 * @param array
60 * @return void
61 */
62 function initialize($config = array())
63 {
64 foreach ($config as $key => $val)
65 {
66 if (isset($this->$key))
67 {
68 $this->$key = $val;
69 }
70 }
71
admin58e3d022006-10-26 23:33:11 +000072 // Prep the hostname
73 $this->hostname = preg_replace('|.+?://|', '', $this->hostname);
admin29932c22006-10-26 23:03:43 +000074 }
75
76 // --------------------------------------------------------------------
77
78 /**
79 * FTP Connect
80 *
81 * @access public
admin631f17b2006-10-27 07:41:28 +000082 * @param array the connection values
83 * @param bool whether to use a secure or standard connection
admin29932c22006-10-26 23:03:43 +000084 * @return bool
85 */
admin631f17b2006-10-27 07:41:28 +000086 function connect($config = array(), $secure = FALSE)
87 {
88 if (count($config) > 0)
89 {
90 $this->initialize($config);
91 }
92
93 $method = ($secure == FALSE) ? 'ftp_connect' : 'ftp_ssl_connect';
admin29932c22006-10-26 23:03:43 +000094
95 if (FALSE === ($this->conn_id = @$method($this->hostname, $this->port)))
96 {
97 if ($this->debug == TRUE)
98 {
99 $this->_error('ftp_unable_to_connect');
100 }
101 return FALSE;
102 }
103
104 if ( ! $this->_login())
105 {
106 if ($this->debug == TRUE)
107 {
108 $this->_error('ftp_unable_to_login');
109 }
110 return FALSE;
111 }
112
admin58e3d022006-10-26 23:33:11 +0000113 // Set passive mode if needed
admin29932c22006-10-26 23:03:43 +0000114 if ($this->passive == TRUE)
115 {
116 ftp_pasv($this->conn_id, TRUE);
117 }
118
119 return TRUE;
120 }
admin631f17b2006-10-27 07:41:28 +0000121
122 // --------------------------------------------------------------------
123
124 /**
125 * Secure FTP Connect
126 *
127 * @access public
128 * @param array the connection values
129 * @return bool
130 */
131 function sconnect($config = array())
132 {
133 return $this->connect($config, TRUE);
134 }
admin29932c22006-10-26 23:03:43 +0000135
136 // --------------------------------------------------------------------
137
138 /**
139 * FTP Login
140 *
141 * @access private
142 * @return bool
143 */
144 function _login()
145 {
146 return @ftp_login($this->conn_id, $this->username, $this->password);
147 }
148
149 // --------------------------------------------------------------------
150
151 /**
admind7f88ca2006-10-27 06:34:06 +0000152 * Change direcotry
153 *
154 * The second parameter lets us momentarily turn off debugging so that
155 * this function can be used to test for the existance of a folder
156 * without throwing an error. There's no FTP equivalent to is_dir()
157 * so we do it by trying to change to a particular directory.
158 * Internally, this paramter is only used by the "mirror" function below.
admin29932c22006-10-26 23:03:43 +0000159 *
160 * @access public
161 * @param string
admind7f88ca2006-10-27 06:34:06 +0000162 * @param bool
admin29932c22006-10-26 23:03:43 +0000163 * @return array
164 */
admin58e3d022006-10-26 23:33:11 +0000165 function changedir($path = '', $supress_debug = FALSE)
admin29932c22006-10-26 23:03:43 +0000166 {
167 if ($path == '')
168 {
169 return FALSE;
170 }
171
admin29932c22006-10-26 23:03:43 +0000172 $result = @ftp_chdir($this->conn_id, $path);
173
174 if ($result === FALSE)
175 {
admin58e3d022006-10-26 23:33:11 +0000176 if ($this->debug == TRUE AND $supress_debug != TRUE)
admin29932c22006-10-26 23:03:43 +0000177 {
178 $this->_error('ftp_unable_to_changedir');
179 }
180 return FALSE;
181 }
182
183 return TRUE;
admin29932c22006-10-26 23:03:43 +0000184 }
185
186 // --------------------------------------------------------------------
187
188 /**
189 * Create a directory
190 *
191 * @access public
192 * @param string
193 * @return array
194 */
195 function mkdir($path = '')
196 {
197 if ($path == '')
198 {
199 return FALSE;
200 }
201
202 $result = @ftp_mkdir($this->conn_id, $path);
203
204 if ($result === FALSE)
205 {
206 if ($this->debug == TRUE)
207 {
208 $this->_error('ftp_unable_to_makdir');
209 }
210 return FALSE;
211 }
212
213 return TRUE;
214 }
215
216 // --------------------------------------------------------------------
217
218 /**
219 * Upload a file to the server
220 *
221 * @access public
222 * @param string
223 * @param string
224 * @param string
225 * @return array
226 */
admin58e3d022006-10-26 23:33:11 +0000227 function upload($locpath, $rempath, $mode = 'auto', $permissions = NULL)
admin29932c22006-10-26 23:03:43 +0000228 {
229 if ( ! file_exists($locpath))
230 {
231 $this->_error('ftp_no_source_file');
admin29932c22006-10-26 23:03:43 +0000232 return FALSE;
233 }
234
admin58e3d022006-10-26 23:33:11 +0000235 // Set the mode if not specified
236 if ($mode == 'auto')
237 {
238 // Get the file extension so we can se the upload type
239 $ext = $this->_getext($locpath);
240 $mode = $this->_settype($ext);
241 }
242
admin29932c22006-10-26 23:03:43 +0000243 $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;
admin58e3d022006-10-26 23:33:11 +0000244
admin29932c22006-10-26 23:03:43 +0000245 $result = @ftp_put($this->conn_id, $rempath, $locpath, $mode);
246
247 if ($result === FALSE)
248 {
249 if ($this->debug == TRUE)
250 {
251 $this->_error('ftp_unable_to_upload');
252 }
253 return FALSE;
254 }
255
admin58e3d022006-10-26 23:33:11 +0000256 // Set file permissions if needed
admin29932c22006-10-26 23:03:43 +0000257 if ( ! is_null($permissions))
258 {
259 $this->chmod($rempath, (int)$permissions);
260 }
261
262 return TRUE;
263 }
264
265 // --------------------------------------------------------------------
266
267 /**
268 * Set file permissions
269 *
270 * @access public
271 * @param string the file path
272 * @param string the permissions
273 * @return array
274 */
275 function chmod($path, $perm)
admind7f88ca2006-10-27 06:34:06 +0000276 {
277 // Permissions can only be set when running PHP 5
278 if ( ! function_exists('ftp_chmod'))
279 {
280 if ($this->debug == TRUE)
281 {
282 $this->_error('ftp_unable_to_chmod');
283 }
284 return FALSE;
285 }
286
admin29932c22006-10-26 23:03:43 +0000287 $result = @ftp_chmod($this->conn_id, $perm, $path);
288
289 if ($result === FALSE)
290 {
291 if ($this->debug == TRUE)
292 {
293 $this->_error('ftp_unable_to_chmod');
294 }
295 return FALSE;
296 }
297
298 return TRUE;
299 }
300
301 // --------------------------------------------------------------------
302
303 /**
304 * FTP List files in the specified directory
305 *
306 * @access public
307 * @return array
308 */
admind7f88ca2006-10-27 06:34:06 +0000309 function list_files($path = '.')
admin29932c22006-10-26 23:03:43 +0000310 {
311 return ftp_nlist($this->conn_id, $path);
312 }
313
314 // ------------------------------------------------------------------------
315
316 /**
admin58e3d022006-10-26 23:33:11 +0000317 * Read a directory and recreate it remotely
admin29932c22006-10-26 23:03:43 +0000318 *
319 * This function recursively reads a folder and everything it contains (including
admin631f17b2006-10-27 07:41:28 +0000320 * sub-folders) and creates a mirror via FTP based on it. Whatever the directory structure
321 * of the original file path will be recreated on the server.
admin29932c22006-10-26 23:03:43 +0000322 *
323 * @access public
admind7f88ca2006-10-27 06:34:06 +0000324 * @param string path to source with trailing slash
325 * @param string path to destination - include the base folder with trailing slash
admin29932c22006-10-26 23:03:43 +0000326 * @return bool
327 */
328 function mirror($locpath, $rempath)
329 {
330 // Open the local file path
331 if ($fp = @opendir($locpath))
332 {
333 // Attempt to open the remote file path.
admin58e3d022006-10-26 23:33:11 +0000334 if ( ! $this->changedir($rempath, TRUE))
admin29932c22006-10-26 23:03:43 +0000335 {
336 // If it doesn't exist we'll attempt to create the direcotory
337 if ( ! $this->mkdir($rempath) OR ! $this->changedir($rempath))
338 {
339 return FALSE;
340 }
341 }
342
343 // Recursively read the local directory
344 while (FALSE !== ($file = readdir($fp)))
345 {
346 if (@is_dir($locpath.$file) && substr($file, 0, 1) != '.')
347 {
348 $this->mirror($locpath.$file."/", $rempath.$file."/");
349 }
350 elseif (substr($file, 0, 1) != ".")
351 {
admin58e3d022006-10-26 23:33:11 +0000352 // Get the file extension so we can se the upload type
353 $ext = $this->_getext($file);
354 $mode = $this->_settype($ext);
355
admin29932c22006-10-26 23:03:43 +0000356 $this->upload($locpath.$file, $rempath.$file, $mode);
357 }
358 }
359 return TRUE;
360 }
361
362 return FALSE;
363 }
364
admin58e3d022006-10-26 23:33:11 +0000365
366 // --------------------------------------------------------------------
367
368 /**
369 * Extract the file extension
370 *
371 * @access private
372 * @param string
373 * @return string
374 */
375 function _getext($filename)
376 {
377 if (FALSE === strpos($filename, '.'))
378 {
379 return 'txt';
380 }
381
382 $x = explode('.', $filename);
383 return end($x);
384 }
385
386
387 // --------------------------------------------------------------------
388
389 /**
390 * Set the upload type
391 *
392 * @access private
393 * @param string
394 * @return string
395 */
396 function _settype($ext)
397 {
398 $text_types = array(
399 'txt',
400 'text',
401 'php',
402 'phps',
403 'php4',
404 'js',
405 'css',
406 'htm',
407 'html',
408 'phtml',
409 'shtml',
410 'log',
411 'xml'
412 );
413
414
415 return (in_array($ext, $text_types)) ? 'ascii' : 'binary';
416 }
417
admin29932c22006-10-26 23:03:43 +0000418 // ------------------------------------------------------------------------
419
420 /**
421 * Close the connection
422 *
423 * @access public
424 * @param string path to source
425 * @param string path to destination
426 * @return bool
427 */
428 function close()
429 {
430 @ftp_close($this->conn_id);
431 }
432
433 // ------------------------------------------------------------------------
434
435 /**
436 * Display error message
437 *
438 * @access private
439 * @param string
440 * @return bool
441 */
442 function _error($line)
443 {
444 $CI =& get_instance();
445 $CI->lang->load('ftp');
446 show_error($CI->lang->line($line));
447 }
448
449
450}
admin58e3d022006-10-26 23:33:11 +0000451// END FTP Class
admin29932c22006-10-26 23:03:43 +0000452?>