blob: 6c1bad8e1ffdac1441e1a77ead4418bf16ec200d [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;
34 var $secure = FALSE;
35 var $debug = FALSE;
36 var $conn_id;
37
38
admin29932c22006-10-26 23:03:43 +000039 /**
40 * Constructor - Sets Preferences
41 *
42 * The constructor can be passed an array of config values
43 */
44 function CI_FTP($config = array())
45 {
46 if (count($config) > 0)
47 {
48 $this->initialize($config);
49 }
50
51 log_message('debug', "FTP Class Initialized");
52 }
53
54 // --------------------------------------------------------------------
55
56 /**
57 * Initialize preferences
58 *
59 * @access public
60 * @param array
61 * @return void
62 */
63 function initialize($config = array())
64 {
65 foreach ($config as $key => $val)
66 {
67 if (isset($this->$key))
68 {
69 $this->$key = $val;
70 }
71 }
72
admin58e3d022006-10-26 23:33:11 +000073 // Prep the hostname
74 $this->hostname = preg_replace('|.+?://|', '', $this->hostname);
admin29932c22006-10-26 23:03:43 +000075 }
76
77 // --------------------------------------------------------------------
78
79 /**
80 * FTP Connect
81 *
82 * @access public
83 * @return bool
84 */
85 function connect()
86 {
87 $method = ($this->secure == FALSE) ? 'ftp_connect' : 'ftp_ssl_connect';
88
89 if (FALSE === ($this->conn_id = @$method($this->hostname, $this->port)))
90 {
91 if ($this->debug == TRUE)
92 {
93 $this->_error('ftp_unable_to_connect');
94 }
95 return FALSE;
96 }
97
98 if ( ! $this->_login())
99 {
100 if ($this->debug == TRUE)
101 {
102 $this->_error('ftp_unable_to_login');
103 }
104 return FALSE;
105 }
106
admin58e3d022006-10-26 23:33:11 +0000107 // Set passive mode if needed
admin29932c22006-10-26 23:03:43 +0000108 if ($this->passive == TRUE)
109 {
110 ftp_pasv($this->conn_id, TRUE);
111 }
112
113 return TRUE;
114 }
115
116 // --------------------------------------------------------------------
117
118 /**
119 * FTP Login
120 *
121 * @access private
122 * @return bool
123 */
124 function _login()
125 {
126 return @ftp_login($this->conn_id, $this->username, $this->password);
127 }
128
129 // --------------------------------------------------------------------
130
131 /**
admind7f88ca2006-10-27 06:34:06 +0000132 * Change direcotry
133 *
134 * The second parameter lets us momentarily turn off debugging so that
135 * this function can be used to test for the existance of a folder
136 * without throwing an error. There's no FTP equivalent to is_dir()
137 * so we do it by trying to change to a particular directory.
138 * Internally, this paramter is only used by the "mirror" function below.
admin29932c22006-10-26 23:03:43 +0000139 *
140 * @access public
141 * @param string
admind7f88ca2006-10-27 06:34:06 +0000142 * @param bool
admin29932c22006-10-26 23:03:43 +0000143 * @return array
144 */
admin58e3d022006-10-26 23:33:11 +0000145 function changedir($path = '', $supress_debug = FALSE)
admin29932c22006-10-26 23:03:43 +0000146 {
147 if ($path == '')
148 {
149 return FALSE;
150 }
151
admin29932c22006-10-26 23:03:43 +0000152 $result = @ftp_chdir($this->conn_id, $path);
153
154 if ($result === FALSE)
155 {
admin58e3d022006-10-26 23:33:11 +0000156 if ($this->debug == TRUE AND $supress_debug != TRUE)
admin29932c22006-10-26 23:03:43 +0000157 {
158 $this->_error('ftp_unable_to_changedir');
159 }
160 return FALSE;
161 }
162
163 return TRUE;
admin29932c22006-10-26 23:03:43 +0000164 }
165
166 // --------------------------------------------------------------------
167
168 /**
169 * Create a directory
170 *
171 * @access public
172 * @param string
173 * @return array
174 */
175 function mkdir($path = '')
176 {
177 if ($path == '')
178 {
179 return FALSE;
180 }
181
182 $result = @ftp_mkdir($this->conn_id, $path);
183
184 if ($result === FALSE)
185 {
186 if ($this->debug == TRUE)
187 {
188 $this->_error('ftp_unable_to_makdir');
189 }
190 return FALSE;
191 }
192
193 return TRUE;
194 }
195
196 // --------------------------------------------------------------------
197
198 /**
199 * Upload a file to the server
200 *
201 * @access public
202 * @param string
203 * @param string
204 * @param string
205 * @return array
206 */
admin58e3d022006-10-26 23:33:11 +0000207 function upload($locpath, $rempath, $mode = 'auto', $permissions = NULL)
admin29932c22006-10-26 23:03:43 +0000208 {
209 if ( ! file_exists($locpath))
210 {
211 $this->_error('ftp_no_source_file');
admin29932c22006-10-26 23:03:43 +0000212 return FALSE;
213 }
214
admin58e3d022006-10-26 23:33:11 +0000215 // Set the mode if not specified
216 if ($mode == 'auto')
217 {
218 // Get the file extension so we can se the upload type
219 $ext = $this->_getext($locpath);
220 $mode = $this->_settype($ext);
221 }
222
admin29932c22006-10-26 23:03:43 +0000223 $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;
admin58e3d022006-10-26 23:33:11 +0000224
admin29932c22006-10-26 23:03:43 +0000225 $result = @ftp_put($this->conn_id, $rempath, $locpath, $mode);
226
227 if ($result === FALSE)
228 {
229 if ($this->debug == TRUE)
230 {
231 $this->_error('ftp_unable_to_upload');
232 }
233 return FALSE;
234 }
235
admin58e3d022006-10-26 23:33:11 +0000236 // Set file permissions if needed
admin29932c22006-10-26 23:03:43 +0000237 if ( ! is_null($permissions))
238 {
239 $this->chmod($rempath, (int)$permissions);
240 }
241
242 return TRUE;
243 }
244
245 // --------------------------------------------------------------------
246
247 /**
248 * Set file permissions
249 *
250 * @access public
251 * @param string the file path
252 * @param string the permissions
253 * @return array
254 */
255 function chmod($path, $perm)
admind7f88ca2006-10-27 06:34:06 +0000256 {
257 // Permissions can only be set when running PHP 5
258 if ( ! function_exists('ftp_chmod'))
259 {
260 if ($this->debug == TRUE)
261 {
262 $this->_error('ftp_unable_to_chmod');
263 }
264 return FALSE;
265 }
266
admin29932c22006-10-26 23:03:43 +0000267 $result = @ftp_chmod($this->conn_id, $perm, $path);
268
269 if ($result === FALSE)
270 {
271 if ($this->debug == TRUE)
272 {
273 $this->_error('ftp_unable_to_chmod');
274 }
275 return FALSE;
276 }
277
278 return TRUE;
279 }
280
281 // --------------------------------------------------------------------
282
283 /**
284 * FTP List files in the specified directory
285 *
286 * @access public
287 * @return array
288 */
admind7f88ca2006-10-27 06:34:06 +0000289 function list_files($path = '.')
admin29932c22006-10-26 23:03:43 +0000290 {
291 return ftp_nlist($this->conn_id, $path);
292 }
293
294 // ------------------------------------------------------------------------
295
296 /**
admin58e3d022006-10-26 23:33:11 +0000297 * Read a directory and recreate it remotely
admin29932c22006-10-26 23:03:43 +0000298 *
299 * This function recursively reads a folder and everything it contains (including
300 * sub-folders) and creates a mirror via FTP based on it. Whatever directory structure
301 * is in the original file path will be recreated in the zip file.
302 *
303 * @access public
admind7f88ca2006-10-27 06:34:06 +0000304 * @param string path to source with trailing slash
305 * @param string path to destination - include the base folder with trailing slash
admin29932c22006-10-26 23:03:43 +0000306 * @return bool
307 */
308 function mirror($locpath, $rempath)
309 {
310 // Open the local file path
311 if ($fp = @opendir($locpath))
312 {
313 // Attempt to open the remote file path.
admin58e3d022006-10-26 23:33:11 +0000314 if ( ! $this->changedir($rempath, TRUE))
admin29932c22006-10-26 23:03:43 +0000315 {
316 // If it doesn't exist we'll attempt to create the direcotory
317 if ( ! $this->mkdir($rempath) OR ! $this->changedir($rempath))
318 {
319 return FALSE;
320 }
321 }
322
323 // Recursively read the local directory
324 while (FALSE !== ($file = readdir($fp)))
325 {
326 if (@is_dir($locpath.$file) && substr($file, 0, 1) != '.')
327 {
328 $this->mirror($locpath.$file."/", $rempath.$file."/");
329 }
330 elseif (substr($file, 0, 1) != ".")
331 {
admin58e3d022006-10-26 23:33:11 +0000332 // Get the file extension so we can se the upload type
333 $ext = $this->_getext($file);
334 $mode = $this->_settype($ext);
335
admin29932c22006-10-26 23:03:43 +0000336 $this->upload($locpath.$file, $rempath.$file, $mode);
337 }
338 }
339 return TRUE;
340 }
341
342 return FALSE;
343 }
344
admin58e3d022006-10-26 23:33:11 +0000345
346 // --------------------------------------------------------------------
347
348 /**
349 * Extract the file extension
350 *
351 * @access private
352 * @param string
353 * @return string
354 */
355 function _getext($filename)
356 {
357 if (FALSE === strpos($filename, '.'))
358 {
359 return 'txt';
360 }
361
362 $x = explode('.', $filename);
363 return end($x);
364 }
365
366
367 // --------------------------------------------------------------------
368
369 /**
370 * Set the upload type
371 *
372 * @access private
373 * @param string
374 * @return string
375 */
376 function _settype($ext)
377 {
378 $text_types = array(
379 'txt',
380 'text',
381 'php',
382 'phps',
383 'php4',
384 'js',
385 'css',
386 'htm',
387 'html',
388 'phtml',
389 'shtml',
390 'log',
391 'xml'
392 );
393
394
395 return (in_array($ext, $text_types)) ? 'ascii' : 'binary';
396 }
397
admin29932c22006-10-26 23:03:43 +0000398 // ------------------------------------------------------------------------
399
400 /**
401 * Close the connection
402 *
403 * @access public
404 * @param string path to source
405 * @param string path to destination
406 * @return bool
407 */
408 function close()
409 {
410 @ftp_close($this->conn_id);
411 }
412
413 // ------------------------------------------------------------------------
414
415 /**
416 * Display error message
417 *
418 * @access private
419 * @param string
420 * @return bool
421 */
422 function _error($line)
423 {
424 $CI =& get_instance();
425 $CI->lang->load('ftp');
426 show_error($CI->lang->line($line));
427 }
428
429
430}
admin58e3d022006-10-26 23:33:11 +0000431// END FTP Class
admin29932c22006-10-26 23:03:43 +0000432?>