📦 Updating compiled files or packages.

This commit is contained in:
wisp-x
2019-10-31 12:00:26 +08:00
parent 075c2141c6
commit c65787f9e8
20 changed files with 1666 additions and 3 deletions

View File

@@ -23,7 +23,8 @@
"upyun/sdk": "^3.3",
"qcloud/cos-sdk-v5": "^1.2",
"topthink/think-image": "^1.0",
"phpmailer/phpmailer": "^6.0"
"phpmailer/phpmailer": "^6.0",
"nicolab/php-ftp-client": "^1.5"
},
"autoload": {
"psr-4": {

57
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "f3a07db17ca2f758f19303939f3bb3d6",
"content-hash": "fb6ffef3fc6c84854a1c9c891746c6e1",
"packages": [
{
"name": "aliyuncs/oss-sdk-php",
@@ -361,6 +361,61 @@
],
"time": "2019-07-01T23:21:34+00:00"
},
{
"name": "nicolab/php-ftp-client",
"version": "v1.5.1",
"source": {
"type": "git",
"url": "https://github.com/Nicolab/php-ftp-client.git",
"reference": "8c66e1104da1b638f5d7a9e24624a5525b459a0c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Nicolab/php-ftp-client/zipball/8c66e1104da1b638f5d7a9e24624a5525b459a0c",
"reference": "8c66e1104da1b638f5d7a9e24624a5525b459a0c",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-ftp": "*",
"php": ">=5.4"
},
"type": "library",
"autoload": {
"psr-0": {
"FtpClient": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Tallefourtane",
"email": "dev@nicolab.net",
"homepage": "http://nicolab.net"
}
],
"description": "A flexible FTP and SSL-FTP client for PHP. This lib provides helpers easy to use to manage the remote files.",
"homepage": "https://github.com/Nicolab/php-ftp-client",
"keywords": [
"file",
"ftp",
"helper",
"lib",
"server",
"sftp",
"ssl",
"ssl-ftp"
],
"time": "2019-04-23T09:22:37+00:00"
},
{
"name": "phpmailer/phpmailer",
"version": "v6.1.1",

View File

@@ -29,4 +29,8 @@ return [
'name' => '又拍云USS',
'class' => \strategy\driver\Uss::class
],
'remote' => [
'name' => '远程',
'class' => \strategy\driver\Remote::class
],
];

View File

@@ -153,11 +153,18 @@ INSERT INTO `lsky_config` (`id`, `key`, `type`, `input_type`, `name`, `title`, `
(NULL, 'uss', 'text', 'text', 'uss_operator_name', 'OperatorName', '操作员账号', '', ''),
(NULL, 'uss', 'text', 'password', 'uss_operator_pwd', 'OperatorPwd', '操作员密码', '', ''),
(NULL, 'uss', 'text', 'text', 'uss_service_name', 'ServiceName', '云储存服务名称', '', ''),
(NULL, 'basics', 'textarea', 'textarea', 'notice', '系统公告', '支持html', '', ''),
(NULL, 'remote', 'text', 'text', 'remote_cdn_domain', '域名', NULL, '', ''),
(NULL, 'remote', 'select', 'text', 'remote_type', '远程储存类型', NULL, 'ftp', '{\"ftp\":\"ftp\"}'),
(NULL, 'remote', 'text', 'text', 'remote_host', '连接地址', NULL, '', ''),
(NULL, 'remote', 'text', 'text', 'remote_name', '登录账号', NULL, '', ''),
(NULL, 'remote', 'text', 'password', 'remote_password', '登录密码', NULL, '', ''),
(NULL, 'remote', 'text', 'number', 'remote_port', '连接端口', NULL, '21', ''),
(NULL, 'audit', 'bool', 'checkbox', 'open_audit', '开启图片鉴黄', '接口申请地址:<a href="https://www.moderatecontent.com" target="_blank">https://www.moderatecontent.com</a>', '0', ''),
(NULL, 'audit', 'text', 'text', 'audit_key', 'Key', NULL, '', ''),
(NULL, 'audit', 'select', 'text', 'audit_index', '内容评级', '1=所有人2=少年3=成人', '3', '{\"1\": \"所有人\", \"2\": \"少年\", \"3\": \"成人\"}'),
(NULL, '', 'text', 'text', 'system_version', '系统版本', NULL, '1.5.4', '');
(NULL, '', 'text', 'text', 'system_version', '系统版本', NULL, '1.5.5', '');
INSERT INTO `lsky_group` (`id`, `strategy`, `name`, `default`, `update_time`, `create_time`) VALUES (NULL, 'local', '默认组', '1', '0', '0');

View File

@@ -76,3 +76,14 @@ UPDATE `lsky_config` SET `value` = '1.5.3' WHERE `lsky_config`.`name` = 'system_
-- v1.5.4
UPDATE `lsky_config` SET `value` = '1.5.4' WHERE `lsky_config`.`name` = 'system_version';
-- v1.5.5
UPDATE `lsky_config` SET `value` = '1.5.5' WHERE `lsky_config`.`name` = 'system_version';
INSERT IGNORE INTO `lsky_config` (`id`, `key`, `type`, `input_type`, `name`, `title`, `tip`, `value`, `extend`) VALUES
(NULL, 'basics', 'textarea', 'textarea', 'notice', '系统公告', '支持html', '', ''),
(NULL, 'remote', 'text', 'text', 'remote_cdn_domain', '域名', NULL, '', ''),
(NULL, 'remote', 'select', 'text', 'remote_type', '远程储存类型', NULL, 'ftp', '{\"ftp\":\"Ftp\"}'),
(NULL, 'remote', 'text', 'text', 'remote_host', '连接地址', NULL, '', ''),
(NULL, 'remote', 'text', 'text', 'remote_name', '登录账号', NULL, '', ''),
(NULL, 'remote', 'text', 'password', 'remote_password', '登录密码', NULL, '', ''),
(NULL, 'remote', 'text', 'number', 'remote_port', '连接端口', NULL, '21', '');

View File

@@ -9,4 +9,5 @@ return array(
'Qcloud\\Cos\\' => array($vendorDir . '/qcloud/cos-sdk-v5/src'),
'Guzzle\\Tests' => array($vendorDir . '/guzzle/guzzle/tests'),
'Guzzle' => array($vendorDir . '/guzzle/guzzle/src'),
'FtpClient' => array($vendorDir . '/nicolab/php-ftp-client/src'),
);

View File

@@ -129,6 +129,13 @@ class ComposerStaticInitf1a511e38c2f284964a16f1eeccf1745
0 => __DIR__ . '/..' . '/guzzle/guzzle/src',
),
),
'F' =>
array (
'FtpClient' =>
array (
0 => __DIR__ . '/..' . '/nicolab/php-ftp-client/src',
),
),
);
public static function getInitializer(ClassLoader $loader)

View File

@@ -364,6 +364,63 @@
"url"
]
},
{
"name": "nicolab/php-ftp-client",
"version": "v1.5.1",
"version_normalized": "1.5.1.0",
"source": {
"type": "git",
"url": "https://github.com/Nicolab/php-ftp-client.git",
"reference": "8c66e1104da1b638f5d7a9e24624a5525b459a0c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Nicolab/php-ftp-client/zipball/8c66e1104da1b638f5d7a9e24624a5525b459a0c",
"reference": "8c66e1104da1b638f5d7a9e24624a5525b459a0c",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-ftp": "*",
"php": ">=5.4"
},
"time": "2019-04-23T09:22:37+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"FtpClient": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Tallefourtane",
"email": "dev@nicolab.net",
"homepage": "http://nicolab.net"
}
],
"description": "A flexible FTP and SSL-FTP client for PHP. This lib provides helpers easy to use to manage the remote files.",
"homepage": "https://github.com/Nicolab/php-ftp-client",
"keywords": [
"file",
"ftp",
"helper",
"lib",
"server",
"sftp",
"ssl",
"ssl-ftp"
]
},
{
"name": "phpmailer/phpmailer",
"version": "v6.1.1",

View File

@@ -0,0 +1,7 @@
/vendor
composer.phar
composer.lock
.DS_Store
Thumbs.db
/.Trash-1000
.idea/

22
vendor/nicolab/php-ftp-client/LICENSE vendored Normal file
View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2014 Nicolas Tallefourtane dev@nicolab.net
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

249
vendor/nicolab/php-ftp-client/README.md vendored Normal file
View File

@@ -0,0 +1,249 @@
# nicolab/php-ftp-client
A flexible FTP and SSL-FTP client for PHP.
This lib provides helpers easy to use to manage the remote files.
> This package is aimed to remain simple and light. It's only a wrapper of the FTP native API of PHP, with some useful helpers. If you want to customize some methods, you can do this by inheriting one of the [3 classes of the package](src/FtpClient).
## Install
* Use composer: _require_ `nicolab/php-ftp-client`
* Or use GIT clone command: `git clone git@github.com:Nicolab/php-ftp-client.git`
* Or download the library, configure your autoloader or include the 3 files of `php-ftp-client/src/FtpClient` directory.
## Getting Started
Connect to a server FTP :
```php
$ftp = new \FtpClient\FtpClient();
$ftp->connect($host);
$ftp->login($login, $password);
```
OR
Connect to a server FTP via SSL (on port 990 or another port) :
```php
$ftp = new \FtpClient\FtpClient();
$ftp->connect($host, true, 990);
$ftp->login($login, $password);
```
Note: The connection is implicitly closed at the end of script execution (when the object is destroyed). Therefore it is unnecessary to call `$ftp->close()`, except for an explicit re-connection.
### Usage
Upload all files and all directories is easy :
```php
// upload with the BINARY mode
$ftp->putAll($source_directory, $target_directory);
// Is equal to
$ftp->putAll($source_directory, $target_directory, FTP_BINARY);
// or upload with the ASCII mode
$ftp->putAll($source_directory, $target_directory, FTP_ASCII);
```
*Note : FTP_ASCII and FTP_BINARY are predefined PHP internal constants.*
Get a directory size :
```php
// size of the current directory
$size = $ftp->dirSize();
// size of a given directory
$size = $ftp->dirSize('/path/of/directory');
```
Count the items in a directory :
```php
// count in the current directory
$total = $ftp->count();
// count in a given directory
$total = $ftp->count('/path/of/directory');
// count only the "files" in the current directory
$total_file = $ftp->count('.', 'file');
// count only the "files" in a given directory
$total_file = $ftp->count('/path/of/directory', 'file');
// count only the "directories" in a given directory
$total_dir = $ftp->count('/path/of/directory', 'directory');
// count only the "symbolic links" in a given directory
$total_link = $ftp->count('/path/of/directory', 'link');
```
Detailed list of all files and directories :
```php
// scan the current directory and returns the details of each item
$items = $ftp->scanDir();
// scan the current directory (recursive) and returns the details of each item
var_dump($ftp->scanDir('.', true));
```
Result:
'directory#www' =>
array (size=10)
'permissions' => string 'drwx---r-x' (length=10)
'number' => string '3' (length=1)
'owner' => string '32385' (length=5)
'group' => string 'users' (length=5)
'size' => string '5' (length=1)
'month' => string 'Nov' (length=3)
'day' => string '24' (length=2)
'time' => string '17:25' (length=5)
'name' => string 'www' (length=3)
'type' => string 'directory' (length=9)
'link#www/index.html' =>
array (size=11)
'permissions' => string 'lrwxrwxrwx' (length=10)
'number' => string '1' (length=1)
'owner' => string '0' (length=1)
'group' => string 'users' (length=5)
'size' => string '38' (length=2)
'month' => string 'Nov' (length=3)
'day' => string '16' (length=2)
'time' => string '14:57' (length=5)
'name' => string 'index.html' (length=10)
'type' => string 'link' (length=4)
'target' => string '/var/www/shared/index.html' (length=26)
'file#www/README' =>
array (size=10)
'permissions' => string '-rw----r--' (length=10)
'number' => string '1' (length=1)
'owner' => string '32385' (length=5)
'group' => string 'users' (length=5)
'size' => string '0' (length=1)
'month' => string 'Nov' (length=3)
'day' => string '24' (length=2)
'time' => string '17:25' (length=5)
'name' => string 'README' (length=6)
'type' => string 'file' (length=4)
All FTP PHP functions are supported and some improved :
```php
// Requests execution of a command on the FTP server
$ftp->exec($command);
// Turns passive mode on or off
$ftp->pasv(true);
// Set permissions on a file via FTP
$ftp->chmod(0777, 'file.php');
// Removes a directory
$ftp->rmdir('path/of/directory/to/remove');
// Removes a directory (recursive)
$ftp->rmdir('path/of/directory/to/remove', true);
// Creates a directory
$ftp->mkdir('path/of/directory/to/create');
// Creates a directory (recursive),
// creates automaticaly the sub directory if not exist
$ftp->mkdir('path/of/directory/to/create', true);
// and more ...
```
Get the help information of remote FTP server :
```php
var_dump($ftp->help());
```
Result :
array (size=6)
0 => string '214-The following SITE commands are recognized' (length=46)
1 => string ' ALIAS' (length=6)
2 => string ' CHMOD' (length=6)
3 => string ' IDLE' (length=5)
4 => string ' UTIME' (length=6)
5 => string '214 Pure-FTPd - http://pureftpd.org/' (length=36)
_Note : The result depend of FTP server._
### Extend
Create your custom `FtpClient`.
```php
// MyFtpClient.php
/**
* My custom FTP Client
* @inheritDoc
*/
class MyFtpClient extends \FtpClient\FtpClient {
public function removeByTime($path, $timestamp) {
// your code here
}
public function search($regex) {
// your code here
}
}
```
```php
// example.php
$ftp = new MyFtpClient();
$ftp->connect($host);
$ftp->login($login, $password);
// remove the old files
$ftp->removeByTime('/www/mysite.com/demo', time() - 86400));
// search PNG files
$ftp->search('/(.*)\.png$/i');
```
## API doc
See the [source code](https://github.com/Nicolab/php-ftp-client/tree/master/src/FtpClient) for more details.
It is fully documented :blue_book:
## Testing
Tested with "atoum" unit testing framework.
## License
[MIT](https://github.com/Nicolab/php-ftp-client/blob/master/LICENSE) c) 2014, Nicolas Tallefourtane.
## Author
| [![Nicolas Tallefourtane - Nicolab.net](http://www.gravatar.com/avatar/d7dd0f4769f3aa48a3ecb308f0b457fc?s=64)](http://nicolab.net) |
|---|
| [Nicolas Talle](http://nicolab.net) |
| [![Make a donation via Paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=PGRH4ZXP36GUC) |

View File

@@ -0,0 +1,23 @@
{
"name": "nicolab/php-ftp-client",
"type": "library",
"description": "A flexible FTP and SSL-FTP client for PHP. This lib provides helpers easy to use to manage the remote files.",
"license": "MIT",
"keywords": ["ftp", "sftp", "ssl-ftp", "ssl", "file", "server", "lib", "helper"],
"homepage": "https://github.com/Nicolab/php-ftp-client",
"authors" : [
{
"name" : "Nicolas Tallefourtane",
"email" : "dev@nicolab.net",
"homepage" : "http://nicolab.net"
}
],
"require": {
"php": ">=5.4",
"ext-ftp": "*"
},
"autoload": {
"psr-0": {"FtpClient": "src/"}
}
}

View File

@@ -0,0 +1,938 @@
<?php
/*
* This file is part of the `nicolab/php-ftp-client` package.
*
* (c) Nicolas Tallefourtane <dev@nicolab.net>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Nicolas Tallefourtane http://nicolab.net
*/
namespace FtpClient;
use \Countable;
/**
* The FTP and SSL-FTP client for PHP.
*
* @method bool alloc() alloc(int $filesize, string &$result = null) Allocates space for a file to be uploaded
* @method bool cdup() cdup() Changes to the parent directory
* @method bool chdir() chdir(string $directory) Changes the current directory on a FTP server
* @method int chmod() chmod(int $mode, string $filename) Set permissions on a file via FTP
* @method bool delete() delete(string $path) Deletes a file on the FTP server
* @method bool exec() exec(string $command) Requests execution of a command on the FTP server
* @method bool fget() fget(resource $handle, string $remote_file, int $mode, int $resumepos = 0) Downloads a file from the FTP server and saves to an open file
* @method bool fput() fput(string $remote_file, resource $handle, int $mode, int $startpos = 0) Uploads from an open file to the FTP server
* @method mixed get_option() get_option(int $option) Retrieves various runtime behaviours of the current FTP stream
* @method bool get() get(string $local_file, string $remote_file, int $mode, int $resumepos = 0) Downloads a file from the FTP server
* @method int mdtm() mdtm(string $remote_file) Returns the last modified time of the given file
* @method int nb_continue() nb_continue() Continues retrieving/sending a file (non-blocking)
* @method int nb_fget() nb_fget(resource $handle, string $remote_file, int $mode, int $resumepos = 0) Retrieves a file from the FTP server and writes it to an open file (non-blocking)
* @method int nb_fput() nb_fput(string $remote_file, resource $handle, int $mode, int $startpos = 0) Stores a file from an open file to the FTP server (non-blocking)
* @method int nb_get() nb_get(string $local_file, string $remote_file, int $mode, int $resumepos = 0) Retrieves a file from the FTP server and writes it to a local file (non-blocking)
* @method int nb_put() nb_put(string $remote_file, string $local_file, int $mode, int $startpos = 0) Stores a file on the FTP server (non-blocking)
* @method bool pasv() pasv(bool $pasv) Turns passive mode on or off
* @method bool put() put(string $remote_file, string $local_file, int $mode, int $startpos = 0) Uploads a file to the FTP server
* @method string pwd() pwd() Returns the current directory name
* @method bool quit() quit() Closes an FTP connection
* @method array raw() raw(string $command) Sends an arbitrary command to an FTP server
* @method bool rename() rename(string $oldname, string $newname) Renames a file or a directory on the FTP server
* @method bool set_option() set_option(int $option, mixed $value) Set miscellaneous runtime FTP options
* @method bool site() site(string $command) Sends a SITE command to the server
* @method int size() size(string $remote_file) Returns the size of the given file
* @method string systype() systype() Returns the system type identifier of the remote FTP server
*
* @author Nicolas Tallefourtane <dev@nicolab.net>
*/
class FtpClient implements Countable
{
/**
* The connection with the server.
*
* @var resource
*/
protected $conn;
/**
* PHP FTP functions wrapper.
*
* @var FtpWrapper
*/
private $ftp;
/**
* Constructor.
*
* @param resource|null $connection
* @throws FtpException If FTP extension is not loaded.
*/
public function __construct($connection = null)
{
if (!extension_loaded('ftp')) {
throw new FtpException('FTP extension is not loaded!');
}
if ($connection) {
$this->conn = $connection;
}
$this->setWrapper(new FtpWrapper($this->conn));
}
/**
* Close the connection when the object is destroyed.
*/
public function __destruct()
{
if ($this->conn) {
$this->ftp->close();
}
}
/**
* Call an internal method or a FTP method handled by the wrapper.
*
* Wrap the FTP PHP functions to call as method of FtpClient object.
* The connection is automaticaly passed to the FTP PHP functions.
*
* @param string $method
* @param array $arguments
* @return mixed
* @throws FtpException When the function is not valid
*/
public function __call($method, array $arguments)
{
return $this->ftp->__call($method, $arguments);
}
/**
* Overwrites the PHP limit
*
* @param string|null $memory The memory limit, if null is not modified
* @param int $time_limit The max execution time, unlimited by default
* @param bool $ignore_user_abort Ignore user abort, true by default
* @return FtpClient
*/
public function setPhpLimit($memory = null, $time_limit = 0, $ignore_user_abort = true)
{
if (null !== $memory) {
ini_set('memory_limit', $memory);
}
ignore_user_abort($ignore_user_abort);
set_time_limit($time_limit);
return $this;
}
/**
* Get the help information of the remote FTP server.
*
* @return array
*/
public function help()
{
return $this->ftp->raw('help');
}
/**
* Open a FTP connection.
*
* @param string $host
* @param bool $ssl
* @param int $port
* @param int $timeout
*
* @return FtpClient
* @throws FtpException If unable to connect
*/
public function connect($host, $ssl = false, $port = 21, $timeout = 90)
{
if ($ssl) {
$this->conn = $this->ftp->ssl_connect($host, $port, $timeout);
} else {
$this->conn = $this->ftp->connect($host, $port, $timeout);
}
if (!$this->conn) {
throw new FtpException('Unable to connect');
}
return $this;
}
/**
* Closes the current FTP connection.
*
* @return bool
*/
public function close()
{
if ($this->conn) {
$this->ftp->close();
$this->conn = null;
}
}
/**
* Get the connection with the server.
*
* @return resource
*/
public function getConnection()
{
return $this->conn;
}
/**
* Get the wrapper.
*
* @return FtpWrapper
*/
public function getWrapper()
{
return $this->ftp;
}
/**
* Logs in to an FTP connection.
*
* @param string $username
* @param string $password
*
* @return FtpClient
* @throws FtpException If the login is incorrect
*/
public function login($username = 'anonymous', $password = '')
{
$result = $this->ftp->login($username, $password);
if ($result === false) {
throw new FtpException('Login incorrect');
}
return $this;
}
/**
* Returns the last modified time of the given file.
* Return -1 on error
*
* @param string $remoteFile
* @param string|null $format
*
* @return int
*/
public function modifiedTime($remoteFile, $format = null)
{
$time = $this->ftp->mdtm($remoteFile);
if ($time !== -1 && $format !== null) {
return date($format, $time);
}
return $time;
}
/**
* Changes to the parent directory.
*
* @throws FtpException
* @return FtpClient
*/
public function up()
{
$result = $this->ftp->cdup();
if ($result === false) {
throw new FtpException('Unable to get parent folder');
}
return $this;
}
/**
* Returns a list of files in the given directory.
*
* @param string $directory The directory, by default is "." the current directory
* @param bool $recursive
* @param callable $filter A callable to filter the result, by default is asort() PHP function.
* The result is passed in array argument,
* must take the argument by reference !
* The callable should proceed with the reference array
* because is the behavior of several PHP sorting
* functions (by reference ensure directly the compatibility
* with all PHP sorting functions).
*
* @return array
* @throws FtpException If unable to list the directory
*/
public function nlist($directory = '.', $recursive = false, $filter = 'sort')
{
if (!$this->isDir($directory)) {
throw new FtpException('"'.$directory.'" is not a directory');
}
$files = $this->ftp->nlist($directory);
if ($files === false) {
throw new FtpException('Unable to list directory');
}
$result = array();
$dir_len = strlen($directory);
// if it's the current
if (false !== ($kdot = array_search('.', $files))) {
unset($files[$kdot]);
}
// if it's the parent
if(false !== ($kdot = array_search('..', $files))) {
unset($files[$kdot]);
}
if (!$recursive) {
$result = $files;
// working with the reference (behavior of several PHP sorting functions)
$filter($result);
return $result;
}
// utils for recursion
$flatten = function (array $arr) use (&$flatten) {
$flat = [];
foreach ($arr as $k => $v) {
if (is_array($v)) {
$flat = array_merge($flat, $flatten($v));
} else {
$flat[] = $v;
}
}
return $flat;
};
foreach ($files as $file) {
$file = $directory.'/'.$file;
// if contains the root path (behavior of the recursivity)
if (0 === strpos($file, $directory, $dir_len)) {
$file = substr($file, $dir_len);
}
if ($this->isDir($file)) {
$result[] = $file;
$items = $flatten($this->nlist($file, true, $filter));
foreach ($items as $item) {
$result[] = $item;
}
} else {
$result[] = $file;
}
}
$result = array_unique($result);
$filter($result);
return $result;
}
/**
* Creates a directory.
*
* @see FtpClient::rmdir()
* @see FtpClient::remove()
* @see FtpClient::put()
* @see FtpClient::putAll()
*
* @param string $directory The directory
* @param bool $recursive
* @return array
*/
public function mkdir($directory, $recursive = false)
{
if (!$recursive or $this->isDir($directory)) {
return $this->ftp->mkdir($directory);
}
$result = false;
$pwd = $this->ftp->pwd();
$parts = explode('/', $directory);
foreach ($parts as $part) {
if ($part == '') {
continue;
}
if (!@$this->ftp->chdir($part)) {
$result = $this->ftp->mkdir($part);
$this->ftp->chdir($part);
}
}
$this->ftp->chdir($pwd);
return $result;
}
/**
* Remove a directory.
*
* @see FtpClient::mkdir()
* @see FtpClient::cleanDir()
* @see FtpClient::remove()
* @see FtpClient::delete()
* @param string $directory
* @param bool $recursive Forces deletion if the directory is not empty
* @return bool
* @throws FtpException If unable to list the directory to remove
*/
public function rmdir($directory, $recursive = true)
{
if ($recursive) {
$files = $this->nlist($directory, false, 'rsort');
// remove children
foreach ($files as $file) {
$this->remove($file, true);
}
}
// remove the directory
return $this->ftp->rmdir($directory);
}
/**
* Empty directory.
*
* @see FtpClient::remove()
* @see FtpClient::delete()
* @see FtpClient::rmdir()
*
* @param string $directory
* @return bool
*/
public function cleanDir($directory)
{
if (!$files = $this->nlist($directory)) {
return $this->isEmpty($directory);
}
// remove children
foreach ($files as $file) {
$this->remove($file, true);
}
return $this->isEmpty($directory);
}
/**
* Remove a file or a directory.
*
* @see FtpClient::rmdir()
* @see FtpClient::cleanDir()
* @see FtpClient::delete()
* @param string $path The path of the file or directory to remove
* @param bool $recursive Is effective only if $path is a directory, {@see FtpClient::rmdir()}
* @return bool
*/
public function remove($path, $recursive = false)
{
try {
if (@$this->ftp->delete($path)
or ($this->isDir($path) and $this->rmdir($path, $recursive))) {
return true;
}
return false;
} catch (\Exception $e) {
return false;
}
}
/**
* Check if a directory exist.
*
* @param string $directory
* @return bool
* @throws FtpException
*/
public function isDir($directory)
{
$pwd = $this->ftp->pwd();
if ($pwd === false) {
throw new FtpException('Unable to resolve the current directory');
}
if (@$this->ftp->chdir($directory)) {
$this->ftp->chdir($pwd);
return true;
}
$this->ftp->chdir($pwd);
return false;
}
/**
* Check if a directory is empty.
*
* @param string $directory
* @return bool
*/
public function isEmpty($directory)
{
return $this->count($directory, null, false) === 0 ? true : false;
}
/**
* Scan a directory and returns the details of each item.
*
* @see FtpClient::nlist()
* @see FtpClient::rawlist()
* @see FtpClient::parseRawList()
* @see FtpClient::dirSize()
* @param string $directory
* @param bool $recursive
* @return array
*/
public function scanDir($directory = '.', $recursive = false)
{
return $this->parseRawList($this->rawlist($directory, $recursive));
}
/**
* Returns the total size of the given directory in bytes.
*
* @param string $directory The directory, by default is the current directory.
* @param bool $recursive true by default
* @return int The size in bytes.
*/
public function dirSize($directory = '.', $recursive = true)
{
$items = $this->scanDir($directory, $recursive);
$size = 0;
foreach ($items as $item) {
$size += (int) $item['size'];
}
return $size;
}
/**
* Count the items (file, directory, link, unknown).
*
* @param string $directory The directory, by default is the current directory.
* @param string|null $type The type of item to count (file, directory, link, unknown)
* @param bool $recursive true by default
* @return int
*/
public function count($directory = '.', $type = null, $recursive = true)
{
$items = (null === $type ? $this->nlist($directory, $recursive)
: $this->scanDir($directory, $recursive));
$count = 0;
foreach ($items as $item) {
if (null === $type or $item['type'] == $type) {
$count++;
}
}
return $count;
}
/**
* Downloads a file from the FTP server into a string
*
* @param string $remote_file
* @param int $mode
* @param int $resumepos
* @return string|null
*/
public function getContent($remote_file, $mode = FTP_BINARY, $resumepos = 0)
{
$handle = fopen('php://temp', 'r+');
if ($this->fget($handle, $remote_file, $mode, $resumepos)) {
rewind($handle);
return stream_get_contents($handle);
}
return null;
}
/**
* Uploads a file to the server from a string.
*
* @param string $remote_file
* @param string $content
* @return FtpClient
* @throws FtpException When the transfer fails
*/
public function putFromString($remote_file, $content)
{
$handle = fopen('php://temp', 'w');
fwrite($handle, $content);
rewind($handle);
if ($this->ftp->fput($remote_file, $handle, FTP_BINARY)) {
return $this;
}
throw new FtpException('Unable to put the file "'.$remote_file.'"');
}
/**
* Uploads a file to the server.
*
* @param string $local_file
* @return FtpClient
* @throws FtpException When the transfer fails
*/
public function putFromPath($local_file)
{
$remote_file = basename($local_file);
$handle = fopen($local_file, 'r');
if ($this->ftp->fput($remote_file, $handle, FTP_BINARY)) {
rewind($handle);
return $this;
}
throw new FtpException(
'Unable to put the remote file from the local file "'.$local_file.'"'
);
}
/**
* Upload files.
*
* @param string $source_directory
* @param string $target_directory
* @param int $mode
* @return FtpClient
*/
public function putAll($source_directory, $target_directory, $mode = FTP_BINARY)
{
$d = dir($source_directory);
// do this for each file in the directory
while ($file = $d->read()) {
// to prevent an infinite loop
if ($file != "." && $file != "..") {
// do the following if it is a directory
if (is_dir($source_directory.'/'.$file)) {
if (!$this->isDir($target_directory.'/'.$file)) {
// create directories that do not yet exist
$this->ftp->mkdir($target_directory.'/'.$file);
}
// recursive part
$this->putAll(
$source_directory.'/'.$file, $target_directory.'/'.$file,
$mode
);
} else {
// put the files
$this->ftp->put(
$target_directory.'/'.$file, $source_directory.'/'.$file,
$mode
);
}
}
}
return $this;
}
/**
* Downloads all files from remote FTP directory
*
* @param string $source_directory The remote directory
* @param string $target_directory The local directory
* @param int $mode
* @return FtpClient
*/
public function getAll($source_directory, $target_directory, $mode = FTP_BINARY)
{
if ($source_directory != ".") {
if ($this->ftp->chdir($source_directory) == false) {
throw new FtpException("Unable to change directory: ".$source_directory);
}
if (!(is_dir($source_directory))) {
mkdir($source_directory);
}
chdir($source_directory);
}
$contents = $this->ftp->nlist(".");
foreach ($contents as $file) {
if ($file == '.' || $file == '..') {
continue;
}
$this->ftp->get($target_directory."/".$file, $file, $mode);
}
$this->ftp->chdir("..");
chdir("..");
return $this;
}
/**
* Returns a detailed list of files in the given directory.
*
* @see FtpClient::nlist()
* @see FtpClient::scanDir()
* @see FtpClient::dirSize()
* @param string $directory The directory, by default is the current directory
* @param bool $recursive
* @return array
* @throws FtpException
*/
public function rawlist($directory = '.', $recursive = false)
{
if (!$this->isDir($directory)) {
throw new FtpException('"'.$directory.'" is not a directory.');
}
if (strpos($directory, " ") > 0) {
$ftproot = $this->ftp->pwd();
$this->ftp->chdir($directory);
$list = $this->ftp->rawlist("");
$this->ftp->chdir($ftproot);
} else {
$list = $this->ftp->rawlist($directory);
}
$items = array();
if (!$list) {
return $items;
}
if (false == $recursive) {
foreach ($list as $path => $item) {
$chunks = preg_split("/\s+/", $item);
// if not "name"
if (empty($chunks[8]) || $chunks[8] == '.' || $chunks[8] == '..') {
continue;
}
$path = $directory.'/'.$chunks[8];
if (isset($chunks[9])) {
$nbChunks = count($chunks);
for ($i = 9; $i < $nbChunks; $i++) {
$path .= ' '.$chunks[$i];
}
}
if (substr($path, 0, 2) == './') {
$path = substr($path, 2);
}
$items[ $this->rawToType($item).'#'.$path ] = $item;
}
return $items;
}
$path = '';
foreach ($list as $item) {
$len = strlen($item);
if (!$len
// "."
|| ($item[$len-1] == '.' && $item[$len-2] == ' '
// ".."
or $item[$len-1] == '.' && $item[$len-2] == '.' && $item[$len-3] == ' ')
) {
continue;
}
$chunks = preg_split("/\s+/", $item);
// if not "name"
if (empty($chunks[8]) || $chunks[8] == '.' || $chunks[8] == '..') {
continue;
}
$path = $directory.'/'.$chunks[8];
if (isset($chunks[9])) {
$nbChunks = count($chunks);
for ($i = 9; $i < $nbChunks; $i++) {
$path .= ' '.$chunks[$i];
}
}
if (substr($path, 0, 2) == './') {
$path = substr($path, 2);
}
$items[$this->rawToType($item).'#'.$path] = $item;
if ($item[0] == 'd') {
$sublist = $this->rawlist($path, true);
foreach ($sublist as $subpath => $subitem) {
$items[$subpath] = $subitem;
}
}
}
return $items;
}
/**
* Parse raw list.
*
* @see FtpClient::rawlist()
* @see FtpClient::scanDir()
* @see FtpClient::dirSize()
* @param array $rawlist
* @return array
*/
public function parseRawList(array $rawlist)
{
$items = array();
$path = '';
foreach ($rawlist as $key => $child) {
$chunks = preg_split("/\s+/", $child, 9);
if (isset($chunks[8]) && ($chunks[8] == '.' or $chunks[8] == '..')) {
continue;
}
if (count($chunks) === 1) {
$len = strlen($chunks[0]);
if ($len && $chunks[0][$len-1] == ':') {
$path = substr($chunks[0], 0, -1);
}
continue;
}
// Prepare for filename that has space
$nameSlices = array_slice($chunks, 8, true);
$item = [
'permissions' => $chunks[0],
'number' => $chunks[1],
'owner' => $chunks[2],
'group' => $chunks[3],
'size' => $chunks[4],
'month' => $chunks[5],
'day' => $chunks[6],
'time' => $chunks[7],
'name' => implode(' ', $nameSlices),
'type' => $this->rawToType($chunks[0]),
];
if ($item['type'] == 'link' && isset($chunks[10])) {
$item['target'] = $chunks[10]; // 9 is "->"
}
// if the key is not the path, behavior of ftp_rawlist() PHP function
if (is_int($key) || false === strpos($key, $item['name'])) {
array_splice($chunks, 0, 8);
$key = $item['type'].'#'
.($path ? $path.'/' : '')
.implode(' ', $chunks);
if ($item['type'] == 'link') {
// get the first part of 'link#the-link.ext -> /path/of/the/source.ext'
$exp = explode(' ->', $key);
$key = rtrim($exp[0]);
}
$items[$key] = $item;
} else {
// the key is the path, behavior of FtpClient::rawlist() method()
$items[$key] = $item;
}
}
return $items;
}
/**
* Convert raw info (drwx---r-x ...) to type (file, directory, link, unknown).
* Only the first char is used for resolving.
*
* @param string $permission Example : drwx---r-x
*
* @return string The file type (file, directory, link, unknown)
* @throws FtpException
*/
public function rawToType($permission)
{
if (!is_string($permission)) {
throw new FtpException('The "$permission" argument must be a string, "'
.gettype($permission).'" given.');
}
if (empty($permission[0])) {
return 'unknown';
}
switch ($permission[0]) {
case '-':
return 'file';
case 'd':
return 'directory';
case 'l':
return 'link';
default:
return 'unknown';
}
}
/**
* Set the wrapper which forward the PHP FTP functions to use in FtpClient instance.
*
* @param FtpWrapper $wrapper
* @return FtpClient
*/
protected function setWrapper(FtpWrapper $wrapper)
{
$this->ftp = $wrapper;
return $this;
}
}

View File

@@ -0,0 +1,20 @@
<?php
/*
* This file is part of the `nicolab/php-ftp-client` package.
*
* (c) Nicolas Tallefourtane <dev@nicolab.net>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Nicolas Tallefourtane http://nicolab.net
*/
namespace FtpClient;
/**
* The FtpException class.
* Exception thrown if an error on runtime of the FTP client occurs.
* @inheritDoc
* @author Nicolas Tallefourtane <dev@nicolab.net>
*/
class FtpException extends \Exception {}

View File

@@ -0,0 +1,115 @@
<?php
/*
* This file is part of the `nicolab/php-ftp-client` package.
*
* (c) Nicolas Tallefourtane <dev@nicolab.net>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Nicolas Tallefourtane http://nicolab.net
*/
namespace FtpClient;
/**
* Wrap the PHP FTP functions
*
* @method bool alloc() alloc(int $filesize, string &$result = null) Allocates space for a file to be uploaded
* @method bool cdup() cdup() Changes to the parent directory
* @method bool chdir() chdir(string $directory) Changes the current directory on a FTP server
* @method int chmod() chmod(int $mode, string $filename) Set permissions on a file via FTP
* @method bool close() close() Closes an FTP connection
* @method bool delete() delete(string $path) Deletes a file on the FTP server
* @method bool exec() exec(string $command) Requests execution of a command on the FTP server
* @method bool fget() fget(resource $handle, string $remote_file, int $mode, int $resumepos = 0) Downloads a file from the FTP server and saves to an open file
* @method bool fput() fput(string $remote_file, resource $handle, int $mode, int $startpos = 0) Uploads from an open file to the FTP server
* @method mixed get_option() get_option(int $option) Retrieves various runtime behaviours of the current FTP stream
* @method bool get() get(string $local_file, string $remote_file, int $mode, int $resumepos = 0) Downloads a file from the FTP server
* @method bool login() login(string $username, string $password) Logs in to an FTP connection
* @method int mdtm() mdtm(string $remote_file) Returns the last modified time of the given file
* @method string mkdir() mkdir(string $directory) Creates a directory
* @method int nb_continue() nb_continue() Continues retrieving/sending a file (non-blocking)
* @method int nb_fget() nb_fget(resource $handle, string $remote_file, int $mode, int $resumepos = 0) Retrieves a file from the FTP server and writes it to an open file (non-blocking)
* @method int nb_fput() nb_fput(string $remote_file, resource $handle, int $mode, int $startpos = 0) Stores a file from an open file to the FTP server (non-blocking)
* @method int nb_get() nb_get(string $local_file, string $remote_file, int $mode, int $resumepos = 0) Retrieves a file from the FTP server and writes it to a local file (non-blocking)
* @method int nb_put() nb_put(string $remote_file, string $local_file, int $mode, int $startpos = 0) Stores a file on the FTP server (non-blocking)
* @method array nlist() nlist(string $directory) Returns a list of files in the given directory
* @method bool pasv() pasv(bool $pasv) Turns passive mode on or off
* @method bool put() put(string $remote_file, string $local_file, int $mode, int $startpos = 0) Uploads a file to the FTP server
* @method string pwd() pwd() Returns the current directory name
* @method bool quit() quit() Closes an FTP connection
* @method array raw() raw(string $command) Sends an arbitrary command to an FTP server
* @method array rawlist() rawlist(string $directory, bool $recursive = false) Returns a detailed list of files in the given directory
* @method bool rename() rename(string $oldname, string $newname) Renames a file or a directory on the FTP server
* @method bool rmdir() rmdir(string $directory) Removes a directory
* @method bool set_option() set_option(int $option, mixed $value) Set miscellaneous runtime FTP options
* @method bool site() site(string $command) Sends a SITE command to the server
* @method int size() size(string $remote_file) Returns the size of the given file
* @method string systype() systype() Returns the system type identifier of the remote FTP server
*
* @author Nicolas Tallefourtane <dev@nicolab.net>
*/
class FtpWrapper
{
/**
* The connection with the server
*
* @var resource
*/
protected $conn;
/**
* Constructor.
*
* @param resource &$connection The FTP (or SSL-FTP) connection (takes by reference).
*/
public function __construct(&$connection)
{
$this->conn = &$connection;
}
/**
* Forward the method call to FTP functions
*
* @param string $function
* @param array $arguments
* @return mixed
* @throws FtpException When the function is not valid
*/
public function __call($function, array $arguments)
{
$function = 'ftp_' . $function;
if (function_exists($function)) {
array_unshift($arguments, $this->conn);
return @call_user_func_array($function, $arguments);
}
throw new FtpException("{$function} is not a valid FTP function");
}
/**
* Opens a FTP connection
*
* @param string $host
* @param int $port
* @param int $timeout
* @return resource
*/
public function connect($host, $port = 21, $timeout = 90)
{
return @ftp_connect($host, $port, $timeout);
}
/**
* Opens a Secure SSL-FTP connection
* @param string $host
* @param int $port
* @param int $timeout
* @return resource
*/
public function ssl_connect($host, $port = 21, $timeout = 90)
{
return @ftp_ssl_connect($host, $port, $timeout);
}
}

View File

@@ -0,0 +1,10 @@
<?php
use \mageekguy\atoum;
$report = $script->addDefaultReport();
// This will add a green or red logo after each run depending on its status.
$report->addField(new atoum\report\fields\runner\result\logo());
$script->bootstrapFile(__DIR__. '/bootstrap.php');
$runner->addTestsFromDirectory(__DIR__. '/units');

View File

@@ -0,0 +1,6 @@
<?php
if (!defined('FTP_CLIENT_TEST_VENDOR')) {
define('FTP_CLIENT_TEST_VENDOR', __DIR__ . '/../../../');
}
$loader = require_once FTP_CLIENT_TEST_VENDOR . '/autoload.php';

View File

@@ -0,0 +1,34 @@
<?php
/*
* This file is part of the `nicolab/php-ftp-client` package.
*
* (c) Nicolas Tallefourtane <dev@nicolab.net>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Nicolas Tallefourtane http://nicolab.net
*/
namespace tests\units\FtpClient;
use
mageekguy\atoum,
FtpClient\FtpClient as TestedClass
;
/**
* Tests the FtpClient\FtpClient class.
* @author Nicolas Tallefourtane <dev@nicolab.net>
*/
class FtpClient extends atoum\test
{
public function test__construct()
{
$this
->given($ftp = new TestedClass())
->object($ftp)
->isInstanceOf('\FtpClient\FtpClient')
;
}
}

View File

@@ -0,0 +1,43 @@
<?php
/*
* This file is part of the `nicolab/php-ftp-client` package.
*
* (c) Nicolas Tallefourtane <dev@nicolab.net>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Nicolas Tallefourtane http://nicolab.net
*/
namespace tests\units\FtpClient;
use
mageekguy\atoum,
FtpClient\FtpException as TestedClass
;
/**
* Tests the FtpClient\FtpException class.
* @author Nicolas Tallefourtane <dev@nicolab.net>
*/
class FtpException extends atoum\test
{
public function test__instance()
{
$ftp = new \FtpClient\FtpClient();
$this
->given($e = new TestedClass())
->object($e)
->isInstanceOf('\FtpClient\FtpException')
->isInstanceOf('\Exception')
->exception(function () use ($ftp) {
$ftp->doNotExist();
})
->isInstanceOf('\FtpClient\FtpException')
->isInstanceOf('\Exception')
;
}
}

View File

@@ -0,0 +1,53 @@
<?php
/*
* This file is part of the `nicolab/php-ftp-client` package.
*
* (c) Nicolas Tallefourtane <dev@nicolab.net>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Nicolas Tallefourtane http://nicolab.net
*/
namespace tests\units\FtpClient;
use
mageekguy\atoum,
FtpClient\FtpWrapper as TestedClass
;
/**
* Tests the FtpClient\FtpWrapper class.
* @author Nicolas Tallefourtane <dev@nicolab.net>
*/
class FtpWrapper extends atoum\test
{
public function test__construct()
{
$conn = null;
$this
->given($wrapper = new TestedClass($conn))
->object($wrapper)
->isInstanceOf('\FtpClient\FtpWrapper')
;
}
public function test__call()
{
$conn = null;
$this
->given($wrapper = new TestedClass($conn))
->exception(function () use ($wrapper) {
$wrapper->doNotExist();
})
->isInstanceOf('\FtpClient\FtpException')
->isInstanceOf('\Exception')
->variable(array($wrapper, 'alloc'))
->isCallable()
;
}
}