<commit_before><?php


/**
 * List of classes that extend 'kFileTransferMgr'.
 * Instances of these classes can be created using the 'getInstance($type)' function.
 * 
 * @package infra
 * @subpackage Storage
 */
class kFileTransferMgrType
{
	const FTP  = 1; // FTP Protocol
	const SCP  = 2; // SCP Protocol
	const SFTP = 3; // SFTP Protocol
	const HTTP = 4;
	const HTTPS = 5;
}
// path where the classes extending kFileTransferMgr are stored relative to this file
define ("PATH_TO_MANAGERS", "file_transfer_managers");




/**
 * List of exception types relevant to 'kFileTransferMgr'.
 * Should be used as the exception code (getCode()) when creating a 'kFileTransferMgrException' exception.
 * 
 * @package infra
 * @subpackage Storage
 */
class kFileTransferMgrException extends Exception
{
	const notYetConnected    = 1; // connection not yet established
	const cantConnect        = 2; // cannot connect to server/port
	const cantAuthenticate   = 3; // username or password problem
	const localFileNotExists = 4; // local file not found (when uploading a file)
	const remotePathNotValid = 5; // remote file / path string is not valid
	const remoteFileExists   = 6; // trying to putFile that already exists with $overwrite == false
	const otherError         = 99; // other - exception's getMessage() will provide more details
}



/**
 * An abstract class that implements a file transfer manager.
 * 
 * @package infra
 * @subpackage Storage
 */
abstract class kFileTransferMgr
{
	/********************/
	/* Member Variables */
	/********************/

	// consts for function result values
	const FILETRANSFERMGR_RES_OK  = true;
	const FILETRANSFERMGR_RES_ERR = false;

	// resource used to identify the current connection
	protected $connection_id;
	// user's starting directory
	protected $start_dir;

	/**
	 * returned value from put and get commands
	 * @var mixed
	 */
	protected $results;


	/**
	 * @return the $results
	 */
	public function getResults()
	{
		return $this->results;
	}

	/*********************************************************************************************/
	/* Abstract functions that should be implemented in all classes extending 'kFileTransferMgr'.
	 /*********************************************************************************************/

	/**
	 * Should create a connection to the given server & port
	 *
	 * @param $ftp_server server hostname / ip address
	 * @param $ftp_port server port
	 *
	 * @return the connection resource identifier
	 */
	abstract protected function doConnect($server, &$port);

	/**
	 * Should login to a previous initiatied connection with the user / pass given.
	 *
	 * @param $user username
	 * @param $pass <PASSWORD>
	 * @param $ftp_passive_mode passive mode true/false - relevant for FTP only
	 *
	 * @return true / false according to success
	 */
	abstract protected function doLogin($user, $pass, $ftp_passive_mode = TRUE);

	/**
	 * Should login to a previous initiatied connection with the given public key
	 *
	 * @param $user remote username
	 * @param $pubKeyFile public key file
	 * @param $privKeyFile  private key file
	 * @param $passphrase if $privKeyFile is encrypted (which it should be), the passphrase must be provided
	 *
	 * @return true / false according to success
	 */
	abstract protected function doLoginPubKey($user, $pubKeyFile, $privKeyFile, $passphrase = null);

	/**
	 * Should upload the given 'local_file' to the connected server with name 'remote_file'
	 *
	 * @param $remote_file remote file's name
	 * @param $local_file local file's name
	 * @param $ftp_mode ftp transfer mode (FTP_BINARY / FTP_ASCII) - relevant for FTP only
	 *
	 * @return true / false according to success
	 */
	abstract protected function doPutFile($remote_file, $local_file, $ftp_mode, $http_field_name = null, $http_file_name = null);

	/**
	 * Should download the fiven 'remote_file' from the server as 'local_file'
	 *
	 * @param $remote_file remote file's name
	 * @param $local_file local file's name
	 * @param $ftp_mode ftp transfer mode (FTP_BINARY / FTP_ASCII) - relevant for FTP only
	 *
	 * @return true / false according to success
	 */
	abstract protected function doGetFile ($remote_file, $local_file, $ftp_mode);

	/**
	 * Should create a new directory on the server.
	 *
	 * @param $remote_path
	 *
	 * @return true / false according to success
	 */
	abstract protected function doMkDir ($remote_path);

