<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); | |
/** | |
* CodeIgniter | |
* | |
* An open source application development framework for PHP 4.3.2 or newer | |
* | |
* @package CodeIgniter | |
* @author ExpressionEngine Dev Team | |
* @copyright Copyright (c) 2006, EllisLab, Inc. | |
* @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 ExpressionEngine 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 | |
*/ | |
function CI_FTP($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 direcotry | |
* | |
* The second parameter lets us momentarily turn off debugging so that | |
* this function can be used to test for the existance 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 paramter 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; | |
} | |
// -------------------------------------------------------------------- | |
/** | |
* 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) | |
{ | |
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; | |
} | |
// Permissions can only be set when running PHP 5 | |
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 |