PageRenderTime 207ms CodeModel.GetById 100ms app.highlight 15ms RepoModel.GetById 86ms app.codeStats 0ms

/system/libraries/Ftp.php

https://bitbucket.org/nanomites_webdev/heroframework
PHP | 660 lines | 319 code | 93 blank | 248 comment | 72 complexity | c0d5ee1a88549ec27663c66eb8076835 MD5 | raw file
  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 */