	/**
	 * Should delete the given file on the server.
	 *
	 * @param string $remote_file remote file's name
	 *
	 * @return true / false according to success
	 */
	abstract protected function doDelFile ($remote_file);

	/**
	 * Should delete the given directory on the server (including all its contents)
	 *
	 * @param string $remote_path remote directory's name
	 *
	 * @return true / false according to success
	 */
	abstract protected function doDelDir ($remote_path);



	/**
	 * Should chmod the given file with the given code
	 *
	 * @param $remote_file
	 * @param $chmod_code
	 *
	 * @return true / false according to success
	 */
	abstract protected function doChmod ($remote_file, $chmod_code);

	/**
	 * Should return true/false if the given file or directory exists on the server
	 *
	 * @param $remote_file
	 *
	 * @return true / false according to success
	 */
	abstract protected function doFileExists($remote_file);

	/**
	 * Should return the current working directory as a string
	 *
	 * @return a string of the current working directory's path
	 */
	abstract protected function doPwd();

	/**
	 * Should return an array of all elements
	 *
	 * @return an array of all elements
	 */

	abstract protected function doList ($remote_path);


	/********************/
	/* Public Functions */
	/********************/

	/**
	 * Create a new class instance according to the given type.
	 *
	 * @param fileTransferMgrTypes $type Class type from the list under 'kFileTransferMgrType' class.
	 *
	 * @return kFileTransferMgr a new instance
	 */
	public static function getInstance($type)
	{
		switch($type)
		{
			case kFileTransferMgrType::FTP:
				return new ftpMgr();

			case kFileTransferMgrType::SCP:
				return new scpMgr();

			case kFileTransferMgrType::SFTP:
				return new sftpMgr();

			case kFileTransferMgrType::HTTP:
			case kFileTransferMgrType::HTTPS:
				return new httpMgr();
		}

		return null;
	}


	/**
	 * Return the current connection identifier resource.
	 */
	public function getConnection ()
	{
		return $this->connection_id;
	}


	/**
	 * Connect & authenticate on the given server, using the given username & password.
	 *
	 * @param $server Server's hostname or IP address
	 * @param $user User's name
	 * @param $pass Password
	 * @param $port Server's listening port
	 * @param $ftp_passive_mode Used for FTP only
	 *
	 * @throws kFileTransferMgrException
	 *
	 * @return FILETRANSFERMGR_RES_OK / FILETRANSFERMGR_RES_ERR
	 */
	public function login ( $server, $user, $pass, $port = null, $ftp_passive_mode = true)
	{
		KalturaLog::debug("Login to server [$server] port [$port] username/password [$user/$pass] passive [$ftp_passive_mode]");
		
		$ftp_passive_mode = true;
		KalturaLog::debug("FTP passive mode changed to [true] because of a bug with ftp_put on fedora");
		
		$this->connection_id = @($this->doConnect($server, $port));
		if (!$this->connection_id) {
			$last_error = error_get_last();
			throw new kFileTransferMgrException ("Can't connect [$server:$port] - " . $last_error['message'], kFileTransferMgrException::cantConnect);
		}
		
		if(@($this->doLogin($user, $pass, $ftp_passive_mode)))
		{
			KalturaLog::debug("Logged in successfully");
		}
		else
		{
			$last_error = error_get_last();
			throw new kFileTransferMgrException ( "Can't authenticate [$user] - " . $last_error['message'], kFileTransferMgrException::cantAuthenticate);
		}
		$this->start_dir = kString::removeNewLine($this->doPwd());
	}


