<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');


/**


 * CodeIgniter


 *


 * An open source application development framework for PHP 5.1.6 or newer


 *


 * @package		CodeIgniter


 * @author		EllisLab Dev Team


 * @copyright		Copyright (c) 2008 - 2014, EllisLab, Inc.


 * @copyright		Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)


 * @license		http://codeigniter.com/user_guide/license.html


 * @link		http://codeigniter.com


 * @since		Version 1.0


 * @filesource


 */





// ------------------------------------------------------------------------





/**


 * FTP Class


 *


 * @package		CodeIgniter


 * @subpackage	Libraries


 * @category	Libraries


 * @author		EllisLab Dev Team


 * @link		http://codeigniter.com/user_guide/libraries/ftp.html


 */


class CI_FTP {





	var $hostname	= '';


	var $username	= '';


	var $password	= '';


	var $port		= 21;


	var $passive	= TRUE;


	var $debug		= FALSE;


	var $conn_id	= FALSE;








	/**


	 * Constructor - Sets Preferences


	 *


	 * The constructor can be passed an array of config values


	 */


	public function __construct($config = array())


	{


		if (count($config) > 0)


		{


			$this->initialize($config);


		}





		log_message('debug', "FTP Class Initialized");


	}





	// --------------------------------------------------------------------





	/**


	 * Initialize preferences


	 *


	 * @access	public


	 * @param	array


	 * @return	void


	 */


	function initialize($config = array())


	{


		foreach ($config as $key => $val)


		{


			if (isset($this->$key))


			{


				$this->$key = $val;


			}


		}





		// Prep the hostname


		$this->hostname = preg_replace('|.+?://|', '', $this->hostname);


	}





	// --------------------------------------------------------------------





	/**


	 * FTP Connect


	 *


	 * @access	public


	 * @param	array	 the connection values


	 * @return	bool


	 */


	function connect($config = array())


	{


		if (count($config) > 0)


		{


			$this->initialize($config);


		}





		if (FALSE === ($this->conn_id = @ftp_connect($this->hostname, $this->port)))


		{


			if ($this->debug == TRUE)


			{


				$this->_error('ftp_unable_to_connect');


			}


			return FALSE;


		}





		if ( ! $this->_login())


		{


			if ($this->debug == TRUE)


			{


				$this->_error('ftp_unable_to_login');


			}


			return FALSE;


		}





		// Set passive mode if needed


		if ($this->passive == TRUE)


		{


			ftp_pasv($this->conn_id, TRUE);


		}





		return TRUE;


	}





	// --------------------------------------------------------------------





	/**


	 * FTP Login


	 *


	 * @access	private


	 * @return	bool


	 */


	function _login()


	{


		return @ftp_login($this->conn_id, $this->username, $this->password);


	}





	// --------------------------------------------------------------------





	/**


	 * Validates the connection ID


	 *


	 * @access	private


	 * @return	bool


	 */


	function _is_conn()


	{


		if ( ! is_resource($this->conn_id))


		{


			if ($this->debug == TRUE)


			{


				$this->_error('ftp_no_connection');


			}


			return FALSE;


		}


		return TRUE;


	}





	// --------------------------------------------------------------------








	/**


	 * Change directory


	 *


	 * The second parameter lets us momentarily turn off debugging so that


	 * this function can be used to test for the existence of a folder


	 * without throwing an error.  There's no FTP equivalent to is_dir()


	 * so we do it by trying to change to a particular directory.


	 * Internally, this parameter is only used by the "mirror" function below.


	 *


	 * @access	public


	 * @param	string


	 * @param	bool


	 * @return	bool


	 */


	function changedir($path = '', $supress_debug = FALSE)


	{


		if ($path == '' OR ! $this->_is_conn())


		{


			return FALSE;


		}





		$result = @ftp_chdir($this->conn_id, $path);





		if ($result === FALSE)


		{


			if ($this->debug == TRUE AND $supress_debug == FALSE)


			{


				$this->_error('ftp_unable_to_changedir');


			}


			return FALSE;


		}





		return TRUE;


	}





	// --------------------------------------------------------------------





	/**


	 * Create a directory


	 *


	 * @access	public


	 * @param	string


	 * @return	bool


	 */


	function mkdir($path = '', $permissions = NULL)


	{


		if ($path == '' OR ! $this->_is_conn())


		{


			return FALSE;


		}





		$result = @ftp_mkdir($this->conn_id, $path);





		if ($result === FALSE)


		{


			if ($this->debug == TRUE)


			{


				$this->_error('ftp_unable_to_makdir');


			}


			return FALSE;


		}





		// Set file permissions if needed


		if ( ! is_null($permissions))


		{


			$this->chmod($path, (int)$permissions);


		}





		return TRUE;


	}





