Version 5.0.0 beta 1

This commit is contained in:
Neo committed 2025-12-19 16:27:35 -08:00
1 parent 25ddeb65d6
commit 15c7beabc5
6736 files changed
+627902 -497943

No files matched your search

+72 -65
View File
@@ -11,16 +11,24 @@
namespace IPS\Ftp;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use BadMethodCallException;
use IPS\Ftp;
use function defined;
use function extension_loaded;
use function in_array;
use const IPS\TEMP_DIRECTORY;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* SFTP Class
*/
class _Sftp extends \IPS\Ftp
class Sftp extends Ftp
{
/**
* @brief SSH2 Connection resource
@@ -35,58 +43,58 @@ class _Sftp extends \IPS\Ftp
/**
* @brief Current Directory
*/
protected $dir;
protected string $dir;
/**
* Constructor
*
* @param string $host Hostname
* @param string $username Username
* @param string $password Password
* @param int $port Port
* @param string $host Hostname
* @param string $username Username
* @param string $password Password
* @param int $port Port
* @return void
* @throws \IPS\Ftp\Exception
* @throws \BadMethodCallException If server does not have ssh
* @throws Exception
* @throws BadMethodCallException If server does not have ssh
*/
public function __construct( $host, $username, $password, $port=22 )
public function __construct( string $host, string $username, string $password, int $port=22 )
{
if ( !\extension_loaded( 'ssh2' ) )
if ( !extension_loaded( 'ssh2' ) )
{
throw new \BadMethodCallException;
throw new BadMethodCallException;
}
$this->ssh = ssh2_connect( $host, $port );
if ( $this->ssh === FALSE )
{
throw new \IPS\Ftp\Exception( 'COULD_NOT_CONNECT' );
throw new Exception( 'COULD_NOT_CONNECT' );
}
if ( !@ssh2_auth_password( $this->ssh, $username, $password ) )
{
throw new \IPS\Ftp\Exception( 'COULD_NOT_LOGIN' );
throw new Exception( 'COULD_NOT_LOGIN' );
}
$this->sftp = @ssh2_sftp( $this->ssh );
if ( $this->sftp === FALSE )
{
throw new \IPS\Ftp\Exception( 'COULD_NOT_CONNECT' );
throw new Exception( 'COULD_NOT_CONNECT' );
}
}
/**
* chdir
*
* @param string $dir Directory
* @param string $dir Directory
* @return void
* @throws \IPS\Ftp\Exception
* @throws Exception
*/
public function chdir( $dir )
public function chdir( string $dir ) : void
{
$dir = mb_substr( $dir, 0, 1 ) === '/' ? $dir : ( $this->dir . $dir );
if ( $dir and !@ssh2_sftp_stat( $this->sftp, $dir ) )
{
throw new \IPS\Ftp\Exception( 'COULD_NOT_CHDIR' );
throw new Exception( 'COULD_NOT_CHDIR' );
}
$this->dir = ssh2_sftp_realpath( $this->sftp, $dir ) . '/';
@@ -96,9 +104,9 @@ class _Sftp extends \IPS\Ftp
* cdup
*
* @return void
* @throws \IPS\Ftp\Exception
* @throws Exception
*/
public function cdup()
public function cdup() : void
{
$this->chdir( mb_substr( $this->dir, 0, mb_strrpos( mb_substr( $this->dir, 0, -1 ), '/' ) ) );
}
@@ -106,31 +114,31 @@ class _Sftp extends \IPS\Ftp
/**
* mkdir
*
* @param string $dir Directory
* @param string $dir Directory
* @return void
* @throws \IPS\Ftp\Exception
* @throws Exception
*/
public function mkdir( $dir )
public function mkdir( string $dir ) : void
{
if ( !@ssh2_sftp_mkdir( $this->sftp, $this->dir . $dir ) )
{
throw new \IPS\Ftp\Exception( 'COULD_NOT_MKDIR' );
throw new Exception( 'COULD_NOT_MKDIR' );
}
}
/**
* ls
*
* @param string $path Path
* @param string $path Path
* @return array|bool
*/
public function ls( $path = '' )
public function ls( string $path = '' ): bool|array
{
$return = array();
$handle = opendir("ssh2.sftp://{$this->sftp}/{$this->dir}");
while( $entry = readdir( $handle ) )
{
if ( !\in_array( $entry, array( '.', '..' ) ) )
if ( !in_array( $entry, array( '.', '..' ) ) )
{
$return[] = $entry;
}
@@ -141,17 +149,17 @@ class _Sftp extends \IPS\Ftp
/**
* Raw list
*
* @param string $path The path
* @param bool $recursive Whether or not to recursively list
* @param string $path The path
* @param bool $recursive Whether or not to recursively list
* @return array
*/
public function rawList( $path = '.', $recursive = FALSE )
public function rawList( string $path = '.', bool $recursive=FALSE ): array
{
$return = array();
$handle = opendir("ssh2.sftp://{$this->sftp}/{$this->dir}");
while( $entry = readdir( $handle ) )
{
if ( !\in_array( $entry, array( '.', '..' ) ) )
if ( !in_array( $entry, array( '.', '..' ) ) )
{
$bits = array();
$stats = @ssh2_sftp_stat( $this->sftp, $this->dir . $entry );
@@ -192,10 +200,10 @@ class _Sftp extends \IPS\Ftp
}
$bits[] = ( is_dir("ssh2.sftp://{$this->sftp}/{$this->dir}/{$entry}") ? 'd' : '-' ) . $perms;
$bits[] = isset( $stats['nlink'] ) ? $stats['nlink'] : 0;
$bits[] = isset( $stats['uid'] ) ? $stats['uid'] : 0;
$bits[] = isset( $stats['gid'] ) ? $stats['gid'] : 0;
$bits[] = isset( $stats['size'] ) ? $stats['size'] : 0;
$bits[] = $stats['nlink'] ?? 0;
$bits[] = $stats['uid'] ?? 0;
$bits[] = $stats['gid'] ?? 0;
$bits[] = $stats['size'] ?? 0;
$bits[] = isset( $stats['mtime'] ) ? date( 'd M H:i', $stats['mtime'] ) : 0;
$bits[] = $entry;
@@ -208,40 +216,39 @@ class _Sftp extends \IPS\Ftp
/**
* Upload File
*
* @param string $filename Filename to use
* @param string $file Path to local file
* @param string $filename Filename to use
* @param string $file Path to local file
* @return void
* @throws \IPS\Ftp\Exception
* @throws Exception
*/
public function upload( $filename, $file )
public function upload( string $filename, string $file ) : void
{
if ( !@ssh2_scp_send( $this->ssh, $file, $this->dir . $filename ) )
{
throw new \IPS\Ftp\Exception( 'COULD_NOT_UPLOAD' );
throw new Exception( 'COULD_NOT_UPLOAD' );
}
}
/**
* Download File
*
* @param string $filename The file to download
* @param string|null $target Location to save downloaded file or NULL to return contents
* @param bool $returnPath Return the path to the downloaded file instead of the contents
* @return string File contents
* @throws \IPS\Ftp\Exception
* @param string $filename The file to download
* @param string|null $target Location to save downloaded file or NULL to return contents
* @param bool $returnPath Return the path to the downloaded file instead of the contents
* @return string|null File contents
*/
public function download( $filename, $target=NULL, $returnPath=FALSE )
public function download( string $filename, string $target=NULL, bool $returnPath=FALSE ): ?string
{
$temp = FALSE;
if ( $target === NULL )
{
$temp = TRUE;
$target = tempnam( \IPS\TEMP_DIRECTORY, 'IPS' );
$target = tempnam( TEMP_DIRECTORY, 'IPS' );
}
if ( !@ssh2_scp_recv( $this->ssh, $this->dir . $filename, $target ) )
{
throw new \IPS\Ftp\Exception( 'COULD_NOT_DOWNLOAD' );
throw new Exception( 'COULD_NOT_DOWNLOAD' );
}
/* We use this to avoid out of memory errors - just return path */
@@ -263,25 +270,25 @@ class _Sftp extends \IPS\Ftp
/**
* Delete file
*
* @param string $file Path to file
* @param string $file Path to file
* @return void
* @throws \IPS\Ftp\Exception
* @throws Exception
*/
public function delete( $file )
public function delete( string $file ) : void
{
if ( !@ssh2_sftp_unlink( $this->sftp, $this->dir . $file ) )
{
throw new \IPS\Ftp\Exception( 'COULD_NOT_DELETE' );
throw new Exception( 'COULD_NOT_DELETE' );
}
}
/**
* Get file size (if possible)
*
* @param string $file Path to file
* @return float
* @param string $file Path to file
* @return float|int
*/
public function size( $file )
public function size( string $file ): float|int
{
if( $stats = @ssh2_sftp_stat( $this->sftp, $this->dir . $file ) )
{
@@ -297,24 +304,24 @@ class _Sftp extends \IPS\Ftp
/**
* Delete directory
*
* @param string $dir Path to directory
* @param bool $recursive Recursive? (If FALSE and directory is not empty, operation will fail)
* @param string $dir Path to directory
* @param bool $recursive Recursive? (If FALSE and directory is not empty, operation will fail)
* @return void
* @throws \IPS\Ftp\Exception
* @throws Exception
*/
public function rmdir( $dir, $recursive=FALSE )
public function rmdir( string $dir, bool $recursive=FALSE ) : void
{
if ( $recursive )
{
$this->chdir( $dir );
foreach ( $this->rawList() as $data )
foreach ($this->rawList() as $data )
{
preg_match( '/^(.).*\s(.*)$/', $data, $matches );
if ( $matches[2] !== '.' and $matches[2] !== '..' )
{
if ( $matches[1] === 'd' )
{
$this->rmdir( $matches[2], TRUE );
$this->rmdir($matches[2], TRUE);
}
else
{
@@ -327,7 +334,7 @@ class _Sftp extends \IPS\Ftp
if ( !@ssh2_sftp_rmdir( $this->sftp, $this->dir . $dir ) )
{
throw new \IPS\Ftp\Exception( 'COULD_NOT_DELETE' );
throw new Exception( 'COULD_NOT_DELETE' );
}
}
}