	/**
	 * Connect & authenticate on the given server, using the given given public key.
	 *
	 * @param $server Server's hostname or IP address
	 * @param $remoteUser remote username
	 * @param $pubKeyFile public key file
	 * @param $privKeyFile  private key file
	 * @param $port server's listening port
	 * @param $passphrase if $privKeyFile is encrypted (which it should be), the passphrase must be provided
	 *
	 * @throws kFileTransferMgrException
	 *
	 * @return FILETRANSFERMGR_RES_OK / FILETRANSFERMGR_RES_ERR
	 */
	public function loginPubKey ( $server, $user, $pubKeyFile, $privKeyFile, $passphrase = null, $port = null)
	{
		KalturaLog::debug("Login to server [$server] port [$port] username [$user] public key file [$pubKeyFile] private key file [$privKeyFile]");
		
		$this->connection_id = @($this->doConnect($server, $port));
		if (!$this->connection_id) {
			$last_error = error_get_last();
			throw new kFileTransferMgrException ("Can't connect [$server:$port] - " . $last_error['message'], kFileTransferMgrException::cantConnect);
		}
		
		if(@($this->doLoginPubKey($user, $pubKeyFile, $privKeyFile, $passphrase)))
		{
			KalturaLog::debug("Logged in successfully");
		}
		else
		{
			$last_error = error_get_last();
			throw new kFileTransferMgrException ( "Can't authenticate [$user] - " . $last_error['message'], kFileTransferMgrException::cantAuthenticate);
		}
		$this->start_dir = kString::removeNewLine($this->doPwd());
	}


	/**
	 * Upload a file to the server
	 *
	 * @param $remote_file Remote file name
	 * @param $local_file Local file name
	 * @param $overwrite true if should overwrite an existing remote file, or false otherwise
	 * @param $ftp_mode FTP_BINARY or FTP_ASCII - used for FTP only
	 *
	 * @throws kFileTransferMgrException
	 *
	 * @return FILETRANSFERMGR_RES_OK / FILETRANSFERMGR_RES_ERR
	 */
	public function putFile ($remote_file, $local_file, $overwrite = false, $ftp_mode = FTP_BINARY, $http_field_name = null, $http_file_name = null)
	{
		KalturaLog::debug("Puts file [$remote_file] from local [$local_file] overwrite [$overwrite]");
		
		// parameter checks
		if (!$this->connection_id) {
			throw new kFileTransferMgrException("No connection established yet.", kFileTransferMgrException::notYetConnected);
		}
		if (!file_exists($local_file)) {
			throw new kFileTransferMgrException("Can't find local file [$local_file]", kFileTransferMgrException::localFileNotExists);
		}
		if ($ftp_mode != FTP_ASCII)	{
			$ftp_mode = FTP_BINARY;
		}

		$remote_file = $this->fixPathString($remote_file);

		// delete existing file if overwrite == true
		$res = true;
		if ($overwrite) {
			if ($this->fileExists($remote_file)) {
				$res = @($this->delFile($remote_file));
			}
			// check if deletion was done succesfully
			if (!$res) {
				$last_error = error_get_last();
				throw new kFileTransferMgrException("Can't delete existing file [$remote_file] - " . $last_error['message'], kFileTransferMgrException::otherError);
				return self::FILETRANSFERMGR_RES_ERR;
			}
		}
		else { // $overwrite == false
			if ($this->fileExists($remote_file)) {
				throw new kFileTransferMgrException("Remote file [$remote_file] already exists.", kFileTransferMgrException::remoteFileExists);
			}
		}

		// create remote directory if necessary
		if (!$this->fileExists(dirname($remote_file))) {
			$this->mkDir(dirname($remote_file));
		}

		// try to upload file
		$res = @($this->doPutFile($remote_file, $local_file, $ftp_mode, $http_field_name, $http_file_name));

		$this->results = $res;
		
		// check response
		if ( !$res ) {
			$last_error = error_get_last();
			throw new kFileTransferMgrException("Can't put file [$remote_file] - " . $last_error['message'], kFileTransferMgrException::otherError);
		}
		
		KalturaLog::debug("File uploaded successfully");
		return self::FILETRANSFERMGR_RES_OK;
	}
	
	/**
	 * Download a file from the server
	 *
	 * @param $remote_file Remote file name
	 * @param $local_file Local file name
	 * @param $ftp_mode FTP_BINARY or FTP_ASCII - used for FTP only
	 *
	 * @throws kFileTransferMgrException
	 *
	 * @return FILETRANSFERMGR_RES_OK / FILETRANSFERMGR_RES_ERR
	 */
	public function getFile ( $remote_file, $local_file, $ftp_mode = FTP_BINARY)
	{
		KalturaLog::debug("Gets file [$remote_file] to local [$local_file]");
		
		// parameter checks
		if (!$this->connection_id) {
			throw new kFileTransferMgrException("No connection established yet.", kFileTransferMgrException::notYetConnected);
		}
		if ($ftp_mode != FTP_ASCII)	{
			$ftp_mode = FTP_BINARY;
		}

		$remote_file = $this->fixPathString($remote_file);

		// try to download file
		$res = @($this->doGetFile($remote_file, $local_file, $ftp_mode));

		$this->results = $res;
		
		// check response
		if ( ! $res ) {
			$last_error = error_get_last();
			throw new kFileTransferMgrException("Can't get file [$remote_file] - " . $last_error['message'], kFileTransferMgrException::otherError);
			return self::FILETRANSFERMGR_RES_ERR;
		}
		else
		{
			KalturaLog::debug("File retrieved successfully");
			return self::FILETRANSFERMGR_RES_OK;
		}
	}