	// --------------------------------------------------------------------





	/**


	 * Upload a file to the server


	 *


	 * @access	public


	 * @param	string


	 * @param	string


	 * @param	string


	 * @return	bool


	 */


	function upload($locpath, $rempath, $mode = 'auto', $permissions = NULL)


	{


		if ( ! $this->_is_conn())


		{


			return FALSE;


		}





		if ( ! file_exists($locpath))


		{


			$this->_error('ftp_no_source_file');


			return FALSE;


		}





		// Set the mode if not specified


		if ($mode == 'auto')


		{


			// Get the file extension so we can set the upload type


			$ext = $this->_getext($locpath);


			$mode = $this->_settype($ext);


		}





		$mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;





		$result = @ftp_put($this->conn_id, $rempath, $locpath, $mode);





		if ($result === FALSE)


		{


			if ($this->debug == TRUE)


			{


				$this->_error('ftp_unable_to_upload');


			}


			return FALSE;


		}





		// Set file permissions if needed


		if ( ! is_null($permissions))


		{


			$this->chmod($rempath, (int)$permissions);


		}





		return TRUE;


	}





	// --------------------------------------------------------------------





	/**


	 * Download a file from a remote server to the local server


	 *


	 * @access	public


	 * @param	string


	 * @param	string


	 * @param	string


	 * @return	bool


	 */


	function download($rempath, $locpath, $mode = 'auto')


	{


		if ( ! $this->_is_conn())


		{


			return FALSE;


		}





		// Set the mode if not specified


		if ($mode == 'auto')


		{


			// Get the file extension so we can set the upload type


			$ext = $this->_getext($rempath);


			$mode = $this->_settype($ext);


		}





		$mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;





		$result = @ftp_get($this->conn_id, $locpath, $rempath, $mode);





		if ($result === FALSE)


		{


			if ($this->debug == TRUE)


			{


				$this->_error('ftp_unable_to_download');


			}


			return FALSE;


		}





		return TRUE;


	}





	// --------------------------------------------------------------------





	/**


	 * Rename (or move) a file


	 *


	 * @access	public


	 * @param	string


	 * @param	string


	 * @param	bool


	 * @return	bool


	 */


	function rename($old_file, $new_file, $move = FALSE)


	{


		if ( ! $this->_is_conn())


		{


			return FALSE;


		}





		$result = @ftp_rename($this->conn_id, $old_file, $new_file);





		if ($result === FALSE)


		{


			if ($this->debug == TRUE)


			{


				$msg = ($move == FALSE) ? 'ftp_unable_to_rename' : 'ftp_unable_to_move';





				$this->_error($msg);


			}


			return FALSE;


		}





		return TRUE;


	}





	// --------------------------------------------------------------------





	/**


	 * Move a file


	 *


	 * @access	public


	 * @param	string


	 * @param	string


	 * @return	bool


	 */


	function move($old_file, $new_file)


	{


		return $this->rename($old_file, $new_file, TRUE);


	}





	// --------------------------------------------------------------------





	/**


	 * Rename (or move) a file


	 *


	 * @access	public


	 * @param	string


	 * @return	bool


	 */


	function delete_file($filepath)


	{


		if ( ! $this->_is_conn())


		{


			return FALSE;


		}





		$result = @ftp_delete($this->conn_id, $filepath);





		if ($result === FALSE)


		{


			if ($this->debug == TRUE)


			{


				$this->_error('ftp_unable_to_delete');


			}


			return FALSE;


		}





		return TRUE;


	}





	// --------------------------------------------------------------------





	/**


	 * Delete a folder and recursively delete everything (including sub-folders)


	 * containted within it.


	 *


	 * @access	public


	 * @param	string


	 * @return	bool


	 */


	function delete_dir($filepath)


	{


		if ( ! $this->_is_conn())


		{


			return FALSE;


		}





		// Add a trailing slash to the file path if needed


		$filepath = preg_replace("/(.+?)\/*$/", "\\1/",  $filepath);





		$list = $this->list_files($filepath);





		if ($list !== FALSE AND count($list) > 0)


		{


			foreach ($list as $item)


			{


				// If we can't delete the item it's probaly a folder so


				// we'll recursively call delete_dir()


				if ( ! @ftp_delete($this->conn_id, $item))


				{


					$this->delete_dir($item);


				}


			}


		}





		$result = @ftp_rmdir($this->conn_id, $filepath);





		if ($result === FALSE)


		{


			if ($this->debug == TRUE)


			{


				$this->_error('ftp_unable_to_delete');


			}


			return FALSE;


		}





		return TRUE;


	}





