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