New file |
0,0 → 1,2148 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
|
/** |
* Net_FTP main file. |
* |
* This file must be included to use the Net_FTP package. |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Networking |
* @package FTP |
* @author Tobias Schlitt <toby@php.net> |
* @copyright 1997-2005 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: FTP.php,v 1.2 2006-10-05 08:55:35 florian Exp $ |
* @link http://pear.php.net/package/Net_FTP |
* @since File available since Release 0.0.1 |
*/ |
|
require_once 'PEAR.php'; |
|
/** |
* Option to let the ls() method return only files. |
* |
* @since 1.3 |
* @name NET_FTP_FILES_ONLY |
* @see Net_FTP::ls() |
*/ |
define('NET_FTP_FILES_ONLY', 0, true); |
|
/** |
* Option to let the ls() method return only directories. |
* |
* @since 1.3 |
* @name NET_FTP_DIRS_ONLY |
* @see Net_FTP::ls() |
*/ |
define('NET_FTP_DIRS_ONLY', 1, true); |
|
/** |
* Option to let the ls() method return directories and files (default). |
* |
* @since 1.3 |
* @name NET_FTP_DIRS_FILES |
* @see Net_FTP::ls() |
*/ |
define('NET_FTP_DIRS_FILES', 2, true); |
|
/** |
* Option to let the ls() method return the raw directory listing from ftp_rawlist(). |
* |
* @since 1.3 |
* @name NET_FTP_RAWLIST |
* @see Net_FTP::ls() |
*/ |
define('NET_FTP_RAWLIST', 3, true); |
|
|
/** |
* Error code to indicate a failed connection |
* This error code indicates, that the connection you tryed to set up |
* could not be established. Check your connection settings (host & port)! |
* |
* @since 1.3 |
* @name NET_FTP_ERR_CONNECT_FAILED |
* @see Net_FTP::connect() |
*/ |
define('NET_FTP_ERR_CONNECT_FAILED', -1); |
|
/** |
* Error code to indicate a failed login |
* This error code indicates, that the login to the FTP server failed. Check |
* your user data (username & password). |
* |
* @since 1.3 |
* @name NET_FTP_ERR_LOGIN_FAILED |
* @see Net_FTP::login() |
*/ |
define('NET_FTP_ERR_LOGIN_FAILED', -2); |
|
/** |
* Error code to indicate a failed directory change |
* The cd() method failed. Ensure that the directory you wanted to access exists. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_DIRCHANGE_FAILED |
* @see Net_FTP::cd() |
*/ |
define('NET_FTP_ERR_DIRCHANGE_FAILED', 2); // Compatibillity reasons! |
|
/** |
* Error code to indicate that Net_FTP could not determine the current path |
* The cwd() method failed and could not determine the path you currently reside |
* in on the FTP server. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_DETERMINEPATH_FAILED |
* @see Net_FTP::pwd() |
*/ |
define('NET_FTP_ERR_DETERMINEPATH_FAILED', 4); // Compatibillity reasons! |
|
/** |
* Error code to indicate that the creation of a directory failed |
* The directory you tryed to create could not be created. Check the |
* access rights on the parent directory! |
* |
* @since 1.3 |
* @name NET_FTP_ERR_CREATEDIR_FAILED |
* @see Net_FTP::mkdir() |
*/ |
define('NET_FTP_ERR_CREATEDIR_FAILED', -4); |
|
/** |
* Error code to indicate that the EXEC execution failed. |
* The execution of a command using EXEC failed. Ensure, that your |
* FTP server supports the EXEC command. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_EXEC_FAILED |
* @see Net_FTP::execute() |
*/ |
define('NET_FTP_ERR_EXEC_FAILED', -5); |
|
/** |
* Error code to indicate that the SITE command failed. |
* The execution of a command using SITE failed. Ensure, that your |
* FTP server supports the SITE command. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_SITE_FAILED |
* @see Net_FTP::site() |
*/ |
define('NET_FTP_ERR_SITE_FAILED', -6); |
|
/** |
* Error code to indicate that the CHMOD command failed. |
* The execution of CHMOD failed. Ensure, that your |
* FTP server supports the CHMOD command and that you have the appropriate |
* access rights to use CHMOD. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_CHMOD_FAILED |
* @see Net_FTP::chmod() |
*/ |
define('NET_FTP_ERR_CHMOD_FAILED', -7); |
|
/** |
* Error code to indicate that a file rename failed |
* The renaming of a file on the server failed. Ensure that you have the |
* appropriate access rights to rename the file. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_RENAME_FAILED |
* @see Net_FTP::rename() |
*/ |
define('NET_FTP_ERR_RENAME_FAILED', -8); |
|
/** |
* Error code to indicate that the MDTM command failed |
* The MDTM command is not supported for directories. Ensure that you gave |
* a file path to the mdtm() method, not a directory path. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_MDTMDIR_UNSUPPORTED |
* @see Net_FTP::mdtm() |
*/ |
define('NET_FTP_ERR_MDTMDIR_UNSUPPORTED', -9); |
|
/** |
* Error code to indicate that the MDTM command failed |
* The MDTM command failed. Ensure that your server supports the MDTM command. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_MDTM_FAILED |
* @see Net_FTP::mdtm() |
*/ |
define('NET_FTP_ERR_MDTM_FAILED', -10); |
|
/** |
* Error code to indicate that a date returned by the server was misformated |
* A date string returned by your server seems to be missformated and could not be |
* parsed. Check that the server is configured correctly. If you're sure, please |
* send an email to the auhtor with a dumped output of $ftp->ls('./', NET_FTP_RAWLIST); |
* to get the date format supported. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_DATEFORMAT_FAILED |
* @see Net_FTP::mdtm(), Net_FTP::ls() |
*/ |
define('NET_FTP_ERR_DATEFORMAT_FAILED', -11); |
|
/** |
* Error code to indicate that the SIZE command failed |
* The determination of the filesize of a file failed. Ensure that your server supports the |
* SIZE command. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_SIZE_FAILED |
* @see Net_FTP::size() |
*/ |
define('NET_FTP_ERR_SIZE_FAILED', -12); |
|
/** |
* Error code to indicate that a local file could not be overwritten |
* You specified not to overwrite files. Therefore the local file has not been |
* overwriten. If you want to get the file overwriten, please set the option to |
* do so. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN |
* @see Net_FTP::get(), Net_FTP::getRecursive() |
*/ |
define('NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN', -13); |
|
/** |
* Error code to indicate that a local file could not be overwritten |
* Also you specified to overwrite the local file you want to download to, |
* it has not been possible to do so. Check that you have the appropriate access |
* rights on the local file to overwrite it. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_OVERWRITELOCALFILE_FAILED |
* @see Net_FTP::get(), Net_FTP::getRecursive() |
*/ |
define('NET_FTP_ERR_OVERWRITELOCALFILE_FAILED', -14); |
|
/** |
* Error code to indicate that the file you wanted to upload does not exist |
* The file you tried to upload does not exist. Ensure that it exists. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_LOCALFILENOTEXIST |
* @see Net_FTP::put(), Net_FTP::putRecursive() |
*/ |
define('NET_FTP_ERR_LOCALFILENOTEXIST', -15); |
|
/** |
* Error code to indicate that a remote file could not be overwritten |
* You specified not to overwrite files. Therefore the remote file has not been |
* overwriten. If you want to get the file overwriten, please set the option to |
* do so. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN |
* @see Net_FTP::put(), Net_FTP::putRecursive() |
*/ |
define('NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN', -16); |
|
/** |
* Error code to indicate that the upload of a file failed |
* The upload you tried failed. Ensure that you have appropriate access rights |
* to upload the desired file. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_UPLOADFILE_FAILED |
* @see Net_FTP::put(), Net_FTP::putRecursive() |
*/ |
define('NET_FTP_ERR_UPLOADFILE_FAILED', -17); |
|
/** |
* Error code to indicate that you specified an incorrect directory path |
* The remote path you specified seems not to be a directory. Ensure that |
* the path you specify is a directory and that the path string ends with |
* a /. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_REMOTEPATHNODIR |
* @see Net_FTP::putRecursive(), Net_FTP::getRecursive() |
*/ |
define('NET_FTP_ERR_REMOTEPATHNODIR', -18); |
|
/** |
* Error code to indicate that you specified an incorrect directory path |
* The local path you specified seems not to be a directory. Ensure that |
* the path you specify is a directory and that the path string ends with |
* a /. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_LOCALPATHNODIR |
* @see Net_FTP::putRecursive(), Net_FTP::getRecursive() |
*/ |
define('NET_FTP_ERR_LOCALPATHNODIR', -19); |
|
/** |
* Error code to indicate that a local directory failed to be created |
* You tried to create a local directory through getRecursive() method, |
* which has failed. Ensure that you have the appropriate access rights |
* to create it. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_CREATELOCALDIR_FAILED |
* @see Net_FTP::getRecursive() |
*/ |
define('NET_FTP_ERR_CREATELOCALDIR_FAILED', -20); |
|
/** |
* Error code to indicate that the provided hostname was incorrect |
* The hostname you provided was invalid. Ensure to provide either a |
* full qualified domain name or an IP address. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_HOSTNAMENOSTRING |
* @see Net_FTP::setHostname() |
*/ |
define('NET_FTP_ERR_HOSTNAMENOSTRING', -21); |
|
/** |
* Error code to indicate that the provided port was incorrect |
* The port number you provided was invalid. Ensure to provide either a |
* a numeric port number greater zero. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_PORTLESSZERO |
* @see Net_FTP::setPort() |
*/ |
define('NET_FTP_ERR_PORTLESSZERO', -22); |
|
/** |
* Error code to indicate that you provided an invalid mode constant |
* The mode constant you provided was invalid. You may only provide |
* FTP_ASCII or FTP_BINARY. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_NOMODECONST |
* @see Net_FTP::setMode() |
*/ |
define('NET_FTP_ERR_NOMODECONST', -23); |
|
/** |
* Error code to indicate that you provided an invalid timeout |
* The timeout you provided was invalid. You have to provide a timeout greater |
* or equal to zero. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_TIMEOUTLESSZERO |
* @see Net_FTP::Net_FTP(), Net_FTP::setTimeout() |
*/ |
define('NET_FTP_ERR_TIMEOUTLESSZERO', -24); |
|
/** |
* Error code to indicate that you provided an invalid timeout |
* An error occured while setting the timeout. Ensure that you provide a |
* valid integer for the timeount and that your PHP installation works |
* correctly. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_SETTIMEOUT_FAILED |
* @see Net_FTP::Net_FTP(), Net_FTP::setTimeout() |
*/ |
define('NET_FTP_ERR_SETTIMEOUT_FAILED', -25); |
|
/** |
* Error code to indicate that the provided extension file doesn't exist |
* The provided extension file does not exist. Ensure to provided an |
* existant extension file. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_EXTFILENOTEXIST |
* @see Net_FTP::getExtensionFile() |
*/ |
define('NET_FTP_ERR_EXTFILENOTEXIST', -26); |
|
/** |
* Error code to indicate that the provided extension file is not readable |
* The provided extension file is not readable. Ensure to have sufficient |
* access rights for it. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_EXTFILEREAD_FAILED |
* @see Net_FTP::getExtensionFile() |
*/ |
define('NET_FTP_ERR_EXTFILEREAD_FAILED', -27); |
|
/** |
* Error code to indicate that the deletion of a file failed |
* The specified file could not be deleted. Ensure to have sufficient |
* access rights to delete the file. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_EXTFILEREAD_FAILED |
* @see Net_FTP::rm() |
*/ |
define('NET_FTP_ERR_DELETEFILE_FAILED', -28); |
|
/** |
* Error code to indicate that the deletion of a directory faild |
* The specified file could not be deleted. Ensure to have sufficient |
* access rights to delete the file. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_EXTFILEREAD_FAILED |
* @see Net_FTP::rm() |
*/ |
define('NET_FTP_ERR_DELETEDIR_FAILED', -29); |
|
/** |
* Error code to indicate that the directory listing failed |
* PHP could not list the directory contents on the server. Ensure |
* that your server is configured appropriate. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_RAWDIRLIST_FAILED |
* @see Net_FTP::ls() |
*/ |
define('NET_FTP_ERR_RAWDIRLIST_FAILED', -30); |
|
/** |
* Error code to indicate that the directory listing failed |
* The directory listing format your server uses seems not to |
* be supported by Net_FTP. Please send the output of the |
* call ls('./', NET_FTP_RAWLIST); to the author of this |
* class to get it supported. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_DIRLIST_UNSUPPORTED |
* @see Net_FTP::ls() |
*/ |
define('NET_FTP_ERR_DIRLIST_UNSUPPORTED', -31); |
|
/** |
* Error code to indicate failed disconnecting |
* This error code indicates, that disconnection was not possible. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_DISCONNECT_FAILED |
* @see Net_FTP::disconnect() |
*/ |
define('NET_FTP_ERR_DISCONNECT_FAILED', -32); |
|
/** |
* Error code to indicate that the username you provided was invalid. |
* Check that you provided a non-empty string as the username. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_USERNAMENOSTRING |
* @see Net_FTP::setUsername() |
*/ |
define('NET_FTP_ERR_USERNAMENOSTRING', -33); |
|
/** |
* Error code to indicate that the username you provided was invalid. |
* Check that you provided a non-empty string as the username. |
* |
* @since 1.3 |
* @name NET_FTP_ERR_PASSWORDNOSTRING |
* @see Net_FTP::setPassword() |
*/ |
define('NET_FTP_ERR_PASSWORDNOSTRING', -33); |
|
/** |
* Class for comfortable FTP-communication |
* |
* This class provides comfortable communication with FTP-servers. You may do everything |
* enabled by the PHP-FTP-extension and further functionalities, like recursive-deletion, |
* -up- and -download. Another feature is to create directories recursively. |
* |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @category Networking |
* @package FTP |
* @author Tobias Schlitt <toby@php.net> |
* @copyright 1997-2005 The PHP Group |
* @version Release: @package_version@ |
* @link http://pear.php.net/package/Net_FTP |
* @since 0.0.1 |
* @access public |
*/ |
class Net_FTP extends PEAR |
{ |
/** |
* The host to connect to |
* |
* @access private |
* @var string |
*/ |
|
var $_hostname; |
|
/** |
* The port for ftp-connection (standard is 21) |
* |
* @access private |
* @var int |
*/ |
|
var $_port = 21; |
|
/** |
* The username for login |
* |
* @access private |
* @var string |
*/ |
|
var $_username; |
|
/** |
* The password for login |
* |
* @access private |
* @var string |
*/ |
|
var $_password; |
|
/** |
* Determine whether to use passive-mode (true) or active-mode (false) |
* |
* @access private |
* @var bool |
*/ |
|
var $_passv; |
|
/** |
* The standard mode for ftp-transfer |
* |
* @access private |
* @var int |
*/ |
|
var $_mode = FTP_BINARY; |
|
/** |
* This holds the handle for the ftp-connection |
* |
* @access private |
* @var resource |
*/ |
|
var $_handle; |
|
/** |
* Contains the timeout for FTP operations |
* |
* @access private |
* @var int |
* @since 1.3 |
*/ |
|
var $_timeout = 90; |
|
/** |
* Saves file-extensions for ascii- and binary-mode |
* |
* The array contains 2 sub-arrays ("ascii" and "binary"), which both contain |
* file-extensions without the "." (".php" = "php"). |
* |
* @access private |
* @var array |
*/ |
|
var $_file_extensions; |
|
/** |
* ls match |
* Matches the ls entries against a regex and maps the resulting array to speaking names |
* |
* @access private |
* @var array |
* @since 1.3 |
*/ |
|
var $_ls_match = array( |
'unix' => array( |
'pattern' => '/(?:(d)|.)([rwxt-]+)\s+(\w+)\s+([\w\d-]+)\s+([\w\d-]+)\s+(\w+)\s+(\S+\s+\S+\s+\S+)\s+(.+)/', |
'map' => array( |
'is_dir' => 1, |
'rights' => 2, |
'files_inside' => 3, |
'user' => 4, |
'group' => 5, |
'size' => 6, |
'date' => 7, |
'name' => 8, |
) |
), |
'windows' => array( |
'pattern' => '/(.+)\s+(.+)\s+((<DIR>)|[0-9]+)\s+(.+)/', |
'map' => array( |
'name' => 5, |
'date' => 1, |
'size' => 3, |
'is_dir' => 4, |
) |
) |
); |
|
/** |
* matcher |
* Stores the matcher for the current connection |
* |
* @access private |
* @var array |
* @since 1.3 |
*/ |
var $_matcher = null; |
|
/** |
* Holds all Net_FTP_Observer objects |
* that wish to be notified of new messages. |
* |
* @var array |
* @access private |
* @since 1.3 |
*/ |
|
var $_listeners = array(); |
|
/** |
* This generates a new FTP-Object. The FTP-connection will not be established, yet. |
* You can leave $host and $port blank, if you want. The $host will not be set |
* and the $port will be left at 21. You have to set the $host manualy before |
* trying to connect or with the connect() method. |
* |
* @access public |
* @param string $host (optional) The hostname |
* @param int $port (optional) The port |
* @param int $timeout (optional) Sets the standard timeout |
* @return void |
* @see Net_FTP::setHostname(), Net_FTP::setPort(), Net_FTP::connect() |
*/ |
|
function Net_FTP($host = null, $port = null, $timeout = 90) |
{ |
$this->PEAR(); |
if (isset($host)) { |
$this->setHostname($host); |
} |
if (isset($port)) { |
$this->setPort($port); |
} |
$this->_timeout = $timeout; |
$this->_file_extensions[FTP_ASCII] = array(); |
$this->_file_extensions[FTP_BINARY] = array(); |
} |
|
/** |
* This function generates the FTP-connection. You can optionally define a |
* hostname and/or a port. If you do so, this data is stored inside the object. |
* |
* @access public |
* @param string $host (optional) The Hostname |
* @param int $port (optional) The Port |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_CONNECT_FAILED |
*/ |
|
function connect($host = null, $port = null) |
{ |
$this->_matcher = null; |
if (isset($host)) { |
$this->setHostname($host); |
} |
if (isset($port)) { |
$this->setPort($port); |
} |
$handle = @ftp_connect($this->getHostname(), $this->getPort(), $this->_timeout); |
if (!$handle) { |
return $this->raiseError("Connection to host failed", NET_FTP_ERR_CONNECT_FAILED); |
} else { |
$this->_handle =& $handle; |
return true; |
} |
} |
|
/** |
* This function close the FTP-connection |
* |
* @access public |
* @return bool|PEAR_Error Returns true on success, PEAR_Error on failure |
*/ |
|
function disconnect() |
{ |
$res = @ftp_close($this->_handle); |
if (!$res) { |
return PEAR::raiseError('Disconnect failed.', NET_FTP_ERR_DISCONNECT_FAILED); |
} |
return true; |
} |
|
/** |
* This logges you into the ftp-server. You are free to specify username and password |
* in this method. If you specify it, the values will be taken into the corresponding |
* attributes, if do not specify, the attributes are taken. |
* |
* @access public |
* @param string $username (optional) The username to use |
* @param string $password (optional) The password to use |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_LOGIN_FAILED |
*/ |
|
function login($username = null, $password = null) |
{ |
if (!isset($username)) { |
$username = $this->getUsername(); |
} else { |
$this->setUsername($username); |
} |
|
if (!isset($password)) { |
$password = $this->getPassword(); |
} else { |
$this->setPassword($password); |
} |
|
$res = @ftp_login($this->_handle, $username, $password); |
|
if (!$res) { |
return $this->raiseError("Unable to login", NET_FTP_ERR_LOGIN_FAILED); |
} else { |
return true; |
} |
} |
|
/** |
* This changes the currently used directory. You can use either an absolute |
* directory-path (e.g. "/home/blah") or a relative one (e.g. "../test"). |
* |
* @access public |
* @param string $dir The directory to go to. |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_DIRCHANGE_FAILED |
*/ |
|
function cd($dir) |
{ |
$erg = @ftp_chdir($this->_handle, $dir); |
if (!$erg) { |
return $this->raiseError("Directory change failed", NET_FTP_ERR_DIRCHANGE_FAILED); |
} else { |
return true; |
} |
} |
|
/** |
* Show's you the actual path on the server |
* This function questions the ftp-handle for the actual selected path and returns it. |
* |
* @access public |
* @return mixed The actual path or PEAR::Error |
* @see NET_FTP_ERR_DETERMINEPATH_FAILED |
*/ |
|
function pwd() |
{ |
$res = @ftp_pwd($this->_handle); |
if (!$res) { |
return $this->raiseError("Could not determine the actual path.", NET_FTP_ERR_DETERMINEPATH_FAILED); |
} else { |
return $res; |
} |
} |
|
/** |
* This works similar to the mkdir-command on your local machine. You can either give |
* it an absolute or relative path. The relative path will be completed with the actual |
* selected server-path. (see: pwd()) |
* |
* @access public |
* @param string $dir Absolute or relative dir-path |
* @param bool $recursive (optional) Create all needed directories |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_CREATEDIR_FAILED |
*/ |
|
function mkdir($dir, $recursive = false) |
{ |
$dir = $this->_construct_path($dir); |
$savedir = $this->pwd(); |
$this->pushErrorHandling(PEAR_ERROR_RETURN); |
$e = $this->cd($dir); |
$this->popErrorHandling(); |
if ($e === true) { |
$this->cd($savedir); |
return true; |
} |
$this->cd($savedir); |
if ($recursive === false){ |
$res = @ftp_mkdir($this->_handle, $dir); |
if (!$res) { |
return $this->raiseError("Creation of '$dir' failed", NET_FTP_ERR_CREATEDIR_FAILED); |
} else { |
return true; |
} |
} else { |
if(strpos($dir, '/') === false) { |
return $this->mkdir($dir,false); |
} |
$pos = 0; |
$res = $this->mkdir(dirname($dir), true); |
$res = $this->mkdir($dir, false); |
if ($res !== true) { |
return $res; |
} |
return true; |
} |
} |
|
/** |
* This method tries executing a command on the ftp, using SITE EXEC. |
* |
* @access public |
* @param string $command The command to execute |
* @return mixed The result of the command (if successfull), otherwise PEAR::Error |
* @see NET_FTP_ERR_EXEC_FAILED |
*/ |
|
function execute($command) |
{ |
$res = @ftp_exec($this->_handle, $command); |
if (!$res) { |
return $this->raiseError("Execution of command '$command' failed.", NET_FTP_ERR_EXEC_FAILED); |
} else { |
return $res; |
} |
} |
|
/** |
* Execute a SITE command on the server |
* This method tries to execute a SITE command on the ftp server. |
* |
* @access public |
* @param string $command The command with parameters to execute |
* @return mixed True if successful, otherwise PEAR::Error |
* @see NET_FTP_ERR_SITE_FAILED |
*/ |
|
function site($command) |
{ |
$res = @ftp_site($this->_handle, $command); |
if (!$res) { |
return $this->raiseError("Execution of SITE command '$command' failed.", NET_FTP_ERR_SITE_FAILED); |
} else { |
return $res; |
} |
} |
|
/** |
* This method will try to chmod the file specified on the server |
* Currently, you must give a number as the the permission argument (777 or |
* similar). The file can be either a relative or absolute path. |
* NOTE: Some servers do not support this feature. In that case, you will |
* get a PEAR error object returned. If successful, the method returns true |
* |
* @access public |
* @param mixed $target The file or array of files to set permissions for |
* @param integer $permissions The mode to set the file permissions to |
* @return mixed True if successful, otherwise PEAR::Error |
* @see NET_FTP_ERR_CHMOD_FAILED |
*/ |
|
function chmod($target, $permissions) |
{ |
// If $target is an array: Loop through it. |
if (is_array($target)) { |
|
for ($i = 0; $i < count($target); $i++) { |
$res = $this->chmod($target[$i], $permissions); |
if (PEAR::isError($res)) { |
return $res; |
} // end if isError |
} // end for i < count($target) |
|
} else { |
|
$res = $this->site("CHMOD " . $permissions . " " . $target); |
if (!$res) { |
return PEAR::raiseError("CHMOD " . $permissions . " " . $target . " failed", NET_FTP_ERR_CHMOD_FAILED); |
} else { |
return $res; |
} |
|
} // end if is_array |
|
} // end method chmod |
|
/** |
* This method will try to chmod a folder and all of its contents |
* on the server. The target argument must be a folder or an array of folders |
* and the permissions argument have to be an integer (i.e. 777). |
* The file can be either a relative or absolute path. |
* NOTE: Some servers do not support this feature. In that case, you |
* will get a PEAR error object returned. If successful, the method |
* returns true |
* |
* @access public |
* @param mixed $target The folder or array of folders to |
* set permissions for |
* @param integer $permissions The mode to set the folder |
* and file permissions to |
* @return mixed True if successful, otherwise PEAR::Error |
* @see NET_FTP_ERR_CHMOD_FAILED, NET_FTP_ERR_DETERMINEPATH_FAILED, NET_FTP_ERR_RAWDIRLIST_FAILED, NET_FTP_ERR_DIRLIST_UNSUPPORTED |
*/ |
|
function chmodRecursive($target, $permissions) |
{ |
static $dir_permissions; |
|
if(!isset($dir_permissions)){ // Making directory specific permissions |
$dir_permissions = $this->_makeDirPermissions($permissions); |
} |
|
// If $target is an array: Loop through it |
if (is_array($target)) { |
|
for ($i = 0; $i < count($target); $i++) { |
$res = $this->chmodRecursive($target[$i], $permissions); |
if (PEAR::isError($res)) { |
return $res; |
} // end if isError |
} // end for i < count($target) |
|
} else { |
|
$remote_path = $this->_construct_path($target); |
|
// Chmod the directory itself |
$result = $this->chmod($remote_path, $dir_permissions); |
|
if (PEAR::isError($result)) { |
return $result; |
} |
|
// If $remote_path last character is not a slash, add one |
if (substr($remote_path, strlen($remote_path)-1) != "/") { |
|
$remote_path .= "/"; |
} |
|
$dir_list = array(); |
$mode = NET_FTP_DIRS_ONLY; |
$dir_list = $this->ls($remote_path, $mode); |
foreach ($dir_list as $dir_entry) { |
if ($dir_entry == '.' || $dir_entry == '..') {; |
continue; |
} |
|
$remote_path_new = $remote_path.$dir_entry["name"]."/"; |
|
// Chmod the directory we're about to enter |
$result = $this->chmod($remote_path_new, $dir_permissions); |
|
if (PEAR::isError($result)) { |
return $result; |
} |
|
$result = $this->chmodRecursive($remote_path_new, $permissions); |
|
if (PEAR::isError($result)) { |
return $result; |
} |
|
} // end foreach dir_list as dir_entry |
|
$file_list = array(); |
$mode = NET_FTP_FILES_ONLY; |
$file_list = $this->ls($remote_path, $mode); |
|
foreach ($file_list as $file_entry) { |
|
$remote_file = $remote_path.$file_entry["name"]; |
|
$result = $this->chmod($remote_file, $permissions); |
|
if (PEAR::isError($result)) { |
return $result; |
} |
|
} // end foreach $file_list |
|
} // end if is_array |
|
return true; // No errors |
|
} // end method chmodRecursive |
|
/** |
* Rename or move a file or a directory from the ftp-server |
* |
* @access public |
* @param string $remote_from The remote file or directory original to rename or move |
* @param string $remote_to The remote file or directory final to rename or move |
* @return bool $res True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_RENAME_FAILED |
*/ |
|
function rename ($remote_from, $remote_to) |
{ |
$res = @ftp_rename($this->_handle, $remote_from, $remote_to); |
if(!$res) { |
return $this->raiseError("Could not rename ".$remote_from." to ".$remote_to." !", NET_FTP_ERR_RENAME_FAILED); |
} |
return true; |
} |
|
/** |
* This will return logical permissions mask for directory. |
* if directory have to be writeable it have also be executable |
* |
* @access private |
* @param string $permissions File permissions in digits for file (i.e. 666) |
* @return string File permissions in digits for directory (i.e. 777) |
*/ |
|
function _makeDirPermissions($permissions){ |
$permissions = (string)$permissions; |
|
for($i = 0; $i < strlen($permissions); $i++){ // going through (user, group, world) |
if((int)$permissions{$i} & 4 and !((int)$permissions{$i} & 1)){ // Read permission is set |
// but execute not yet |
(int)$permissions{$i} = (int)$permissions{$i} + 1; // Adding execute flag |
} |
} |
|
return (string)$permissions; |
} |
|
/** |
* This will return the last modification-time of a file. You can either give this |
* function a relative or an absolute path to the file to check. |
* NOTE: Some servers will not support this feature and the function works |
* only on files, not directories! When successful, |
* it will return the last modification-time as a unix-timestamp or, when $format is |
* specified, a preformated timestring. |
* |
* @access public |
* @param string $file The file to check |
* @param string $format (optional) The format to give the date back |
* if not set, it will return a Unix timestamp |
* @return mixed Unix timestamp, a preformated date-string or PEAR::Error |
* @see NET_FTP_ERR_MDTMDIR_UNSUPPORTED, NET_FTP_ERR_MDTM_FAILED, NET_FTP_ERR_DATEFORMAT_FAILED |
*/ |
|
function mdtm($file, $format = null) |
{ |
$file = $this->_construct_path($file); |
if ($this->_check_dir($file)) { |
return $this->raiseError("Filename '$file' seems to be a directory.", NET_FTP_ERR_MDTMDIR_UNSUPPORTED); |
} |
$res = @ftp_mdtm($this->_handle, $file); |
if ($res == -1) { |
return $this->raiseError("Could not get last-modification-date of '$file'.", NET_FTP_ERR_MDTM_FAILED); |
} |
if (isset($format)) { |
$res = date($format, $res); |
if (!$res) { |
return $this->raiseError("Date-format failed on timestamp '$res'.", NET_FTP_ERR_DATEFORMAT_FAILED); |
} |
} |
return $res; |
} |
|
/** |
* This will return the size of a given file in bytes. You can either give this function |
* a relative or an absolute file-path. NOTE: Some servers do not support this feature! |
* |
* @access public |
* @param string $file The file to check |
* @return mixed Size in bytes or PEAR::Error |
* @see NET_FTP_ERR_SIZE_FAILED |
*/ |
|
function size($file) |
{ |
$file = $this->_construct_path($file); |
$res = @ftp_size($this->_handle, $file); |
if ($res == -1) { |
return $this->raiseError("Could not determine filesize of '$file'.", NET_FTP_ERR_SIZE_FAILED); |
} else { |
return $res; |
} |
} |
|
/** |
* This method returns a directory-list of the current directory or given one. |
* To display the current selected directory, simply set the first parameter to null |
* or leave it blank, if you do not want to use any other parameters. |
* <BR><BR> |
* There are 4 different modes of listing directories. Either to list only |
* the files (using NET_FTP_FILES_ONLY), to list only directories (using |
* NET_FTP_DIRS_ONLY) or to show both (using NET_FTP_DIRS_FILES, which is default). |
* <BR><BR> |
* The 4th one is the NET_FTP_RAWLIST, which returns just the array created by the |
* ftp_rawlist()-function build into PHP. |
* <BR><BR> |
* The other function-modes will return an array containing the requested data. |
* The files and dirs are listed in human-sorted order, but if you select |
* NET_FTP_DIRS_FILES the directories will be added above the files, |
* but although both sorted. |
* <BR><BR> |
* All elements in the arrays are associative arrays themselves. The have the following |
* structure: |
* <BR><BR> |
* Dirs:<BR> |
* ["name"] => string The name of the directory<BR> |
* ["rights"] => string The rights of the directory (in style "rwxr-xr-x")<BR> |
* ["user"] => string The owner of the directory<BR> |
* ["group"] => string The group-owner of the directory<BR> |
* ["files_inside"]=> string The number of files/dirs inside the directory |
* excluding "." and ".."<BR> |
* ["date"] => int The creation-date as Unix timestamp<BR> |
* ["is_dir"] => bool true, cause this is a dir<BR> |
* <BR><BR> |
* Files:<BR> |
* ["name"] => string The name of the file<BR> |
* ["size"] => int Size in bytes<BR> |
* ["rights"] => string The rights of the file (in style "rwxr-xr-x")<BR> |
* ["user"] => string The owner of the file<BR> |
* ["group"] => string The group-owner of the file<BR> |
* ["date"] => int The creation-date as Unix timestamp<BR> |
* ["is_dir"] => bool false, cause this is a file<BR> |
* |
* @access public |
* @param string $dir (optional) The directory to list or null, when listing the current directory. |
* @param int $mode (optional) The mode which types to list (files, directories or both). |
* @return mixed The directory list as described above or PEAR::Error on failure. |
* @see NET_FTP_DIRS_FILES, NET_FTP_DIRS_ONLY, NET_FTP_FILES_ONLY, NET_FTP_RAWLIST, NET_FTP_ERR_DETERMINEPATH_FAILED, NET_FTP_ERR_RAWDIRLIST_FAILED, NET_FTP_ERR_DIRLIST_UNSUPPORTED |
*/ |
|
function ls($dir = null, $mode = NET_FTP_DIRS_FILES) |
{ |
if (!isset($dir)) { |
$dir = @ftp_pwd($this->_handle); |
if (!$dir) { |
return $this->raiseError("Could not retrieve current directory", NET_FTP_ERR_DETERMINEPATH_FAILED); |
} |
} |
if (($mode != NET_FTP_FILES_ONLY) && ($mode != NET_FTP_DIRS_ONLY) && ($mode != NET_FTP_RAWLIST)) { |
$mode = NET_FTP_DIRS_FILES; |
} |
|
switch ($mode) { |
case NET_FTP_DIRS_FILES: $res = $this->_ls_both ( $dir ); |
break; |
case NET_FTP_DIRS_ONLY: $res = $this->_ls_dirs ( $dir ); |
break; |
case NET_FTP_FILES_ONLY: $res = $this->_ls_files ( $dir ); |
break; |
case NET_FTP_RAWLIST: $res = @ftp_rawlist($this->_handle, $dir); |
break; |
} |
|
return $res; |
} |
|
/** |
* This method will delete the given file or directory ($path) from the server |
* (maybe recursive). |
* |
* Whether the given string is a file or directory is only determined by the last |
* sign inside the string ("/" or not). |
* |
* If you specify a directory, you can optionally specify $recursive as true, |
* to let the directory be deleted recursive (with all sub-directories and files |
* inherited). |
* |
* You can either give a absolute or relative path for the file / dir. If you choose to |
* use the relative path, it will be automatically completed with the actual |
* selected directory. |
* |
* @access public |
* @param string $path The absolute or relative path to the file / directory. |
* @param bool $recursive (optional) |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_DELETEFILE_FAILED, NET_FTP_ERR_DELETEDIR_FAILED, NET_FTP_ERR_REMOTEPATHNODIR |
*/ |
|
function rm($path, $recursive = false) |
{ |
$path = $this->_construct_path($path); |
|
if ($this->_check_dir($path)) { |
if ($recursive) { |
return $this->_rm_dir_recursive($path); |
} else { |
return $this->_rm_dir($path); |
} |
} else { |
return $this->_rm_file($path); |
} |
} |
|
/** |
* This function will download a file from the ftp-server. You can either spcify a absolute |
* path to the file (beginning with "/") or a relative one, which will be completed |
* with the actual directory you selected on the server. You can specify |
* the path to which the file will be downloaded on the local |
* maschine, if the file should be overwritten if it exists (optionally, default is |
* no overwriting) and in which mode (FTP_ASCII or FTP_BINARY) the file should be |
* downloaded (if you do not specify this, the method tries to determine it automatically |
* from the mode-directory or uses the default-mode, set by you). If you give a relative |
* path to the local-file, the script-path is used as basepath. |
* |
* @access public |
* @param string $remote_file The absolute or relative path to the file to download |
* @param string $local_file The local file to put the downloaded in |
* @param bool $overwrite (optional) Whether to overwrite existing file |
* @param int $mode (optional) Either FTP_ASCII or FTP_BINARY |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED |
*/ |
|
function get($remote_file, $local_file, $overwrite = false, $mode = null) |
{ |
if (!isset($mode)) { |
$mode = $this->checkFileExtension($remote_file); |
} |
|
$remote_file = $this->_construct_path($remote_file); |
|
if (@file_exists($local_file) && !$overwrite) { |
return $this->raiseError("Local file '$local_file' exists and may not be overwriten.", NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN); |
} |
if (@file_exists($local_file) && !@is_writeable($local_file) && $overwrite) { |
return $this->raiseError("Local file '$local_file' is not writeable. Can not overwrite.", NET_FTP_ERR_OVERWRITELOCALFILE_FAILED); |
} |
|
if (@function_exists('ftp_nb_get')){ |
$res = @ftp_nb_get($this->_handle, $local_file, $remote_file, $mode); |
while ($res == FTP_MOREDATA) { |
$this->_announce('nb_get'); |
$res = @ftp_nb_continue ($this->_handle); |
} |
} else { |
$res = @ftp_get($this->_handle, $local_file, $remote_file, $mode); |
} |
if (!$res) { |
return $this->raiseError("File '$remote_file' could not be downloaded to '$local_file'.", NET_FTP_ERR_OVERWRITELOCALFILE_FAILED); |
} else { |
return true; |
} |
} |
|
/** |
* This function will upload a file to the ftp-server. You can either specify a absolute |
* path to the remote-file (beginning with "/") or a relative one, which will be completed |
* with the actual directory you selected on the server. You can specify |
* the path from which the file will be uploaded on the local |
* maschine, if the file should be overwritten if it exists (optionally, default is |
* no overwriting) and in which mode (FTP_ASCII or FTP_BINARY) the file should be |
* downloaded (if you do not specify this, the method tries to determine it automatically |
* from the mode-directory or uses the default-mode, set by you). If you give a relative |
* path to the local-file, the script-path is used as basepath. |
* |
* @access public |
* @param string $local_file The local file to upload |
* @param string $remote_file The absolute or relative path to the file to upload to |
* @param bool $overwrite (optional) Whether to overwrite existing file |
* @param int $mode (optional) Either FTP_ASCII or FTP_BINARY |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_LOCALFILENOTEXIST, NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN, NET_FTP_ERR_UPLOADFILE_FAILED |
*/ |
|
function put($local_file, $remote_file, $overwrite = false, $mode = null) |
{ |
if (!isset($mode)) { |
$mode = $this->checkFileExtension($local_file); |
} |
$remote_file = $this->_construct_path($remote_file); |
|
if (!@file_exists($local_file)) { |
return $this->raiseError("Local file '$local_file' does not exist.", NET_FTP_ERR_LOCALFILENOTEXIST); |
} |
if ((@ftp_size($this->_handle, $remote_file) != -1) && !$overwrite) { |
return $this->raiseError("Remote file '$remote_file' exists and may not be overwriten.", NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN); |
} |
|
if (function_exists('ftp_nb_put')){ |
$res = @ftp_nb_put($this->_handle, $remote_file, $local_file, $mode); |
while ($res == FTP_MOREDATA) { |
$this->_announce('nb_put'); |
$res = @ftp_nb_continue($this->_handle); |
} |
|
} else { |
$res = @ftp_put($this->_handle, $remote_file, $local_file, $mode); |
} |
if (!$res) { |
return $this->raiseError("File '$local_file' could not be uploaded to '$remote_file'.", NET_FTP_ERR_UPLOADFILE_FAILED); |
} else { |
return true; |
} |
} |
|
/** |
* This functionality allows you to transfer a whole directory-structure from the |
* remote-ftp to your local host. You have to give a remote-directory (ending with |
* '/') and the local directory (ending with '/') where to put the files you download. |
* The remote path is automatically completed with the current-remote-dir, if you give |
* a relative path to this function. You can give a relative path for the $local_path, |
* too. Then the script-basedir will be used for comletion of the path. |
* The parameter $overwrite will determine, whether to overwrite existing files or not. |
* Standard for this is false. Fourth you can explicitly set a mode for all transfer- |
* actions done. If you do not set this, the method tries to determine the transfer- |
* mode by checking your mode-directory for the file-extension. If the extension is not |
* inside the mode-directory, it will get your default-mode. |
* |
* @access public |
* @param string $remote_path The path to download |
* @param string $local_path The path to download to |
* @param bool $overwrite (optional) Whether to overwrite existing files (true) or not (false, standard). |
* @param int $mode (optional) The transfermode (either FTP_ASCII or FTP_BINARY). |
* @return mixed True on succes, otherwise PEAR::Error |
* @see NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_LOCALPATHNODIR,NET_FTP_ERR_CREATELOCALDIR_FAILED |
*/ |
|
function getRecursive($remote_path, $local_path, $overwrite = false, $mode = null) |
{ |
$remote_path = $this->_construct_path($remote_path); |
if (!$this->_check_dir($remote_path)) { |
return $this->raiseError("Given remote-path '$remote_path' seems not to be a directory.", NET_FTP_ERR_REMOTEPATHNODIR); |
} |
if (!$this->_check_dir($local_path)) { |
return $this->raiseError("Given local-path '$local_path' seems not to be a directory.", NET_FTP_ERR_LOCALPATHNODIR); |
} |
|
if (!@is_dir($local_path)) { |
$res = @mkdir($local_path); |
if (!$res) { |
return $this->raiseError("Could not create dir '$local_path'", NET_FTP_ERR_CREATELOCALDIR_FAILED); |
} |
} |
$dir_list = array(); |
$dir_list = $this->ls($remote_path, NET_FTP_DIRS_ONLY); |
foreach ($dir_list as $dir_entry) { |
if ($dir_entry['name'] != '.' && $dir_entry['name'] != '..') { |
$remote_path_new = $remote_path.$dir_entry["name"]."/"; |
$local_path_new = $local_path.$dir_entry["name"]."/"; |
$result = $this->getRecursive($remote_path_new, $local_path_new, $overwrite, $mode); |
if ($this->isError($result)) { |
return $result; |
} |
} |
} |
$file_list = array(); |
$file_list = $this->ls($remote_path, NET_FTP_FILES_ONLY); |
foreach ($file_list as $file_entry) { |
$remote_file = $remote_path.$file_entry["name"]; |
$local_file = $local_path.$file_entry["name"]; |
$result = $this->get($remote_file, $local_file, $overwrite, $mode); |
if ($this->isError($result)) { |
return $result; |
} |
} |
return true; |
} |
|
/** |
* This functionality allows you to transfer a whole directory-structure from your |
* local host to the remote-ftp. You have to give a remote-directory (ending with |
* '/') and the local directory (ending with '/') where to put the files you download. |
* The remote path is automatically completed with the current-remote-dir, if you give |
* a relative path to this function. You can give a relative path for the $local_path, |
* too. Then the script-basedir will be used for comletion of the path. |
* The parameter $overwrite will determine, whether to overwrite existing files or not. |
* Standard for this is false. Fourth you can explicitly set a mode for all transfer- |
* actions done. If you do not set this, the method tries to determine the transfer- |
* mode by checking your mode-directory for the file-extension. If the extension is not |
* inside the mode-directory, it will get your default-mode. |
* |
* @access public |
* @param string $remote_path The path to download |
* @param string $local_path The path to download to |
* @param bool $overwrite (optional) Whether to overwrite existing files (true) or not (false, standard). |
* @param int $mode (optional) The transfermode (either FTP_ASCII or FTP_BINARY). |
* @return mixed True on succes, otherwise PEAR::Error |
* @see NET_FTP_ERR_LOCALFILENOTEXIST, NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN, NET_FTP_ERR_UPLOADFILE_FAILED, NET_FTP_ERR_LOCALPATHNODIR, NET_FTP_ERR_REMOTEPATHNODIR |
*/ |
|
function putRecursive($local_path, $remote_path, $overwrite = false, $mode = null) |
{ |
$remote_path = $this->_construct_path($remote_path); |
if (!$this->_check_dir($local_path) || !is_dir($local_path)) { |
return $this->raiseError("Given local-path '$local_path' seems not to be a directory.", NET_FTP_ERR_LOCALPATHNODIR); |
} |
if (!$this->_check_dir($remote_path)) { |
return $this->raiseError("Given remote-path '$remote_path' seems not to be a directory.", NET_FTP_ERR_REMOTEPATHNODIR); |
} |
$old_path = $this->pwd(); |
if ($this->isError($this->cd($remote_path))) { |
$res = $this->mkdir($remote_path); |
if ($this->isError($res)) { |
return $res; |
} |
} |
$this->cd($old_path); |
$dir_list = $this->_ls_local($local_path); |
foreach ($dir_list["dirs"] as $dir_entry) { |
$remote_path_new = $remote_path.$dir_entry."/"; |
$local_path_new = $local_path.$dir_entry."/"; |
$result = $this->putRecursive($local_path_new, $remote_path_new, $overwrite, $mode); |
if ($this->isError($result)) { |
return $result; |
} |
} |
|
foreach ($dir_list["files"] as $file_entry) { |
$remote_file = $remote_path.$file_entry; |
$local_file = $local_path.$file_entry; |
$result = $this->put($local_file, $remote_file, $overwrite, $mode); |
if ($this->isError($result)) { |
return $result; |
} |
} |
return true; |
} |
|
/** |
* This checks, whether a file should be transfered in ascii- or binary-mode |
* by it's file-extension. If the file-extension is not set or |
* the extension is not inside one of the extension-dirs, the actual set |
* transfer-mode is returned. |
* |
* @access public |
* @param string $filename The filename to be checked |
* @return int Either FTP_ASCII or FTP_BINARY |
*/ |
|
function checkFileExtension($filename) |
{ |
$pattern = "/\.(.*)$/"; |
$has_extension = preg_match($pattern, $filename, $eregs); |
if (!$has_extension) { |
return $this->_mode; |
} else { |
$ext = $eregs[1]; |
} |
|
if (!empty($this->_file_extensions[$ext])) { |
return $this->_file_extensions[$ext]; |
} |
|
return $this->_mode; |
} |
|
/** |
* Set the Hostname |
* |
* @access public |
* @param string $host The Hostname to set |
* @return bool True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_HOSTNAMENOSTRING |
*/ |
|
function setHostname($host) |
{ |
if (!is_string($host)) { |
return PEAR::raiseError("Hostname must be a string.", NET_FTP_ERR_HOSTNAMENOSTRING); |
} |
$this->_hostname = $host; |
return true; |
} |
|
/** |
* Set the Port |
* |
* @access public |
* @param int $port The Port to set |
* @return bool True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_PORTLESSZERO |
*/ |
|
function setPort($port) |
{ |
if (!is_int($port) || ($port < 0)) { |
PEAR::raiseError("Invalid port. Has to be integer >= 0", NET_FTP_ERR_PORTLESSZERO); |
} |
$this->_port = $port; |
return true; |
} |
|
/** |
* Set the Username |
* |
* @access public |
* @param string $user The Username to set |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_USERNAMENOSTRING |
*/ |
|
function setUsername($user) |
{ |
if (empty($user) || !is_string($user)) { |
return PEAR::raiseError('Username $user invalid.', NET_FTP_ERR_USERNAMENOSTRING); |
} |
$this->_username = $user; |
} |
|
/** |
* Set the Password |
* |
* @access private |
* @param string $password The Password to set |
* @return void |
* @see NET_FTP_ERR_PASSWORDNOSTRING |
*/ |
|
function setPassword($password) |
{ |
if (empty($password) || !is_string($password)) { |
return PEAR::raiseError('Password xxx invalid.', NET_FTP_ERR_PASSWORDNOSTRING); |
} |
$this->_password = $password; |
} |
|
/** |
* Set the transfer-mode. You can use the predefined constants |
* FTP_ASCII or FTP_BINARY. The mode will be stored for any further transfers. |
* |
* @access public |
* @param int $mode The mode to set |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_NOMODECONST |
*/ |
|
function setMode($mode) |
{ |
if (($mode == FTP_ASCII) || ($mode == FTP_BINARY)) { |
$this->_mode = $mode; |
return true; |
} else { |
return $this->raiseError('FTP-Mode has either to be FTP_ASCII or FTP_BINARY', NET_FTP_ERR_NOMODECONST); |
} |
} |
|
/** |
* Set the transfer-method to passive mode |
* |
* @access public |
* @return void |
*/ |
|
function setPassive() |
{ |
$this->_passv = true; |
@ftp_pasv($this->_handle, true); |
} |
|
/** |
* Set the transfer-method to active mode |
* |
* @access public |
* @return void |
*/ |
|
function setActive() |
{ |
$this->_passv = false; |
@ftp_pasv($this->_handle, false); |
} |
|
/** |
* Set the timeout for FTP operations |
* Use this method to set a timeout for FTP operation. Timeout has to be an integer. |
* |
* @acess public |
* @param int $timeout the timeout to use |
* @return bool True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_TIMEOUTLESSZERO, NET_FTP_ERR_SETTIMEOUT_FAILED |
*/ |
|
function setTimeout ( $timeout = 0 ) |
{ |
if (!is_int($timeout) || ($timeout < 0)) { |
return PEAR::raiseError("Timeout $timeout is invalid, has to be an integer >= 0", NET_FTP_ERR_TIMEOUTLESSZERO); |
} |
$this->_timeout = $timeout; |
if (isset($this->_handle) && is_resource($this->_handle)) { |
$res = @ftp_set_option($this->_handle, FTP_TIMEOUT_SEC, $timeout); |
} else { |
$res = true; |
} |
if (!$res) { |
return PEAR::raiseError("Set timeout failed.", NET_FTP_ERR_SETTIMEOUT_FAILED); |
} |
return true; |
} |
|
/** |
* Adds an extension to a mode-directory |
* The mode-directory saves file-extensions coresponding to filetypes |
* (ascii e.g.: 'php', 'txt', 'htm',...; binary e.g.: 'jpg', 'gif', 'exe',...). |
* The extensions have to be saved without the '.'. And |
* can be predefined in an external file (see: getExtensionsFile()). |
* |
* The array is build like this: 'php' => FTP_ASCII, 'png' => FTP_BINARY |
* |
* To change the mode of an extension, just add it again with the new mode! |
* |
* @access public |
* @param int $mode Either FTP_ASCII or FTP_BINARY |
* @param string $ext Extension |
* @return void |
*/ |
|
function addExtension($mode, $ext) |
{ |
$this->_file_extensions[$ext] = $mode; |
} |
|
/** |
* This function removes an extension from the mode-directories |
* (described above). |
* |
* @access public |
* @param string $ext The extension to remove |
* @return void |
*/ |
|
function removeExtension($ext) |
{ |
unset($this->_file_extensions[$ext]); |
} |
|
/** |
* This get's both (ascii- and binary-mode-directories) from the given file. |
* Beware, if you read a file into the mode-directory, all former set values |
* will be unset! |
* |
* @access public |
* @param string $filename The file to get from |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_EXTFILENOTEXIST, NET_FTP_ERR_EXTFILEREAD_FAILED |
*/ |
|
function getExtensionsFile($filename) |
{ |
if (!file_exists($filename)) { |
return $this->raiseError("Extensions-file '$filename' does not exist", NET_FTP_ERR_EXTFILENOTEXIST); |
} |
|
if (!is_readable($filename)) { |
return $this->raiseError("Extensions-file '$filename' is not readable", NET_FTP_ERR_EXTFILEREAD_FAILED); |
} |
|
$this->_file_extension = @parse_ini_file($filename); |
return true; |
} |
|
/** |
* Returns the Hostname |
* |
* @access public |
* @return string The Hostname |
*/ |
|
function getHostname() |
{ |
return $this->_hostname; |
} |
|
/** |
* Returns the Port |
* |
* @access public |
* @return int The Port |
*/ |
|
function getPort() |
{ |
return $this->_port; |
} |
|
/** |
* Returns the Username |
* |
* @access public |
* @return string The Username |
*/ |
|
function getUsername() |
{ |
return $this->_username; |
} |
|
/** |
* Returns the Password |
* |
* @access public |
* @return string The Password |
*/ |
|
function getPassword() |
{ |
return $this->_password; |
} |
|
/** |
* Returns the Transfermode |
* |
* @access public |
* @return int The transfermode, either FTP_ASCII or FTP_BINARY. |
*/ |
|
function getMode() |
{ |
return $this->_mode; |
} |
|
/** |
* Returns, whether the connection is set to passive mode or not |
* |
* @access public |
* @return bool True if passive-, false if active-mode |
*/ |
|
function isPassive() |
{ |
return $this->_passv; |
} |
|
/** |
* Returns the mode set for a file-extension |
* |
* @access public |
* @param string $ext The extension you wanna ask for |
* @return int Either FTP_ASCII, FTP_BINARY or NULL (if not set a mode for it) |
*/ |
|
function getExtensionMode($ext) |
{ |
return @$this->_file_extensions[$ext]; |
} |
|
/** |
* Get the currently set timeout. |
* Returns the actual timeout set. |
* |
* @access public |
* @return int The actual timeout |
*/ |
|
function getTimeout ( ) |
{ |
return ftp_get_option($this->_handle, FTP_TIMEOUT_SEC); |
} |
|
/** |
* Adds a Net_FTP_Observer instance to the list of observers |
* that are listening for messages emitted by this Net_FTP instance. |
* |
* @param object $observer The Net_FTP_Observer instance to attach |
* as a listener. |
* @return boolean True if the observer is successfully attached. |
* @access public |
* @since 1.3 |
*/ |
|
function attach(&$observer) |
{ |
if (!is_a($observer, 'Net_FTP_Observer')) { |
return false; |
} |
|
$this->_listeners[$observer->getId()] = &$observer; |
return true; |
} |
|
/** |
* Removes a Net_FTP_Observer instance from the list of observers. |
* |
* @param object $observer The Net_FTP_Observer instance to detach |
* from the list of listeners. |
* @return boolean True if the observer is successfully detached. |
* @access public |
* @since 1.3 |
*/ |
|
function detach($observer) |
{ |
if (!is_a($observer, 'Net_FTP_Observer') || |
!isset($this->_listeners[$observer->getId()])) { |
return false; |
} |
|
unset($this->_listeners[$observer->getId()]); |
return true; |
} |
|
/** |
* Informs each registered observer instance that a new message has been |
* sent. |
* |
* @param mixed $event A hash describing the net event. |
* @access private |
* @since 1.3 |
*/ |
|
function _announce($event) |
{ |
foreach ($this->_listeners as $id => $listener) { |
$this->_listeners[$id]->notify($event); |
} |
} |
|
/** |
* Rebuild the path, if given relative |
* |
* @access private |
* @param string $path The path to check and construct |
* @return string The build path |
*/ |
|
function _construct_path($path) |
{ |
if ((substr($path, 0, 1) != "/") && (substr($path, 0, 2) != "./")) { |
$actual_dir = @ftp_pwd($this->_handle); |
if (substr($actual_dir, (strlen($actual_dir) - 2), 1) != "/") { |
$actual_dir .= "/"; |
} |
$path = $actual_dir.$path; |
} |
return $path; |
} |
|
/** |
* Checks, whether a given string is a directory-path (ends with "/") or not. |
* |
* @access private |
* @param string $path Path to check |
* @return bool True if $path is a directory, otherwise false |
*/ |
|
function _check_dir($path) |
{ |
if (!empty($path) && substr($path, (strlen($path) - 1), 1) == "/") { |
return true; |
} else { |
return false; |
} |
} |
|
/** |
* This will remove a file |
* |
* @access private |
* @param string $file The file to delete |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_DELETEFILE_FAILED |
*/ |
|
function _rm_file($file) |
{ |
if (substr($file, 0, 1) != "/") { |
$actual_dir = @ftp_pwd($this->_handle); |
if (substr($actual_dir, (strlen($actual_dir) - 2), 1) != "/") { |
$actual_dir .= "/"; |
} |
$file = $actual_dir.$file; |
} |
$res = @ftp_delete($this->_handle, $file); |
|
if (!$res) { |
return $this->raiseError("Could not delete file '$file'.", NET_FTP_ERR_DELETEFILE_FAILED); |
} else { |
return true; |
} |
} |
|
/** |
* This will remove a dir |
* |
* @access private |
* @param string $dir The dir to delete |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_DELETEDIR_FAILED |
*/ |
|
function _rm_dir($dir) |
{ |
if (substr($dir, (strlen($dir) - 1), 1) != "/") { |
return $this->raiseError("Directory name '$dir' is invalid, has to end with '/'", NET_FTP_ERR_REMOTEPATHNODIR); |
} |
$res = @ftp_rmdir($this->_handle, $dir); |
if (!$res) { |
return $this->raiseError("Could not delete directory '$dir'.", NET_FTP_ERR_DELETEDIR_FAILED); |
} else { |
return true; |
} |
} |
|
/** |
* This will remove a dir and all subdirs and -files |
* |
* @access private |
* @param string $file The dir to delete recursively |
* @return mixed True on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_DELETEDIR_FAILED |
*/ |
|
function _rm_dir_recursive($dir) |
{ |
if (substr($dir, (strlen($dir) - 1), 1) != "/") { |
return $this->raiseError("Directory name '$dir' is invalid, has to end with '/'", NET_FTP_ERR_REMOTEPATHNODIR); |
} |
$file_list = $this->_ls_files($dir); |
foreach ($file_list as $file) { |
$file = $dir.$file["name"]; |
$res = $this->rm($file); |
if ($this->isError($res)) { |
return $res; |
} |
} |
$dir_list = $this->_ls_dirs($dir); |
foreach ($dir_list as $new_dir) { |
if ($new_dir == '.' || $new_dir == '..') { |
continue; |
} |
$new_dir = $dir.$new_dir["name"]."/"; |
$res = $this->_rm_dir_recursive($new_dir); |
if ($this->isError($res)) { |
return $res; |
} |
} |
$res = $this->_rm_dir($dir); |
if (PEAR::isError($res)) { |
return $res; |
} else { |
return true; |
} |
} |
|
/** |
* Lists up files and directories |
* |
* @access private |
* @param string $dir The directory to list up |
* @return array An array of dirs and files |
*/ |
|
function _ls_both($dir) |
{ |
$list_splitted = $this->_list_and_parse($dir); |
if (PEAR::isError($list_splitted)) { |
return $list_splitted; |
} |
if (!is_array($list_splitted["files"])) { |
$list_splitted["files"] = array(); |
} |
if (!is_array($list_splitted["dirs"])) { |
$list_splitted["dirs"] = array(); |
} |
$res = array(); |
@array_splice($res, 0, 0, $list_splitted["files"]); |
@array_splice($res, 0, 0, $list_splitted["dirs"]); |
return $res; |
} |
|
/** |
* Lists up directories |
* |
* @access private |
* @param string $dir The directory to list up |
* @return array An array of dirs |
*/ |
|
function _ls_dirs($dir) |
{ |
$list = $this->_list_and_parse($dir); |
if (PEAR::isError($list)) { |
return $list; |
} |
return $list["dirs"]; |
} |
|
/** |
* Lists up files |
* |
* @access private |
* @param string $dir The directory to list up |
* @return array An array of files |
*/ |
|
function _ls_files($dir) |
{ |
$list = $this->_list_and_parse($dir); |
if (PEAR::isError($list)) { |
return $list; |
} |
return $list["files"]; |
} |
|
/** |
* This lists up the directory-content and parses the items into well-formated arrays |
* The results of this array are sorted (dirs on top, sorted by name; |
* files below, sorted by name). |
* |
* @access private |
* @param string $dir The directory to parse |
* @return array Lists of dirs and files |
* @see NET_FTP_ERR_RAWDIRLIST_FAILED |
*/ |
|
function _list_and_parse($dir) |
{ |
$dirs_list = array(); |
$files_list = array(); |
$dir_list = @ftp_rawlist($this->_handle, $dir); |
if (!is_array($dir_list)) { |
return PEAR::raiseError('Could not get raw directory listing.', NET_FTP_ERR_RAWDIRLIST_FAILED); |
} |
// Handle empty directories |
if (count($dir_list) == 0) { |
return array('dirs' => $dirs_list, 'files' => $files_list); |
} |
|
// Exception for some FTP servers seem to return this wiered result instead of an empty list |
if (count($dirs_list) == 1 && $dirs_list[0] == 'total 0') { |
return array('dirs' => array(), 'files' => $files_list); |
} |
|
if (!isset($this->_matcher) || PEAR::isError($this->_matcher)) { |
$this->_matcher = $this->_determine_os_match($dir_list); |
if (PEAR::isError($this->_matcher)) { |
return $this->_matcher; |
} |
} |
foreach ($dir_list as $entry) { |
if (!preg_match($this->_matcher['pattern'], $entry, $m)) { |
continue; |
} |
$entry = array(); |
foreach ($this->_matcher['map'] as $key=>$val) { |
$entry[$key] = $m[$val]; |
} |
$entry['stamp'] = $this->_parse_Date($entry['date']); |
|
if ($entry['is_dir']) { |
$dirs_list[] = $entry; |
} else { |
$files_list[] = $entry; |
} |
} |
@usort($dirs_list, array("Net_FTP", "_nat_sort")); |
@usort($files_list, array("Net_FTP", "_nat_sort")); |
$res["dirs"] = (is_array($dirs_list)) ? $dirs_list : array(); |
$res["files"] = (is_array($files_list)) ? $files_list : array(); |
return $res; |
} |
|
/** |
* Determine server OS |
* This determines the server OS and returns a valid regex to parse |
* ls() output. |
* |
* @access private |
* @param array $dir_list The raw dir list to parse |
* @return mixed An array of 'pattern' and 'map' on success, otherwise PEAR::Error |
* @see NET_FTP_ERR_DIRLIST_UNSUPPORTED |
*/ |
|
function _determine_os_match(&$dir_list) { |
foreach ($dir_list as $entry) { |
foreach ($this->_ls_match as $os => $match) { |
if (preg_match($match['pattern'], $entry)) { |
return $match; |
} |
} |
} |
$error = 'The list style of your server seems not to be supported. Please email a "$ftp->ls(NET_FTP_RAWLIST);" output plus info on the server to the maintainer of this package to get it supported! Thanks for your help!'; |
return PEAR::raiseError($error, NET_FTP_ERR_DIRLIST_UNSUPPORTED); |
} |
/** |
* Lists a local directory |
* |
* @access private |
* @param string $dir_path The dir to list |
* @return array The list of dirs and files |
*/ |
|
function _ls_local($dir_path) |
{ |
$dir = dir($dir_path); |
$dir_list = array(); |
$file_list = array(); |
while (false !== ($entry = $dir->read())) { |
if (($entry != '.') && ($entry != '..')) { |
if (is_dir($dir_path.$entry)) { |
$dir_list[] = $entry; |
} else { |
$file_list[] = $entry; |
} |
} |
} |
$dir->close(); |
$res['dirs'] = $dir_list; |
$res['files'] = $file_list; |
return $res; |
} |
|
/** |
* Function for use with usort(). |
* Compares the list-array-elements by name. |
* |
* @access private |
*/ |
|
function _nat_sort($item_1, $item_2) |
{ |
return strnatcmp($item_1['name'], $item_2['name']); |
} |
|
/** |
* Parse dates to timestamps |
* |
* @access private |
* @param string $date Date |
* @return int Timestamp |
* @see NET_FTP_ERR_DATEFORMAT_FAILED |
*/ |
|
function _parse_Date($date) |
{ |
// Sep 10 22:06 => Sep 10, <year> 22:06 |
if (preg_match('/([A-Za-z]+)[ ]+([0-9]+)[ ]+([0-9]+):([0-9]+)/', $date, $res)) { |
$year = date('Y'); |
$month = $res[1]; |
$day = $res[2]; |
$hour = $res[3]; |
$minute = $res[4]; |
$date = "$month $day, $year $hour:$minute"; |
$tmpDate = strtotime($date); |
if ($tmpDate > time()) { |
$year--; |
$date = "$month $day, $year $hour:$minute"; |
} |
} |
// 09-10-04 => 09/10/04 |
elseif (preg_match('/^\d\d-\d\d-\d\d/',$date)) { |
$date = str_replace('-','/',$date); |
} |
$res = strtotime($date); |
if (!$res) { |
return $this->raiseError('Dateconversion failed.', NET_FTP_ERR_DATEFORMAT_FAILED); |
} |
return $res; |
} |
} |
?> |