source: sourcecode/system/libraries/Ftp.php @ 1

Last change on this file since 1 was 1, checked in by dungnv, 11 years ago
File size: 12.3 KB
Line 
1<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP 5.1.6 or newer
6 *
7 * @package             CodeIgniter
8 * @author              ExpressionEngine Dev Team
9 * @copyright   Copyright (c) 2008 - 2011, 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 */
27class 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        public function __construct($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         * Download a file from a remote server to the local server
285         *
286         * @access      public
287         * @param       string
288         * @param       string
289         * @param       string
290         * @return      bool
291         */
292        function download($rempath, $locpath, $mode = 'auto')
293        {
294                if ( ! $this->_is_conn())
295                {
296                        return FALSE;
297                }
298
299                // Set the mode if not specified
300                if ($mode == 'auto')
301                {
302                        // Get the file extension so we can set the upload type
303                        $ext = $this->_getext($rempath);
304                        $mode = $this->_settype($ext);
305                }
306
307                $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;
308
309                $result = @ftp_get($this->conn_id, $locpath, $rempath, $mode);
310
311                if ($result === FALSE)
312                {
313                        if ($this->debug == TRUE)
314                        {
315                                $this->_error('ftp_unable_to_download');
316                        }
317                        return FALSE;
318                }
319
320                return TRUE;
321        }
322
323        // --------------------------------------------------------------------
324
325        /**
326         * Rename (or move) a file
327         *
328         * @access      public
329         * @param       string
330         * @param       string
331         * @param       bool
332         * @return      bool
333         */
334        function rename($old_file, $new_file, $move = FALSE)
335        {
336                if ( ! $this->_is_conn())
337                {
338                        return FALSE;
339                }
340
341                $result = @ftp_rename($this->conn_id, $old_file, $new_file);
342
343                if ($result === FALSE)
344                {
345                        if ($this->debug == TRUE)
346                        {
347                                $msg = ($move == FALSE) ? 'ftp_unable_to_rename' : 'ftp_unable_to_move';
348
349                                $this->_error($msg);
350                        }
351                        return FALSE;
352                }
353
354                return TRUE;
355        }
356
357        // --------------------------------------------------------------------
358
359        /**
360         * Move a file
361         *
362         * @access      public
363         * @param       string
364         * @param       string
365         * @return      bool
366         */
367        function move($old_file, $new_file)
368        {
369                return $this->rename($old_file, $new_file, TRUE);
370        }
371
372        // --------------------------------------------------------------------
373
374        /**
375         * Rename (or move) a file
376         *
377         * @access      public
378         * @param       string
379         * @return      bool
380         */
381        function delete_file($filepath)
382        {
383                if ( ! $this->_is_conn())
384                {
385                        return FALSE;
386                }
387
388                $result = @ftp_delete($this->conn_id, $filepath);
389
390                if ($result === FALSE)
391                {
392                        if ($this->debug == TRUE)
393                        {
394                                $this->_error('ftp_unable_to_delete');
395                        }
396                        return FALSE;
397                }
398
399                return TRUE;
400        }
401
402        // --------------------------------------------------------------------
403
404        /**
405         * Delete a folder and recursively delete everything (including sub-folders)
406         * containted within it.
407         *
408         * @access      public
409         * @param       string
410         * @return      bool
411         */
412        function delete_dir($filepath)
413        {
414                if ( ! $this->_is_conn())
415                {
416                        return FALSE;
417                }
418
419                // Add a trailing slash to the file path if needed
420                $filepath = preg_replace("/(.+?)\/*$/", "\\1/",  $filepath);
421
422                $list = $this->list_files($filepath);
423
424                if ($list !== FALSE AND count($list) > 0)
425                {
426                        foreach ($list as $item)
427                        {
428                                // If we can't delete the item it's probaly a folder so
429                                // we'll recursively call delete_dir()
430                                if ( ! @ftp_delete($this->conn_id, $item))
431                                {
432                                        $this->delete_dir($item);
433                                }
434                        }
435                }
436
437                $result = @ftp_rmdir($this->conn_id, $filepath);
438
439                if ($result === FALSE)
440                {
441                        if ($this->debug == TRUE)
442                        {
443                                $this->_error('ftp_unable_to_delete');
444                        }
445                        return FALSE;
446                }
447
448                return TRUE;
449        }
450
451        // --------------------------------------------------------------------
452
453        /**
454         * Set file permissions
455         *
456         * @access      public
457         * @param       string  the file path
458         * @param       string  the permissions
459         * @return      bool
460         */
461        function chmod($path, $perm)
462        {
463                if ( ! $this->_is_conn())
464                {
465                        return FALSE;
466                }
467
468                // Permissions can only be set when running PHP 5
469                if ( ! function_exists('ftp_chmod'))
470                {
471                        if ($this->debug == TRUE)
472                        {
473                                $this->_error('ftp_unable_to_chmod');
474                        }
475                        return FALSE;
476                }
477
478                $result = @ftp_chmod($this->conn_id, $perm, $path);
479
480                if ($result === FALSE)
481                {
482                        if ($this->debug == TRUE)
483                        {
484                                $this->_error('ftp_unable_to_chmod');
485                        }
486                        return FALSE;
487                }
488
489                return TRUE;
490        }
491
492        // --------------------------------------------------------------------
493
494        /**
495         * FTP List files in the specified directory
496         *
497         * @access      public
498         * @return      array
499         */
500        function list_files($path = '.')
501        {
502                if ( ! $this->_is_conn())
503                {
504                        return FALSE;
505                }
506
507                return ftp_nlist($this->conn_id, $path);
508        }
509
510        // ------------------------------------------------------------------------
511
512        /**
513         * Read a directory and recreate it remotely
514         *
515         * This function recursively reads a folder and everything it contains (including
516         * sub-folders) and creates a mirror via FTP based on it.  Whatever the directory structure
517         * of the original file path will be recreated on the server.
518         *
519         * @access      public
520         * @param       string  path to source with trailing slash
521         * @param       string  path to destination - include the base folder with trailing slash
522         * @return      bool
523         */
524        function mirror($locpath, $rempath)
525        {
526                if ( ! $this->_is_conn())
527                {
528                        return FALSE;
529                }
530
531                // Open the local file path
532                if ($fp = @opendir($locpath))
533                {
534                        // Attempt to open the remote file path.
535                        if ( ! $this->changedir($rempath, TRUE))
536                        {
537                                // If it doesn't exist we'll attempt to create the direcotory
538                                if ( ! $this->mkdir($rempath) OR ! $this->changedir($rempath))
539                                {
540                                        return FALSE;
541                                }
542                        }
543
544                        // Recursively read the local directory
545                        while (FALSE !== ($file = readdir($fp)))
546                        {
547                                if (@is_dir($locpath.$file) && substr($file, 0, 1) != '.')
548                                {
549                                        $this->mirror($locpath.$file."/", $rempath.$file."/");
550                                }
551                                elseif (substr($file, 0, 1) != ".")
552                                {
553                                        // Get the file extension so we can se the upload type
554                                        $ext = $this->_getext($file);
555                                        $mode = $this->_settype($ext);
556
557                                        $this->upload($locpath.$file, $rempath.$file, $mode);
558                                }
559                        }
560                        return TRUE;
561                }
562
563                return FALSE;
564        }
565
566
567        // --------------------------------------------------------------------
568
569        /**
570         * Extract the file extension
571         *
572         * @access      private
573         * @param       string
574         * @return      string
575         */
576        function _getext($filename)
577        {
578                if (FALSE === strpos($filename, '.'))
579                {
580                        return 'txt';
581                }
582
583                $x = explode('.', $filename);
584                return end($x);
585        }
586
587
588        // --------------------------------------------------------------------
589
590        /**
591         * Set the upload type
592         *
593         * @access      private
594         * @param       string
595         * @return      string
596         */
597        function _settype($ext)
598        {
599                $text_types = array(
600                                                        'txt',
601                                                        'text',
602                                                        'php',
603                                                        'phps',
604                                                        'php4',
605                                                        'js',
606                                                        'css',
607                                                        'htm',
608                                                        'html',
609                                                        'phtml',
610                                                        'shtml',
611                                                        'log',
612                                                        'xml'
613                                                        );
614
615
616                return (in_array($ext, $text_types)) ? 'ascii' : 'binary';
617        }
618
619        // ------------------------------------------------------------------------
620
621        /**
622         * Close the connection
623         *
624         * @access      public
625         * @param       string  path to source
626         * @param       string  path to destination
627         * @return      bool
628         */
629        function close()
630        {
631                if ( ! $this->_is_conn())
632                {
633                        return FALSE;
634                }
635
636                @ftp_close($this->conn_id);
637        }
638
639        // ------------------------------------------------------------------------
640
641        /**
642         * Display error message
643         *
644         * @access      private
645         * @param       string
646         * @return      bool
647         */
648        function _error($line)
649        {
650                $CI =& get_instance();
651                $CI->lang->load('ftp');
652                show_error($CI->lang->line($line));
653        }
654
655
656}
657// END FTP Class
658
659/* End of file Ftp.php */
660/* Location: ./system/libraries/Ftp.php */
Note: See TracBrowser for help on using the repository browser.