	/**
	 * Create a new directory on the server
	 *
	 * @param $remote_path New directory path
	 *
	 * @throws kFileTransferMgrException
	 *
	 * @return FILETRANSFERMGR_RES_OK / FILETRANSFERMGR_RES_ERR
	 */
	public function mkDir ($remote_path)
	{
		KalturaLog::debug("Makes directory [$remote_path]");
		
		// parameter checks
		if (!$this->connection_id) {
			throw new kFileTransferMgrException("No connection established yet.", kFileTransferMgrException::notYetConnected);
		}
		if (strlen(trim($remote_path)) <= 0) {
			throw new kFileTransferMgrException("Remote path given is empty", kFileTransferMgrException::remotePathNotValid);
			return self::FILETRANSFERMGR_RES_ERR;
		}

		$remote_path = $this->fixPathString($remote_path);

		// recursivly try to create the new directory
		$temp_path = '';
		if ($remote_path[0] == '/' || $remote_path[0] == '\\') {
			$temp_path = '/';
		}
		$split_path = explode("/", $remote_path);
		$res = true;
		$i = 0;
		$array_count = count($split_path);
		while ($res && $i < $array_count) {
			if (($split_path[$i] != null) && (trim($split_path[$i]) != '') )
			{
				$temp_path = $temp_path . $split_path[$i];
				if (!$this->fileExists($temp_path)) { // direcotry doesn't exist<commit_msg>fix bug, removed '/' from prefix of path when creating dir or file. (ticket 10507)<commit_after><?php


/**
 * List of classes that extend 'kFileTransferMgr'.
 * Instances of these classes can be created using the 'getInstance($type)' function.
 * 
 * @package infra
 * @subpackage Storage
 */
class kFileTransferMgrType
{
	const FTP  = 1; // FTP Protocol
	const SCP  = 2; // SCP Protocol
	const SFTP = 3; // SFTP Protocol
	const HTTP = 4;
	const HTTPS = 5;
}
// path where the classes extending kFileTransferMgr are stored relative to this file
define ("PATH_TO_MANAGERS", "file_transfer_managers");




/**
 * List of exception types relevant to 'kFileTransferMgr'.
 * Should be used as the exception code (getCode()) when creating a 'kFileTransferMgrException' exception.
 * 
 * @package infra
 * @subpackage Storage
 */
class kFileTransferMgrException extends Exception
{
	const notYetConnected    = 1; // connection not yet established
	const cantConnect        = 2; // cannot connect to server/port
	const cantAuthenticate   = 3; // username or password problem
	const localFileNotExists = 4; // local file not found (when uploading a file)
	const remotePathNotValid = 5; // remote file / path string is not valid
	const remoteFileExists   = 6; // trying to putFile that already exists with $overwrite == false
	const otherError         = 99; // other - exception's getMessage() will provide more details
}



/**
 * An abstract class that implements a file transfer manager.
 * 
 * @package infra
 * @subpackage Storage
 */
abstract class kFileTransferMgr
{
	/********************/
	/* Member Variables */
	/********************/

	// consts for function result values
	const FILETRANSFERMGR_RES_OK  = true;
	const FILETRANSFERMGR_RES_ERR = false;

	// resource used to identify the current connection
	protected $connection_id;
	// user's starting directory
	protected $start_dir;

	/**
	 * returned value from put and get commands
	 * @var mixed
	 */
	protected $results;


	/**
	 * @return the $results
	 */
	public function getResults()
	{
		return $this->results;
	}

	/*********************************************************************************************/
	/* Abstract functions that should be implemented in all classes extending 'kFileTransferMgr'.
	 /*********************************************************************************************/

	/**
	 * Should create a connection to the given server & port
	 *
	 * @param $ftp_server server hostname / ip address
	 * @param $ftp_port server port
	 *
	 * @return the connection resource identifier
	 */
	abstract protected function doConnect($server, &$port);

	/**
	 * Should login to a previous initiatied connection with the user / pass given.
	 *
	 * @param $user username
	 * @param $pass <PASSWORD>
	 * @param $ftp_passive_mode passive mode true/false - relevant for FTP only
	 *
	 * @return true / false according to success
	 */
	abstract protected function doLogin($user, $pass, $ftp_passive_mode = TRUE);

	/**
	 * Should login to a previous initiatied connection with the given public key
	 *
	 * @param $user remote username
	 * @param $pubKeyFile public key file
	 * @param $privKeyFile  private key file
	 * @param $passphrase if $privKeyFile is encrypted (which it should be), the passphrase must be provided
	 *
	 * @return true / false according to success
	 */
	abstract protected function doLoginPubKey($user, $pubKeyFile, $privKeyFile, $passphrase = null);

	/**
	 * Should upload the given 'local_file' to the connected server with name 'remote_file'
	 *
	 * @param $remote_file remote file's name
	 * @param $local_file local file's name
	 * @param $ftp_mode ftp transfer mode (FTP_BINARY / FTP_ASCII) - relevant for FTP only
	 *
	 * @return true / false according to success
	 */
	abstract protected function doPutFile($remote_file, $local_file, $ftp_mode, $http_field_name = null, $http_file_name = null);

	/**
	 * Should download the fiven 'remote_file' from the server as 'local_file'
	 *
	 * @param $remote_file remote file's name
	 * @param $local_file local file's name
	 * @param $ftp_mode ftp transfer mode (FTP_BINARY / FTP_ASCII) - relevant for FTP only
	 *
	 * @return true / false according to success
	 */
	abstract protected function doGetFile ($remote_file, $local_file, $ftp_mode);

	/**
	 * Should create a new directory on the server.
	 *
	 * @param $remote_path
	 *
	 * @return true / false according to success
	 */
	abstract protected function doMkDir ($remote_path);

	/**
	 * Should delete the given file on the server.
	 *
	 * @param string $remote_file remote file's name
	 *
	 * @return true / false according to success
	 */
	abstract protected function doDelFile ($remote_file);

	/**
	 * Should delete the given directory on the server (including all its contents)
	 *
	 * @param string $remote_path remote directory's name
	 *
	 * @return true / false according to success
	 */
	abstract protected function doDelDir ($remote_path);



	/**
	 * Should chmod the given file with the given code
	 *
	 * @param $remote_file
	 * @param $chmod_code
	 *
	 * @return true / false according to success
	 */
	abstract protected function doChmod ($remote_file, $chmod_code);

	/**
	 * Should return true/false if the given file or directory exists on the server
	 *
	 * @param $remote_file
	 *
	 * @return true / false according to success
	 */
	abstract protected function doFileExists($remote_file);

	/**
	 * Should return the current working directory as a string
	 *
	 * @return a string of the current working directory's path
	 */
	abstract protected function doPwd();

	/**
	 * Should return an array of all elements
	 *
	 * @return an array of all elements
	 */

	abstract protected function doList ($remote_path);


	/********************/
	/* Public Functions */
	/********************/

	/**
	 * Create a new class instance according to the given type.
	 *
	 * @param fileTransferMgrTypes $type Class type from the list under 'kFileTransferMgrType' class.
	 *
	 * @return kFileTransferMgr a new instance
	 */
	public static function getInstance($type)
	{
		switch($type)
		{
			case kFileTransferMgrType::FTP:
				return new ftpMgr();

			case kFileTransferMgrType::SCP:
				return new scpMgr();

			case kFileTransferMgrType::SFTP:
				return new sftpMgr();

			case kFileTransferMgrType::HTTP:
			case kFileTransferMgrType::HTTPS:
				return new httpMgr();
		}

		return null;
	}


	/**
	 * Return the current connection identifier resource.
	 */
	public function getConnection ()
	{
		return $this->connection_id;
	}


	/**
	 * Connect & authenticate on the given server, using the given username & password.
	 *
	 * @param $server Server's hostname or IP address
	 * @param $user User's name
	 * @param $pass Password
	 * @param $port Server's listening port
	 * @param $ftp_passive_mode Used for FTP only
	 *
	 * @throws kFileTransferMgrException
	 *
	 * @return FILETRANSFERMGR_RES_OK / FILETRANSFERMGR_RES_ERR
	 */
	public function login ( $server, $user, $pass, $port = null, $ftp_passive_mode = true)
	{
		KalturaLog::debug("Login to server [$server] port [$port] username/password [$user/$pass] passive [$ftp_passive_mode]");
		
		$ftp_passive_mode = true;
		KalturaLog::debug("FTP passive mode changed to [true] because of a bug with ftp_put on fedora");
		
		$this->connection_id = @($this->doConnect($server, $port));
		if (!$this->connection_id) {
			$last_error = error_get_last();
			throw new kFileTransferMgrException ("Can't connect [$server:$port] - " . $last_error['message'], kFileTransferMgrException::cantConnect);
		}
		
		if(@($this->doLogin($user, $pass, $ftp_passive_mode)))
		{
			KalturaLog::debug("Logged in successfully");
		}
		else
		{
			$last_error = error_get_last();
			throw new kFileTransferMgrException ( "Can't authenticate [$user] - " . $last_error['message'], kFileTransferMgrException::cantAuthenticate);
		}
		$this->start_dir = kString::removeNewLine($this->doPwd());
	}


	/**
	 * Connect & authenticate on the given server, using the given given public key.
	 *
	 * @param $server Server's hostname or IP address
	 * @param $remoteUser remote username
	 * @param $pubKeyFile public key file
	 * @param $privKeyFile  private key file
	 * @param $port server's listening port
	 * @param $passphrase if $privKeyFile is encrypted (which it should be), the passphrase must be provided
	 *
	 * @throws kFileTransferMgrException
	 *
	 * @return FILETRANSFERMGR_RES_OK / FILETRANSFERMGR_RES_ERR
	 */
	public function loginPubKey ( $server, $user, $pubKeyFile, $privKeyFile, $passphrase = null, $port = null)
	{
		KalturaLog::debug("Login to server [$server] port [$port] username [$user] public key file [$pubKeyFile] private key file [$privKeyFile]");
		
		$this->connection_id = @($this->doConnect($server, $port));
		if (!$this->connection_id) {
			$last_error = error_get_last();
			throw new kFileTransferMgrException ("Can't connect [$server:$port] - " . $last_error['message'], kFileTransferMgrException::cantConnect);
		}
		
		if(@($this->doLoginPubKey($user, $pubKeyFile, $privKeyFile, $passphrase)))
		{
			KalturaLog::debug("Logged in successfully");
		}
		else
		{
			$last_error = error_get_last();
			throw new kFileTransferMgrException ( "Can't authenticate [$user] - " . $last_error['message'], kFileTransferMgrException::cantAuthenticate);
		}
		$this->start_dir = kString::removeNewLine($this->doPwd());
	}


	/**
	 * Upload a file to the server
	 *
	 * @param $remote_file Remote file name
	 * @param $local_file Local file name
	 * @param $overwrite true if should overwrite an existing remote file, or false otherwise
	 * @param $ftp_mode FTP_BINARY or FTP_ASCII - used for FTP only
	 *
	 * @throws kFileTransferMgrException
	 *
	 * @return FILETRANSFERMGR_RES_OK / FILETRANSFERMGR_RES_ERR
	 */
	public function putFile ($remote_file, $local_file, $overwrite = false, $ftp_mode = FTP_BINARY, $http_field_name = null, $http_file_name = null)
	{
		KalturaLog::debug("Puts file [$remote_file] from local [$local_file] overwrite [$overwrite]");
		
		// parameter checks
		if (!$this->connection_id) {
			throw new kFileTransferMgrException("No connection established yet.", kFileTransferMgrException::notYetConnected);
		}
		if (!file_exists($local_file)) {
			throw new kFileTransferMgrException("Can't find local file [$local_file]", kFileTransferMgrException::localFileNotExists);
		}
		if ($ftp_mode != FTP_ASCII)	{
			$ftp_mode = FTP_BINARY;
		}

		$remote_file = $this->fixPathString($remote_file);

		// delete existing file if overwrite == true
		$res = true;
		if ($overwrite) {
			if ($this->fileExists($remote_file)) {
				$res = @($this->delFile($remote_file));
			}
			// check if deletion was done succesfully
			if (!$res) {
				$last_error = error_get_last();
				throw new kFileTransferMgrException("Can't delete existing file [$remote_file] - " . $last_error['message'], kFileTransferMgrException::otherError);
				return self::FILETRANSFERMGR_RES_ERR;
			}
		}
		else { // $overwrite == false
			if ($this->fileExists($remote_file)) {
				throw new kFileTransferMgrException("Remote file [$remote_file] already exists.", kFileTransferMgrException::remoteFileExists);
			}
		}

		// create remote directory if necessary
		if (!$this->fileExists(dirname($remote_file))) {
			$this->mkDir(dirname($remote_file));
		}

		$remote_file  = trim($remote_file,'/');
		// try to upload file
		$res = @($this->doPutFile($remote_file, $local_file, $ftp_mode, $http_field_name, $http_file_name));

		$this->results = $res;
		
		// check response
		if ( !$res ) {
			$last_error = error_get_last();
			throw new kFileTransferMgrException("Can't put file [$remote_file] - " . $last_error['message'], kFileTransferMgrException::otherError);
		}
		
		KalturaLog::debug("File uploaded successfully");
		return self::FILETRANSFERMGR_RES_OK;
	}
	
	/**
	 * Download a file from the server
	 *
	 * @param $remote_file Remote file name
	 * @param $local_file Local file name
	 * @param $ftp_mode FTP_BINARY or FTP_ASCII - used for FTP only
	 *
	 * @throws kFileTransferMgrException
	 *
	 * @return FILETRANSFERMGR_RES_OK / FILETRANSFERMGR_RES_ERR
	 */
	public function getFile ( $remote_file, $local_file, $ftp_mode = FTP_BINARY)
	{
		KalturaLog::debug("Gets file [$remote_file] to local [$local_file]");
		
		// parameter checks
		if (!$this->connection_id) {
			throw new kFileTransferMgrException("No connection established yet.", kFileTransferMgrException::notYetConnected);
		}
		if ($ftp_mode != FTP_ASCII)	{
			$ftp_mode = FTP_BINARY;
		}

		$remote_file = $this->fixPathString($remote_file);

		// try to download file
		$res = @($this->doGetFile($remote_file, $local_file, $ftp_mode));

		$this->results = $res;
		
		// check response
		if ( ! $res ) {
			$last_error = error_get_last();
			throw new kFileTransferMgrException("Can't get file [$remote_file] - " . $last_error['message'], kFileTransferMgrException::otherError);
			return self::FILETRANSFERMGR_RES_ERR;
		}
		else
		{
			KalturaLog::debug("File retrieved successfully");
			return self::FILETRANSFERMGR_RES_OK;
		}
	}

	/**
	 * Create a new directory on the server
	 *
	 * @param $remote_path New directory path
	 *
	 * @throws kFileTransferMgrException
	 *
	 * @return FILETRANSFERMGR_RES_OK / FILETRANSFERMGR_RES_ERR
	 */
	public function mkDir ($remote_path)
	{
		KalturaLog::debug("Makes directory [$remote_path]");
		
		// parameter checks
		if (!$this->connection_id) {
			throw new kFileTransferMgrException("No connection established yet.", kFileTransferMgrException::notYetConnected);
		}
		if (strlen(trim($remote_path)) <= 0) {
			throw new kFileTransferMgrException("Remote path given is empty", kFileTransferMgrException::remotePathNotValid);
			return self::FILETRANSFERMGR_RES_ERR;
		}

		$remote_path = $this->fixPathString($remote_path);

		// recursivly try to create the new directory
		$temp_path = '';
		$split_path = explode("/", $remote_path);
		$res = true;
		$i = 0;
		$array_count = count($split_path);
		while ($res && $i < $array_count) {
			if (($split_path[$i] != null) && (trim($split_path[$i]) != '') )
			{
				$temp_path = $temp_path . $split_path[$i];
				if (!$this->fileExists($temp_path)) { // direcotry doesn't exist
{'fraction_non_alphanumeric': 0.13329577861493505, 'fraction_numerical': 0.001302679294440728, 'mean_word_length': 4.117837837837838, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '659789', 'n_tokens_mistral': 9491, 'n_tokens_neox': 8529, 'n_words': 2542}