	// --------------------------------------------------------------------





	/**


	 * Set file permissions


	 *


	 * @access	public


	 * @param	string	the file path


	 * @param	string	the permissions


	 * @return	bool


	 */


	function chmod($path, $perm)


	{


		if ( ! $this->_is_conn())


		{


			return FALSE;


		}





		if ( ! function_exists('ftp_chmod'))


		{


			if ($this->debug == TRUE)


			{


				$this->_error('ftp_unable_to_chmod');


			}


			return FALSE;


		}





		$result = @ftp_chmod($this->conn_id, $perm, $path);





		if ($result === FALSE)


		{


			if ($this->debug == TRUE)


			{


				$this->_error('ftp_unable_to_chmod');


			}


			return FALSE;


		}





		return TRUE;


	}





	// --------------------------------------------------------------------





	/**


	 * FTP List files in the specified directory


	 *


	 * @access	public


	 * @return	array


	 */


	function list_files($path = '.')


	{


		if ( ! $this->_is_conn())


		{


			return FALSE;


		}





		return ftp_nlist($this->conn_id, $path);


	}





	// ------------------------------------------------------------------------





	/**


	 * Read a directory and recreate it remotely


	 *


	 * This function recursively reads a folder and everything it contains (including


	 * sub-folders) and creates a mirror via FTP based on it.  Whatever the directory structure


	 * of the original file path will be recreated on the server.


	 *


	 * @access	public


	 * @param	string	path to source with trailing slash


	 * @param	string	path to destination - include the base folder with trailing slash


	 * @return	bool


	 */


	function mirror($locpath, $rempath)


	{


		if ( ! $this->_is_conn())


		{


			return FALSE;


		}





		// Open the local file path


		if ($fp = @opendir($locpath))


		{


			// Attempt to open the remote file path.


			if ( ! $this->changedir($rempath, TRUE))


			{


				// If it doesn't exist we'll attempt to create the direcotory


				if ( ! $this->mkdir($rempath) OR ! $this->changedir($rempath))


				{


					return FALSE;


				}


			}





			// Recursively read the local directory


			while (FALSE !== ($file = readdir($fp)))


			{


				if (@is_dir($locpath.$file) && substr($file, 0, 1) != '.')


				{


					$this->mirror($locpath.$file."/", $rempath.$file."/");


				}


				elseif (substr($file, 0, 1) != ".")


				{


					// Get the file extension so we can se the upload type


					$ext = $this->_getext($file);


					$mode = $this->_settype($ext);





					$this->upload($locpath.$file, $rempath.$file, $mode);


				}


			}


			return TRUE;


		}





		return FALSE;


	}








	// --------------------------------------------------------------------





	/**


	 * Extract the file extension


	 *


	 * @access	private


	 * @param	string


	 * @return	string


	 */


	function _getext($filename)


	{


		if (FALSE === strpos($filename, '.'))


		{


			return 'txt';


		}





		$x = explode('.', $filename);


		return end($x);


	}








	// --------------------------------------------------------------------





	/**


	 * Set the upload type


	 *


	 * @access	private


	 * @param	string


	 * @return	string


	 */


	function _settype($ext)


	{


		$text_types = array(


							'txt',


							'text',


							'php',


							'phps',


							'php4',


							'js',


							'css',


							'htm',


							'html',


							'phtml',


							'shtml',


							'log',


							'xml'


							);








		return (in_array($ext, $text_types)) ? 'ascii' : 'binary';


	}





	// ------------------------------------------------------------------------





	/**


	 * Close the connection


	 *


	 * @access	public


	 * @param	string	path to source


	 * @param	string	path to destination


	 * @return	bool


	 */


	function close()


	{


		if ( ! $this->_is_conn())


		{


			return FALSE;


		}





		@ftp_close($this->conn_id);


	}





	// ------------------------------------------------------------------------





	/**


	 * Display error message


	 *


	 * @access	private


	 * @param	string


	 * @return	bool


	 */


	function _error($line)


	{


		$CI =& get_instance();


		$CI->lang->load('ftp');


		show_error($CI->lang->line($line));


	}








}


// END FTP Class





/* End of file Ftp.php */


/* Location: ./system/libraries/Ftp.php */