upgrade to codeigniter 1.7.2 for f12
[www-register-wizard.git] / libraries / Ftp.php
1 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2 /**
3  * CodeIgniter
4  *
5  * An open source application development framework for PHP 4.3.2 or newer
6  *
7  * @package             CodeIgniter
8  * @author              ExpressionEngine Dev Team
9  * @copyright   Copyright (c) 2008 - 2009, EllisLab, Inc.
10  * @license             http://codeigniter.com/user_guide/license.html
11  * @link                http://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              ExpressionEngine Dev Team
25  * @link                http://codeigniter.com/user_guide/libraries/ftp.html
26  */
27 class CI_FTP {
28
29         var $hostname   = '';
30         var $username   = '';
31         var $password   = '';
32         var $port               = 21;
33         var $passive    = TRUE;
34         var $debug              = FALSE;
35         var $conn_id    = FALSE;
36
37
38         /**
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
72                 // Prep the hostname
73                 $this->hostname = preg_replace('|.+?://|', '', $this->hostname);
74         }
75
76         // --------------------------------------------------------------------
77
78         /**
79          * FTP Connect
80          *
81          * @access      public
82          * @param       array    the connection values
83          * @return      bool
84          */
85         function connect($config = array())
86         {
87                 if (count($config) > 0)
88                 {
89                         $this->initialize($config);
90                 }
91
92                 if (FALSE === ($this->conn_id = @ftp_connect($this->hostname, $this->port)))
93                 {
94                         if ($this->debug == TRUE)
95                         {
96                                 $this->_error('ftp_unable_to_connect');
97                         }
98                         return FALSE;
99                 }
100
101                 if ( ! $this->_login())
102                 {
103                         if ($this->debug == TRUE)
104                         {
105                                 $this->_error('ftp_unable_to_login');
106                         }
107                         return FALSE;
108                 }
109
110                 // Set passive mode if needed
111                 if ($this->passive == TRUE)
112                 {
113                         ftp_pasv($this->conn_id, TRUE);
114                 }
115
116                 return TRUE;
117         }
118
119         // --------------------------------------------------------------------
120
121         /**
122          * FTP Login
123          *
124          * @access      private
125          * @return      bool
126          */
127         function _login()
128         {
129                 return @ftp_login($this->conn_id, $this->username, $this->password);
130         }
131
132         // --------------------------------------------------------------------
133
134         /**
135          * Validates the connection ID
136          *
137          * @access      private
138          * @return      bool
139          */
140         function _is_conn()
141         {
142                 if ( ! is_resource($this->conn_id))
143                 {
144                         if ($this->debug == TRUE)
145                         {
146                                 $this->_error('ftp_no_connection');
147                         }
148                         return FALSE;
149                 }
150                 return TRUE;
151         }
152
153         // --------------------------------------------------------------------
154
155
156         /**
157          * Change directory
158          *
159          * The second parameter lets us momentarily turn off debugging so that
160          * this function can be used to test for the existence of a folder
161          * without throwing an error.  There's no FTP equivalent to is_dir()
162          * so we do it by trying to change to a particular directory.
163          * Internally, this parameter is only used by the "mirror" function below.
164          *
165          * @access      public
166          * @param       string
167          * @param       bool
168          * @return      bool
169          */
170         function changedir($path = '', $supress_debug = FALSE)
171         {
172                 if ($path == '' OR ! $this->_is_conn())
173                 {
174                         return FALSE;
175                 }
176
177                 $result = @ftp_chdir($this->conn_id, $path);
178
179                 if ($result === FALSE)
180                 {
181                         if ($this->debug == TRUE AND $supress_debug == FALSE)
182                         {
183                                 $this->_error('ftp_unable_to_changedir');
184                         }
185                         return FALSE;
186                 }
187
188                 return TRUE;
189         }
190
191         // --------------------------------------------------------------------
192
193         /**
194          * Create a directory
195          *
196          * @access      public
197          * @param       string
198          * @return      bool
199          */
200         function mkdir($path = '', $permissions = NULL)
201         {
202                 if ($path == '' OR ! $this->_is_conn())
203                 {
204                         return FALSE;
205                 }
206
207                 $result = @ftp_mkdir($this->conn_id, $path);
208
209                 if ($result === FALSE)
210                 {
211                         if ($this->debug == TRUE)
212                         {
213                                 $this->_error('ftp_unable_to_makdir');
214                         }
215                         return FALSE;
216                 }
217
218                 // Set file permissions if needed
219                 if ( ! is_null($permissions))
220                 {
221                         $this->chmod($path, (int)$permissions);
222                 }
223
224                 return TRUE;
225         }
226
227         // --------------------------------------------------------------------
228
229         /**
230          * Upload a file to the server
231          *
232          * @access      public
233          * @param       string
234          * @param       string
235          * @param       string
236          * @return      bool
237          */
238         function upload($locpath, $rempath, $mode = 'auto', $permissions = NULL)
239         {
240                 if ( ! $this->_is_conn())
241                 {
242                         return FALSE;
243                 }
244
245                 if ( ! file_exists($locpath))
246                 {
247                         $this->_error('ftp_no_source_file');
248                         return FALSE;
249                 }
250
251                 // Set the mode if not specified
252                 if ($mode == 'auto')
253                 {
254                         // Get the file extension so we can set the upload type
255                         $ext = $this->_getext($locpath);
256                         $mode = $this->_settype($ext);
257                 }
258
259                 $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;
260
261                 $result = @ftp_put($this->conn_id, $rempath, $locpath, $mode);
262
263                 if ($result === FALSE)
264                 {
265                         if ($this->debug == TRUE)
266                         {
267                                 $this->_error('ftp_unable_to_upload');
268                         }
269                         return FALSE;
270                 }
271
272                 // Set file permissions if needed
273                 if ( ! is_null($permissions))
274                 {
275                         $this->chmod($rempath, (int)$permissions);
276                 }
277
278                 return TRUE;
279         }
280
281         // --------------------------------------------------------------------
282
283         /**
284          * Rename (or move) a file
285          *
286          * @access      public
287          * @param       string
288          * @param       string
289          * @param       bool
290          * @return      bool
291          */
292         function rename($old_file, $new_file, $move = FALSE)
293         {
294                 if ( ! $this->_is_conn())
295                 {
296                         return FALSE;
297                 }
298
299                 $result = @ftp_rename($this->conn_id, $old_file, $new_file);
300
301                 if ($result === FALSE)
302                 {
303                         if ($this->debug == TRUE)
304                         {
305                                 $msg = ($move == FALSE) ? 'ftp_unable_to_rename' : 'ftp_unable_to_move';
306
307                                 $this->_error($msg);
308                         }
309                         return FALSE;
310                 }
311
312                 return TRUE;
313         }
314
315         // --------------------------------------------------------------------
316
317         /**
318          * Move a file
319          *
320          * @access      public
321          * @param       string
322          * @param       string
323          * @return      bool
324          */
325         function move($old_file, $new_file)
326         {
327                 return $this->rename($old_file, $new_file, TRUE);
328         }
329
330         // --------------------------------------------------------------------
331
332         /**
333          * Rename (or move) a file
334          *
335          * @access      public
336          * @param       string
337          * @return      bool
338          */
339         function delete_file($filepath)
340         {
341                 if ( ! $this->_is_conn())
342                 {
343                         return FALSE;
344                 }
345
346                 $result = @ftp_delete($this->conn_id, $filepath);
347
348                 if ($result === FALSE)
349                 {
350                         if ($this->debug == TRUE)
351                         {
352                                 $this->_error('ftp_unable_to_delete');
353                         }
354                         return FALSE;
355                 }
356
357                 return TRUE;
358         }
359
360         // --------------------------------------------------------------------
361
362         /**
363          * Delete a folder and recursively delete everything (including sub-folders)
364          * containted within it.
365          *
366          * @access      public
367          * @param       string
368          * @return      bool
369          */
370         function delete_dir($filepath)
371         {
372                 if ( ! $this->_is_conn())
373                 {
374                         return FALSE;
375                 }
376
377                 // Add a trailing slash to the file path if needed
378                 $filepath = preg_replace("/(.+?)\/*$/", "\\1/",  $filepath);
379
380                 $list = $this->list_files($filepath);
381
382                 if ($list !== FALSE AND count($list) > 0)
383                 {
384                         foreach ($list as $item)
385                         {
386                                 // If we can't delete the item it's probaly a folder so
387                                 // we'll recursively call delete_dir()
388                                 if ( ! @ftp_delete($this->conn_id, $item))
389                                 {
390                                         $this->delete_dir($item);
391                                 }
392                         }
393                 }
394
395                 $result = @ftp_rmdir($this->conn_id, $filepath);
396
397                 if ($result === FALSE)
398                 {
399                         if ($this->debug == TRUE)
400                         {
401                                 $this->_error('ftp_unable_to_delete');
402                         }
403                         return FALSE;
404                 }
405
406                 return TRUE;
407         }
408
409         // --------------------------------------------------------------------
410
411         /**
412          * Set file permissions
413          *
414          * @access      public
415          * @param       string  the file path
416          * @param       string  the permissions
417          * @return      bool
418          */
419         function chmod($path, $perm)
420         {
421                 if ( ! $this->_is_conn())
422                 {
423                         return FALSE;
424                 }
425
426                 // Permissions can only be set when running PHP 5
427                 if ( ! function_exists('ftp_chmod'))
428                 {
429                         if ($this->debug == TRUE)
430                         {
431                                 $this->_error('ftp_unable_to_chmod');
432                         }
433                         return FALSE;
434                 }
435
436                 $result = @ftp_chmod($this->conn_id, $perm, $path);
437
438                 if ($result === FALSE)
439                 {
440                         if ($this->debug == TRUE)
441                         {
442                                 $this->_error('ftp_unable_to_chmod');
443                         }
444                         return FALSE;
445                 }
446
447                 return TRUE;
448         }
449
450         // --------------------------------------------------------------------
451
452         /**
453          * FTP List files in the specified directory
454          *
455          * @access      public
456          * @return      array
457          */
458         function list_files($path = '.')
459         {
460                 if ( ! $this->_is_conn())
461                 {
462                         return FALSE;
463                 }
464
465                 return ftp_nlist($this->conn_id, $path);
466         }
467
468         // ------------------------------------------------------------------------
469
470         /**
471          * Read a directory and recreate it remotely
472          *
473          * This function recursively reads a folder and everything it contains (including
474          * sub-folders) and creates a mirror via FTP based on it.  Whatever the directory structure
475          * of the original file path will be recreated on the server.
476          *
477          * @access      public
478          * @param       string  path to source with trailing slash
479          * @param       string  path to destination - include the base folder with trailing slash
480          * @return      bool
481          */
482         function mirror($locpath, $rempath)
483         {
484                 if ( ! $this->_is_conn())
485                 {
486                         return FALSE;
487                 }
488
489                 // Open the local file path
490                 if ($fp = @opendir($locpath))
491                 {
492                         // Attempt to open the remote file path.
493                         if ( ! $this->changedir($rempath, TRUE))
494                         {
495                                 // If it doesn't exist we'll attempt to create the direcotory
496                                 if ( ! $this->mkdir($rempath) OR ! $this->changedir($rempath))
497                                 {
498                                         return FALSE;
499                                 }
500                         }
501
502                         // Recursively read the local directory
503                         while (FALSE !== ($file = readdir($fp)))
504                         {
505                                 if (@is_dir($locpath.$file) && substr($file, 0, 1) != '.')
506                                 {
507                                         $this->mirror($locpath.$file."/", $rempath.$file."/");
508                                 }
509                                 elseif (substr($file, 0, 1) != ".")
510                                 {
511                                         // Get the file extension so we can se the upload type
512                                         $ext = $this->_getext($file);
513                                         $mode = $this->_settype($ext);
514
515                                         $this->upload($locpath.$file, $rempath.$file, $mode);
516                                 }
517                         }
518                         return TRUE;
519                 }
520
521                 return FALSE;
522         }
523
524
525         // --------------------------------------------------------------------
526
527         /**
528          * Extract the file extension
529          *
530          * @access      private
531          * @param       string
532          * @return      string
533          */
534         function _getext($filename)
535         {
536                 if (FALSE === strpos($filename, '.'))
537                 {
538                         return 'txt';
539                 }
540
541                 $x = explode('.', $filename);
542                 return end($x);
543         }
544
545
546         // --------------------------------------------------------------------
547
548         /**
549          * Set the upload type
550          *
551          * @access      private
552          * @param       string
553          * @return      string
554          */
555         function _settype($ext)
556         {
557                 $text_types = array(
558                                                         'txt',
559                                                         'text',
560                                                         'php',
561                                                         'phps',
562                                                         'php4',
563                                                         'js',
564                                                         'css',
565                                                         'htm',
566                                                         'html',
567                                                         'phtml',
568                                                         'shtml',
569                                                         'log',
570                                                         'xml'
571                                                         );
572
573
574                 return (in_array($ext, $text_types)) ? 'ascii' : 'binary';
575         }
576
577         // ------------------------------------------------------------------------
578
579         /**
580          * Close the connection
581          *
582          * @access      public
583          * @param       string  path to source
584          * @param       string  path to destination
585          * @return      bool
586          */
587         function close()
588         {
589                 if ( ! $this->_is_conn())
590                 {
591                         return FALSE;
592                 }
593
594                 @ftp_close($this->conn_id);
595         }
596
597         // ------------------------------------------------------------------------
598
599         /**
600          * Display error message
601          *
602          * @access      private
603          * @param       string
604          * @return      bool
605          */
606         function _error($line)
607         {
608                 $CI =& get_instance();
609                 $CI->lang->load('ftp');
610                 show_error($CI->lang->line($line));
611         }
612
613
614 }
615 // END FTP Class
616
617 /* End of file Ftp.php */
618 /* Location: ./system/libraries/Ftp.php */