Skip to content

Instantly share code, notes, and snippets.

@robertuniqid
Created May 9, 2016 20:58
Show Gist options
  • Save robertuniqid/424c4c8f683fd36a37d01b2d01bb222c to your computer and use it in GitHub Desktop.
Save robertuniqid/424c4c8f683fd36a37d01b2d01bb222c to your computer and use it in GitHub Desktop.
PHP FTP Connection Helper ( including sorting like Filezilla )
<?php
// Not the most optimal solution, but it's the best for the way I need it.
class DirectoryNavigationFTP {
public $connectionEntity;
/**
* @var bool|resource
*/
public $connectionHandler = false;
public $connection_id;
public $level_limit = 5;
public function __construct( $connection_id ) {
$this->connection_id = ( is_object( $connection_id) ? $connection_id->id : $connection_id );
if( is_object( $connection_id ) )
$this->connectionEntity = $connection_id;
else
$this->connectionEntity = FTPConnection::findOrFail( $connection_id );
$this->setupConnection();
}
public function close() {
if( $this->connectionHandler == false )
return true;
ftp_close( $this->connectionHandler );
$this->connectionHandler = false;
return true;
}
/**
* @param string $path
* @param int $depth
* @return array
*/
public function getDirectoryList( $path = '/', $depth = 0 ) {
return $this->getList( $path, true, $depth );
}
public function getList( $path = '/', $directories_only = true, $depth = 0 ) {
$path = rtrim( $path, '/' ) . '/';
$file_list = @ftp_rawlist( $this->connectionHandler, $path );
$response = [];
foreach ($file_list as $file_information ) {
if( substr( $file_information, 0, 1 ) != 'd' && $directories_only )
continue;
$directory = substr( $file_information, strrpos( $file_information, ' ' ) + 1 );
if( $directory == '.' || $directory == '..' ) continue;
$response[$directory] = ( substr( $file_information, 0, 1 ) != 'd' ?
$file_information : ( $depth > 0 ? $this->getList( $path . $directory, $directories_only, $depth - 1 ) : !$this->_isEmptyDirectory( $path . $directory ) )
);
}
return empty( $response ) ? false : ( $directories_only ? $response : $this->sortFileList( $response ) );
}
private function sortFileList( $response ) {
$directory_list = [];
$file_list = [];
foreach( $response as $index => $information ) {
if( $information === true || is_array( $information ) )
$directory_list[$index] = $information;
else
$file_list[$index] = $information;
}
// Optionally ksort each array, not needed right now.
return $directory_list + $file_list;
}
private function _isEmptyDirectory( $path ) {
$file_list = ftp_nlist( $this->connectionHandler, $path );
return count( $file_list ) <= 2;
}
/**
* @param $path_list
* @param $save_path
* @return bool
*/
public function download( $path_list, $save_path ) {
if( is_array( $path_list ) ) {
foreach( $path_list as $path )
if( $path != '' )
$this->downloadFiles( $path, $save_path );
} else {
ftp_chdir($this->connectionHandler, dirname( $path_list ) );
ftp_get($this->connectionHandler, $save_path, basename($path_list), FTP_BINARY );
}
return true;
}
/**
* @param $path
* @param $save_path
*/
public function downloadFiles( $path, $save_path ) {
$file_list = ftp_nlist($this->connectionHandler, $path);
if( !file_exists($save_path . '/' . trim($path, "/" ) ) )
mkdir( $save_path . '/' . trim($path, "/" ), 0777, true);
foreach( $file_list as $file ) {
if( in_array( $file, [ '.', '..', '.ftpquota' ] ) )
continue;
$is_dir = @ftp_chdir( $this->connectionHandler, $path . '/' . $file );
if ( $is_dir ) {
$this->downloadFiles($path . '/' . $file, $save_path );
continue;
}
ftp_chdir($this->connectionHandler, $path);
ftp_get($this->connectionHandler, $save_path . '/' . $path . '/' . $file, $file, FTP_BINARY );
}
}
/**
* @param $local_file
* @param $remote_destination
* @return bool
*/
public function uploadFile($local_file, $remote_destination ) {
$fp = ( is_string( $local_file ) ? fopen( $local_file, 'r') : $local_file );
$result = ftp_fput( $this->connectionHandler, $remote_destination, $fp, FTP_BINARY );
fclose($fp);
return $result;
}
/**
* @param $local_path
* @param $upload_path
* @return bool
*/
public function uploadFiles( $local_path, $upload_path ) {
$local_path = rtrim( $local_path, "/" );
$upload_path = rtrim( $upload_path, '/' );
foreach( scandir($local_path) as $file_name ) {
if( in_array( $file_name, [ '.', '..' ] ) )
continue;
if( is_dir( $local_path . '/' . $file_name ) ) {
$is_dir = @ftp_chdir( $this->connectionHandler, $upload_path . '/' . $file_name );
if ( !$is_dir )
ftp_mkdir( $this->connectionHandler, $upload_path . '/' . $file_name );
$this->uploadFiles( $local_path . '/' . $file_name, $upload_path . '/' . $file_name );
continue;
}
$this->uploadFile( $local_path . '/' . $file_name, $upload_path . '/' . $file_name );
}
return true;
}
/**
* @param $file_path
* @return string
*/
public function getDownloadPath( $file_path ) {
$result = 'ftp://' . $this->connectionEntity->server_user . ":" . $this->connectionEntity->server_password . '@' . $this->connectionEntity->server_address . $file_path;
return $result;
}
/**
* @param $file_path
* @return bool
*/
public function deleteFile( $file_path ) {
$result = @ftp_delete( $this->connectionHandler, $file_path );
return $result;
}
/**
* @param $directory
* @return bool
*/
public function deleteDirectory( $directory ) {
if( $directory == '' ) {
return false;
}
$is_dir = @ftp_chdir( $this->connectionHandler, $directory );
if( $is_dir ) {
$file_list = @ftp_nlist( $this->connectionHandler, $directory );
foreach($file_list as $file) {
if( trim( $file, '.' ) == '' )
continue;
$this->deleteDirectory($directory . '/' . $file );
}
@ftp_rmdir( $this->connectionHandler, $directory );
} else {
$this->deleteFile( $directory );
}
return true;
}
private function setupConnection() {
if( $this->connectionHandler != false )
return true;
$this->connectionHandler = ftp_connect( $this->connectionEntity->server_address );
$response = ftp_login( $this->connectionHandler, $this->connectionEntity->server_user, $this->connectionEntity->server_password );
if( !$response ) {
$this->connectionHandler = false;
return false;
}
ftp_pasv( $this->connectionHandler, true );
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment