底层框架升级到tp6.1

This commit is contained in:
gongfuxiang
2022-11-21 15:06:53 +08:00
parent ec0420fb51
commit d98b7fe630
279 changed files with 4322 additions and 15159 deletions

View File

@ -1874,7 +1874,8 @@ function MyUrl($path, $params = [])
$ds = ($script_name == 'index.php') ? '/' : '';
$join = ($script_name != 'index.php' || $url_model == 0) ? $ds.'?s=' : '/';
$len = $is_api ? 4 : ($is_install ? 8 : 6);
$url = str_replace('/'.$path, $join.substr($path, $len), $url);
$path = substr($path, $len);
$url = str_replace('/'.$path, $join.$path, $url);
// 避免非当前目录生成url索引错误
if($script_name != 'index.php' && $is_index)

421
composer.lock generated
View File

@ -8,16 +8,16 @@
"packages": [
{
"name": "ezyang/htmlpurifier",
"version": "v4.14.0",
"version": "v4.16.0",
"source": {
"type": "git",
"url": "https://github.com/ezyang/htmlpurifier.git",
"reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75"
"reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/12ab42bd6e742c70c0a52f7b82477fcd44e64b75",
"reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/523407fb06eb9e5f3d59889b3978d5bfe94299c8",
"reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8",
"shasum": "",
"mirrors": [
{
@ -27,7 +27,17 @@
]
},
"require": {
"php": ">=5.2"
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0"
},
"require-dev": {
"cerdic/css-tidy": "^1.7 || ^2.0",
"simpletest/simpletest": "dev-master"
},
"suggest": {
"cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.",
"ext-bcmath": "Used for unit conversion and imagecrash protection",
"ext-iconv": "Converts text to and from non-UTF-8 encodings",
"ext-tidy": "Used for pretty-printing HTML"
},
"type": "library",
"autoload": {
@ -59,228 +69,9 @@
],
"support": {
"issues": "https://github.com/ezyang/htmlpurifier/issues",
"source": "https://github.com/ezyang/htmlpurifier/tree/v4.14.0"
"source": "https://github.com/ezyang/htmlpurifier/tree/v4.16.0"
},
"time": "2021-12-25T01:21:49+00:00"
},
{
"name": "league/flysystem",
"version": "1.1.9",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
"reference": "094defdb4a7001845300334e7c1ee2335925ef99"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/094defdb4a7001845300334e7c1ee2335925ef99",
"reference": "094defdb4a7001845300334e7c1ee2335925ef99",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-fileinfo": "*",
"league/mime-type-detection": "^1.3",
"php": "^7.2.5 || ^8.0"
},
"conflict": {
"league/flysystem-sftp": "<1.0.6"
},
"require-dev": {
"phpspec/prophecy": "^1.11.1",
"phpunit/phpunit": "^8.5.8"
},
"suggest": {
"ext-ftp": "Allows you to use FTP server storage",
"ext-openssl": "Allows you to use FTPS server storage",
"league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2",
"league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3",
"league/flysystem-azure": "Allows you to use Windows Azure Blob storage",
"league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching",
"league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem",
"league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files",
"league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib",
"league/flysystem-webdav": "Allows you to use WebDAV storage",
"league/flysystem-ziparchive": "Allows you to use ZipArchive adapter",
"spatie/flysystem-dropbox": "Allows you to use Dropbox storage",
"srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
}
},
"autoload": {
"psr-4": {
"League\\Flysystem\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frank de Jonge",
"email": "info@frenky.net"
}
],
"description": "Filesystem abstraction: Many filesystems, one API.",
"keywords": [
"Cloud Files",
"WebDAV",
"abstraction",
"aws",
"cloud",
"copy.com",
"dropbox",
"file systems",
"files",
"filesystem",
"filesystems",
"ftp",
"rackspace",
"remote",
"s3",
"sftp",
"storage"
],
"support": {
"issues": "https://github.com/thephpleague/flysystem/issues",
"source": "https://github.com/thephpleague/flysystem/tree/1.1.9"
},
"funding": [
{
"url": "https://offset.earth/frankdejonge",
"type": "other"
}
],
"time": "2021-12-09T09:40:50+00:00"
},
{
"name": "league/flysystem-cached-adapter",
"version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem-cached-adapter.git",
"reference": "d1925efb2207ac4be3ad0c40b8277175f99ffaff"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem-cached-adapter/zipball/d1925efb2207ac4be3ad0c40b8277175f99ffaff",
"reference": "d1925efb2207ac4be3ad0c40b8277175f99ffaff",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"league/flysystem": "~1.0",
"psr/cache": "^1.0.0"
},
"require-dev": {
"mockery/mockery": "~0.9",
"phpspec/phpspec": "^3.4",
"phpunit/phpunit": "^5.7",
"predis/predis": "~1.0",
"tedivm/stash": "~0.12"
},
"suggest": {
"ext-phpredis": "Pure C implemented extension for PHP"
},
"type": "library",
"autoload": {
"psr-4": {
"League\\Flysystem\\Cached\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "frankdejonge",
"email": "info@frenky.net"
}
],
"description": "An adapter decorator to enable meta-data caching.",
"support": {
"issues": "https://github.com/thephpleague/flysystem-cached-adapter/issues",
"source": "https://github.com/thephpleague/flysystem-cached-adapter/tree/master"
},
"time": "2020-07-25T15:56:04+00:00"
},
{
"name": "league/mime-type-detection",
"version": "1.11.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/mime-type-detection.git",
"reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
"reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-fileinfo": "*",
"php": "^7.2 || ^8.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.2",
"phpstan/phpstan": "^0.12.68",
"phpunit/phpunit": "^8.5.8 || ^9.3"
},
"type": "library",
"autoload": {
"psr-4": {
"League\\MimeTypeDetection\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frank de Jonge",
"email": "info@frankdejonge.nl"
}
],
"description": "Mime-type detection for Flysystem",
"support": {
"issues": "https://github.com/thephpleague/mime-type-detection/issues",
"source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0"
},
"funding": [
{
"url": "https://github.com/frankdejonge",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/league/flysystem",
"type": "tidelift"
}
],
"time": "2022-04-17T13:12:02+00:00"
"time": "2022-09-18T07:06:19+00:00"
},
{
"name": "maennchen/zipstream-php",
@ -627,16 +418,16 @@
},
{
"name": "phpoffice/phpspreadsheet",
"version": "1.24.0",
"version": "1.25.2",
"source": {
"type": "git",
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
"reference": "ebe8745c92a7cac4514d040758393b5399633b83"
"reference": "a317a09e7def49852400a4b3eca4a4b0790ceeb5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/ebe8745c92a7cac4514d040758393b5399633b83",
"reference": "ebe8745c92a7cac4514d040758393b5399633b83",
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/a317a09e7def49852400a4b3eca4a4b0790ceeb5",
"reference": "a317a09e7def49852400a4b3eca4a4b0790ceeb5",
"shasum": "",
"mirrors": [
{
@ -659,33 +450,34 @@
"ext-xmlwriter": "*",
"ext-zip": "*",
"ext-zlib": "*",
"ezyang/htmlpurifier": "^4.13",
"ezyang/htmlpurifier": "^4.15",
"maennchen/zipstream-php": "^2.1",
"markbaker/complex": "^3.0",
"markbaker/matrix": "^3.0",
"php": "^7.3 || ^8.0",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
"psr/simple-cache": "^1.0 || ^2.0"
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
"dompdf/dompdf": "^1.0 || ^2.0",
"friendsofphp/php-cs-fixer": "^3.2",
"jpgraph/jpgraph": "^4.0",
"mitoteam/jpgraph": "10.2.4",
"mpdf/mpdf": "8.1.1",
"phpcompatibility/php-compatibility": "^9.3",
"phpstan/phpstan": "^1.1",
"phpstan/phpstan-phpunit": "^1.0",
"phpunit/phpunit": "^8.5 || ^9.0",
"squizlabs/php_codesniffer": "^3.7",
"tecnickcom/tcpdf": "^6.4"
"tecnickcom/tcpdf": "6.5"
},
"suggest": {
"dompdf/dompdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)",
"jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
"ext-intl": "PHP Internationalization Functions",
"mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)"
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
},
"type": "library",
"autoload": {
@ -731,64 +523,9 @@
],
"support": {
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.24.0"
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.25.2"
},
"time": "2022-07-09T13:49:09+00:00"
},
{
"name": "psr/cache",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/cache.git",
"reference": "d11b50ad223250cf17b86e38383413f5a6764bf8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
"reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Cache\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for caching libraries",
"keywords": [
"cache",
"psr",
"psr-6"
],
"support": {
"source": "https://github.com/php-fig/cache/tree/master"
},
"time": "2016-08-06T20:24:11+00:00"
"time": "2022-09-25T17:21:01+00:00"
},
{
"name": "psr/container",
@ -1137,16 +874,16 @@
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.26.0",
"version": "v1.27.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e"
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
"reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
"shasum": "",
"mirrors": [
{
@ -1167,7 +904,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.26-dev"
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
@ -1206,7 +943,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
},
"funding": [
{
@ -1222,20 +959,20 @@
"type": "tidelift"
}
],
"time": "2022-05-24T11:49:31+00:00"
"time": "2022-11-03T14:55:06+00:00"
},
{
"name": "topthink/framework",
"version": "v6.0.13",
"version": "v6.1.1",
"source": {
"type": "git",
"url": "https://github.com/top-think/framework.git",
"reference": "126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6"
"reference": "2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/framework/zipball/126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6",
"reference": "126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6",
"url": "https://api.github.com/repos/top-think/framework/zipball/2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210",
"reference": "2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210",
"shasum": "",
"mirrors": [
{
@ -1247,8 +984,6 @@
"require": {
"ext-json": "*",
"ext-mbstring": "*",
"league/flysystem": "^1.1.4",
"league/flysystem-cached-adapter": "^1.0",
"php": ">=7.2.5",
"psr/container": "~1.0",
"psr/http-message": "^1.0",
@ -1293,9 +1028,9 @@
],
"support": {
"issues": "https://github.com/top-think/framework/issues",
"source": "https://github.com/top-think/framework/tree/v6.0.13"
"source": "https://github.com/top-think/framework/tree/v6.1.1"
},
"time": "2022-07-15T02:52:08+00:00"
"time": "2022-10-26T03:48:53+00:00"
},
{
"name": "topthink/think-helper",
@ -1351,16 +1086,16 @@
},
{
"name": "topthink/think-multi-app",
"version": "v1.0.14",
"version": "v1.0.15",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-multi-app.git",
"reference": "ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3"
"reference": "387e0dac059c20f92cac5da41a871e10829c1c97"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3",
"reference": "ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3",
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/387e0dac059c20f92cac5da41a871e10829c1c97",
"reference": "387e0dac059c20f92cac5da41a871e10829c1c97",
"shasum": "",
"mirrors": [
{
@ -1371,7 +1106,7 @@
},
"require": {
"php": ">=7.1.0",
"topthink/framework": "^6.0.0"
"topthink/framework": "^6.0"
},
"type": "library",
"extra": {
@ -1399,9 +1134,9 @@
"description": "thinkphp6 multi app support",
"support": {
"issues": "https://github.com/top-think/think-multi-app/issues",
"source": "https://github.com/top-think/think-multi-app/tree/master"
"source": "https://github.com/top-think/think-multi-app/tree/v1.0.15"
},
"time": "2020-07-12T13:50:37+00:00"
"time": "2022-10-26T08:03:06+00:00"
},
{
"name": "topthink/think-orm",
@ -1562,16 +1297,16 @@
"packages-dev": [
{
"name": "symfony/polyfill-php72",
"version": "v1.26.0",
"version": "v1.27.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2"
"reference": "869329b1e9894268a8a61dabb69153029b7a8c97"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2",
"reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97",
"reference": "869329b1e9894268a8a61dabb69153029b7a8c97",
"shasum": "",
"mirrors": [
{
@ -1586,7 +1321,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.26-dev"
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
@ -1624,7 +1359,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0"
"source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0"
},
"funding": [
{
@ -1640,20 +1375,20 @@
"type": "tidelift"
}
],
"time": "2022-05-24T11:49:31+00:00"
"time": "2022-11-03T14:55:06+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.26.0",
"version": "v1.27.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace"
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace",
"reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
"shasum": "",
"mirrors": [
{
@ -1668,7 +1403,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.26-dev"
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
@ -1713,7 +1448,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0"
"source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0"
},
"funding": [
{
@ -1729,20 +1464,20 @@
"type": "tidelift"
}
],
"time": "2022-05-10T07:21:04+00:00"
"time": "2022-11-03T14:55:06+00:00"
},
{
"name": "symfony/var-dumper",
"version": "v4.4.44",
"version": "v4.4.47",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "f19951007dae942cc79b979c1fe26bfdfbeb54ed"
"reference": "1069c7a3fca74578022fab6f81643248d02f8e63"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/f19951007dae942cc79b979c1fe26bfdfbeb54ed",
"reference": "f19951007dae942cc79b979c1fe26bfdfbeb54ed",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/1069c7a3fca74578022fab6f81643248d02f8e63",
"reference": "1069c7a3fca74578022fab6f81643248d02f8e63",
"shasum": "",
"mirrors": [
{
@ -1808,7 +1543,7 @@
"dump"
],
"support": {
"source": "https://github.com/symfony/var-dumper/tree/v4.4.44"
"source": "https://github.com/symfony/var-dumper/tree/v4.4.47"
},
"funding": [
{
@ -1824,20 +1559,20 @@
"type": "tidelift"
}
],
"time": "2022-07-20T09:59:04+00:00"
"time": "2022-10-03T15:15:11+00:00"
},
{
"name": "topthink/think-trace",
"version": "v1.4",
"version": "v1.5",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-trace.git",
"reference": "9a9fa8f767b6c66c5a133ad21ca1bc96ad329444"
"reference": "55027fd79abb744f32a3be8d9e1ccf873a3ca9b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-trace/zipball/9a9fa8f767b6c66c5a133ad21ca1bc96ad329444",
"reference": "9a9fa8f767b6c66c5a133ad21ca1bc96ad329444",
"url": "https://api.github.com/repos/top-think/think-trace/zipball/55027fd79abb744f32a3be8d9e1ccf873a3ca9b7",
"reference": "55027fd79abb744f32a3be8d9e1ccf873a3ca9b7",
"shasum": "",
"mirrors": [
{
@ -1848,7 +1583,7 @@
},
"require": {
"php": ">=7.1.0",
"topthink/framework": "^6.0.0"
"topthink/framework": "^6.0"
},
"type": "library",
"extra": {
@ -1879,9 +1614,9 @@
"description": "thinkphp debug trace",
"support": {
"issues": "https://github.com/top-think/think-trace/issues",
"source": "https://github.com/top-think/think-trace/tree/v1.4"
"source": "https://github.com/top-think/think-trace/tree/v1.5"
},
"time": "2020-06-29T05:27:28+00:00"
"time": "2022-10-26T07:56:45+00:00"
}
],
"aliases": [],

View File

@ -7,11 +7,11 @@ $baseDir = dirname($vendorDir);
return array(
'9b552a3cc426e3287cc811caefa3cf53' => $vendorDir . '/topthink/think-helper/src/helper.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'35fab96057f1bf5e7aba31a8a6d5fdde' => $vendorDir . '/topthink/think-orm/stubs/load_stubs.php',
'2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
'2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'dc1275c308c5b416beb314b6317daca2' => $vendorDir . '/overtrue/pinyin/src/const.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
);

View File

@ -9,7 +9,7 @@ return array(
'think\\view\\driver\\' => array($vendorDir . '/topthink/think-view/src'),
'think\\trace\\' => array($vendorDir . '/topthink/think-trace/src'),
'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/src'),
'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src'),
'think\\' => array($vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src', $vendorDir . '/topthink/framework/src/think'),
'app\\' => array($baseDir . '/app'),
'ZipStream\\' => array($vendorDir . '/maennchen/zipstream-php/src'),
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
@ -21,13 +21,9 @@ return array(
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
'PhpOffice\\PhpSpreadsheet\\' => array($vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet'),
'Overtrue\\Pinyin\\' => array($vendorDir . '/overtrue/pinyin/src'),
'MyCLabs\\Enum\\' => array($vendorDir . '/myclabs/php-enum/src'),
'Matrix\\' => array($vendorDir . '/markbaker/matrix/classes/src'),
'League\\MimeTypeDetection\\' => array($vendorDir . '/league/mime-type-detection/src'),
'League\\Flysystem\\Cached\\' => array($vendorDir . '/league/flysystem-cached-adapter/src'),
'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'),
'Complex\\' => array($vendorDir . '/markbaker/complex/classes/src'),
);

View File

@ -8,13 +8,13 @@ class ComposerStaticInit1ed187777399b73a018d9a6af63a57d1
{
public static $files = array (
'9b552a3cc426e3287cc811caefa3cf53' => __DIR__ . '/..' . '/topthink/think-helper/src/helper.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'35fab96057f1bf5e7aba31a8a6d5fdde' => __DIR__ . '/..' . '/topthink/think-orm/stubs/load_stubs.php',
'2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
'2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'dc1275c308c5b416beb314b6317daca2' => __DIR__ . '/..' . '/overtrue/pinyin/src/const.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
);
public static $prefixLengthsPsr4 = array (
@ -47,7 +47,6 @@ class ComposerStaticInit1ed187777399b73a018d9a6af63a57d1
'Psr\\Http\\Message\\' => 17,
'Psr\\Http\\Client\\' => 16,
'Psr\\Container\\' => 14,
'Psr\\Cache\\' => 10,
'PhpOffice\\PhpSpreadsheet\\' => 25,
),
'O' =>
@ -59,12 +58,6 @@ class ComposerStaticInit1ed187777399b73a018d9a6af63a57d1
'MyCLabs\\Enum\\' => 13,
'Matrix\\' => 7,
),
'L' =>
array (
'League\\MimeTypeDetection\\' => 25,
'League\\Flysystem\\Cached\\' => 24,
'League\\Flysystem\\' => 17,
),
'C' =>
array (
'Complex\\' => 8,
@ -86,10 +79,10 @@ class ComposerStaticInit1ed187777399b73a018d9a6af63a57d1
),
'think\\' =>
array (
0 => __DIR__ . '/..' . '/topthink/framework/src/think',
1 => __DIR__ . '/..' . '/topthink/think-helper/src',
2 => __DIR__ . '/..' . '/topthink/think-orm/src',
3 => __DIR__ . '/..' . '/topthink/think-template/src',
0 => __DIR__ . '/..' . '/topthink/think-helper/src',
1 => __DIR__ . '/..' . '/topthink/think-orm/src',
2 => __DIR__ . '/..' . '/topthink/think-template/src',
3 => __DIR__ . '/..' . '/topthink/framework/src/think',
),
'app\\' =>
array (
@ -136,10 +129,6 @@ class ComposerStaticInit1ed187777399b73a018d9a6af63a57d1
array (
0 => __DIR__ . '/..' . '/psr/container/src',
),
'Psr\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/psr/cache/src',
),
'PhpOffice\\PhpSpreadsheet\\' =>
array (
0 => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet',
@ -156,18 +145,6 @@ class ComposerStaticInit1ed187777399b73a018d9a6af63a57d1
array (
0 => __DIR__ . '/..' . '/markbaker/matrix/classes/src',
),
'League\\MimeTypeDetection\\' =>
array (
0 => __DIR__ . '/..' . '/league/mime-type-detection/src',
),
'League\\Flysystem\\Cached\\' =>
array (
0 => __DIR__ . '/..' . '/league/flysystem-cached-adapter/src',
),
'League\\Flysystem\\' =>
array (
0 => __DIR__ . '/..' . '/league/flysystem/src',
),
'Complex\\' =>
array (
0 => __DIR__ . '/..' . '/markbaker/complex/classes/src',

View File

@ -2,17 +2,17 @@
"packages": [
{
"name": "ezyang/htmlpurifier",
"version": "v4.14.0",
"version_normalized": "4.14.0.0",
"version": "v4.16.0",
"version_normalized": "4.16.0.0",
"source": {
"type": "git",
"url": "https://github.com/ezyang/htmlpurifier.git",
"reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75"
"reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/12ab42bd6e742c70c0a52f7b82477fcd44e64b75",
"reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/523407fb06eb9e5f3d59889b3978d5bfe94299c8",
"reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8",
"shasum": "",
"mirrors": [
{
@ -22,18 +22,28 @@
]
},
"require": {
"php": ">=5.2"
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0"
},
"time": "2021-12-25T01:21:49+00:00",
"require-dev": {
"cerdic/css-tidy": "^1.7 || ^2.0",
"simpletest/simpletest": "dev-master"
},
"suggest": {
"cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.",
"ext-bcmath": "Used for unit conversion and imagecrash protection",
"ext-iconv": "Converts text to and from non-UTF-8 encodings",
"ext-tidy": "Used for pretty-printing HTML"
},
"time": "2022-09-18T07:06:19+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"HTMLPurifier": "library/"
},
"files": [
"library/HTMLPurifier.composer.php"
],
"psr-0": {
"HTMLPurifier": "library/"
},
"exclude-from-classmap": [
"/library/HTMLPurifier/Language/"
]
@ -56,232 +66,10 @@
],
"support": {
"issues": "https://github.com/ezyang/htmlpurifier/issues",
"source": "https://github.com/ezyang/htmlpurifier/tree/v4.14.0"
"source": "https://github.com/ezyang/htmlpurifier/tree/v4.16.0"
},
"install-path": "../ezyang/htmlpurifier"
},
{
"name": "league/flysystem",
"version": "1.1.9",
"version_normalized": "1.1.9.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
"reference": "094defdb4a7001845300334e7c1ee2335925ef99"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/094defdb4a7001845300334e7c1ee2335925ef99",
"reference": "094defdb4a7001845300334e7c1ee2335925ef99",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-fileinfo": "*",
"league/mime-type-detection": "^1.3",
"php": "^7.2.5 || ^8.0"
},
"conflict": {
"league/flysystem-sftp": "<1.0.6"
},
"require-dev": {
"phpspec/prophecy": "^1.11.1",
"phpunit/phpunit": "^8.5.8"
},
"suggest": {
"ext-ftp": "Allows you to use FTP server storage",
"ext-openssl": "Allows you to use FTPS server storage",
"league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2",
"league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3",
"league/flysystem-azure": "Allows you to use Windows Azure Blob storage",
"league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching",
"league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem",
"league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files",
"league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib",
"league/flysystem-webdav": "Allows you to use WebDAV storage",
"league/flysystem-ziparchive": "Allows you to use ZipArchive adapter",
"spatie/flysystem-dropbox": "Allows you to use Dropbox storage",
"srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications"
},
"time": "2021-12-09T09:40:50+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"League\\Flysystem\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frank de Jonge",
"email": "info@frenky.net"
}
],
"description": "Filesystem abstraction: Many filesystems, one API.",
"keywords": [
"Cloud Files",
"WebDAV",
"abstraction",
"aws",
"cloud",
"copy.com",
"dropbox",
"file systems",
"files",
"filesystem",
"filesystems",
"ftp",
"rackspace",
"remote",
"s3",
"sftp",
"storage"
],
"support": {
"issues": "https://github.com/thephpleague/flysystem/issues",
"source": "https://github.com/thephpleague/flysystem/tree/1.1.9"
},
"funding": [
{
"url": "https://offset.earth/frankdejonge",
"type": "other"
}
],
"install-path": "../league/flysystem"
},
{
"name": "league/flysystem-cached-adapter",
"version": "1.1.0",
"version_normalized": "1.1.0.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem-cached-adapter.git",
"reference": "d1925efb2207ac4be3ad0c40b8277175f99ffaff"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem-cached-adapter/zipball/d1925efb2207ac4be3ad0c40b8277175f99ffaff",
"reference": "d1925efb2207ac4be3ad0c40b8277175f99ffaff",
"shasum": ""
},
"require": {
"league/flysystem": "~1.0",
"psr/cache": "^1.0.0"
},
"require-dev": {
"mockery/mockery": "~0.9",
"phpspec/phpspec": "^3.4",
"phpunit/phpunit": "^5.7",
"predis/predis": "~1.0",
"tedivm/stash": "~0.12"
},
"suggest": {
"ext-phpredis": "Pure C implemented extension for PHP"
},
"time": "2020-07-25T15:56:04+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"League\\Flysystem\\Cached\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "frankdejonge",
"email": "info@frenky.net"
}
],
"description": "An adapter decorator to enable meta-data caching.",
"support": {
"issues": "https://github.com/thephpleague/flysystem-cached-adapter/issues",
"source": "https://github.com/thephpleague/flysystem-cached-adapter/tree/master"
},
"install-path": "../league/flysystem-cached-adapter"
},
{
"name": "league/mime-type-detection",
"version": "1.11.0",
"version_normalized": "1.11.0.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/mime-type-detection.git",
"reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
"reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-fileinfo": "*",
"php": "^7.2 || ^8.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.2",
"phpstan/phpstan": "^0.12.68",
"phpunit/phpunit": "^8.5.8 || ^9.3"
},
"time": "2022-04-17T13:12:02+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"League\\MimeTypeDetection\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frank de Jonge",
"email": "info@frankdejonge.nl"
}
],
"description": "Mime-type detection for Flysystem",
"support": {
"issues": "https://github.com/thephpleague/mime-type-detection/issues",
"source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0"
},
"funding": [
{
"url": "https://github.com/frankdejonge",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/league/flysystem",
"type": "tidelift"
}
],
"install-path": "../league/mime-type-detection"
},
{
"name": "maennchen/zipstream-php",
"version": "2.2.1",
@ -642,17 +430,17 @@
},
{
"name": "phpoffice/phpspreadsheet",
"version": "1.24.0",
"version_normalized": "1.24.0.0",
"version": "1.25.2",
"version_normalized": "1.25.2.0",
"source": {
"type": "git",
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
"reference": "ebe8745c92a7cac4514d040758393b5399633b83"
"reference": "a317a09e7def49852400a4b3eca4a4b0790ceeb5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/ebe8745c92a7cac4514d040758393b5399633b83",
"reference": "ebe8745c92a7cac4514d040758393b5399633b83",
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/a317a09e7def49852400a4b3eca4a4b0790ceeb5",
"reference": "a317a09e7def49852400a4b3eca4a4b0790ceeb5",
"shasum": "",
"mirrors": [
{
@ -675,35 +463,36 @@
"ext-xmlwriter": "*",
"ext-zip": "*",
"ext-zlib": "*",
"ezyang/htmlpurifier": "^4.13",
"ezyang/htmlpurifier": "^4.15",
"maennchen/zipstream-php": "^2.1",
"markbaker/complex": "^3.0",
"markbaker/matrix": "^3.0",
"php": "^7.3 || ^8.0",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
"psr/simple-cache": "^1.0 || ^2.0"
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
"dompdf/dompdf": "^1.0 || ^2.0",
"friendsofphp/php-cs-fixer": "^3.2",
"jpgraph/jpgraph": "^4.0",
"mitoteam/jpgraph": "10.2.4",
"mpdf/mpdf": "8.1.1",
"phpcompatibility/php-compatibility": "^9.3",
"phpstan/phpstan": "^1.1",
"phpstan/phpstan-phpunit": "^1.0",
"phpunit/phpunit": "^8.5 || ^9.0",
"squizlabs/php_codesniffer": "^3.7",
"tecnickcom/tcpdf": "^6.4"
"tecnickcom/tcpdf": "6.5"
},
"suggest": {
"dompdf/dompdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)",
"jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
"ext-intl": "PHP Internationalization Functions",
"mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)"
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
},
"time": "2022-07-09T13:49:09+00:00",
"time": "2022-09-25T17:21:01+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -749,62 +538,10 @@
],
"support": {
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.24.0"
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.25.2"
},
"install-path": "../phpoffice/phpspreadsheet"
},
{
"name": "psr/cache",
"version": "1.0.1",
"version_normalized": "1.0.1.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/cache.git",
"reference": "d11b50ad223250cf17b86e38383413f5a6764bf8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
"reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"time": "2016-08-06T20:24:11+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Psr\\Cache\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for caching libraries",
"keywords": [
"cache",
"psr",
"psr-6"
],
"support": {
"source": "https://github.com/php-fig/cache/tree/master"
},
"install-path": "../psr/cache"
},
{
"name": "psr/container",
"version": "1.1.2",
@ -1158,17 +895,17 @@
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.26.0",
"version_normalized": "1.26.0.0",
"version": "v1.27.0",
"version_normalized": "1.27.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e"
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
"reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
"shasum": "",
"mirrors": [
{
@ -1186,11 +923,11 @@
"suggest": {
"ext-mbstring": "For best performance"
},
"time": "2022-05-24T11:49:31+00:00",
"time": "2022-11-03T14:55:06+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.26-dev"
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
@ -1230,7 +967,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
},
"funding": [
{
@ -1250,17 +987,17 @@
},
{
"name": "symfony/polyfill-php72",
"version": "v1.26.0",
"version_normalized": "1.26.0.0",
"version": "v1.27.0",
"version_normalized": "1.27.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2"
"reference": "869329b1e9894268a8a61dabb69153029b7a8c97"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2",
"reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97",
"reference": "869329b1e9894268a8a61dabb69153029b7a8c97",
"shasum": "",
"mirrors": [
{
@ -1272,11 +1009,11 @@
"require": {
"php": ">=7.1"
},
"time": "2022-05-24T11:49:31+00:00",
"time": "2022-11-03T14:55:06+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.26-dev"
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
@ -1315,7 +1052,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0"
"source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0"
},
"funding": [
{
@ -1335,17 +1072,17 @@
},
{
"name": "symfony/polyfill-php80",
"version": "v1.26.0",
"version_normalized": "1.26.0.0",
"version": "v1.27.0",
"version_normalized": "1.27.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace"
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace",
"reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
"shasum": "",
"mirrors": [
{
@ -1357,11 +1094,11 @@
"require": {
"php": ">=7.1"
},
"time": "2022-05-10T07:21:04+00:00",
"time": "2022-11-03T14:55:06+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.26-dev"
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
@ -1407,7 +1144,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0"
"source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0"
},
"funding": [
{
@ -1427,17 +1164,17 @@
},
{
"name": "symfony/var-dumper",
"version": "v4.4.44",
"version_normalized": "4.4.44.0",
"version": "v4.4.47",
"version_normalized": "4.4.47.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "f19951007dae942cc79b979c1fe26bfdfbeb54ed"
"reference": "1069c7a3fca74578022fab6f81643248d02f8e63"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/f19951007dae942cc79b979c1fe26bfdfbeb54ed",
"reference": "f19951007dae942cc79b979c1fe26bfdfbeb54ed",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/1069c7a3fca74578022fab6f81643248d02f8e63",
"reference": "1069c7a3fca74578022fab6f81643248d02f8e63",
"shasum": "",
"mirrors": [
{
@ -1467,7 +1204,7 @@
"ext-intl": "To show region name in time zone dump",
"symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
},
"time": "2022-07-20T09:59:04+00:00",
"time": "2022-10-03T15:15:11+00:00",
"bin": [
"Resources/bin/var-dump-server"
],
@ -1505,7 +1242,7 @@
"dump"
],
"support": {
"source": "https://github.com/symfony/var-dumper/tree/v4.4.44"
"source": "https://github.com/symfony/var-dumper/tree/v4.4.47"
},
"funding": [
{
@ -1525,17 +1262,17 @@
},
{
"name": "topthink/framework",
"version": "v6.0.13",
"version_normalized": "6.0.13.0",
"version": "v6.1.1",
"version_normalized": "6.1.1.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/framework.git",
"reference": "126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6"
"reference": "2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/framework/zipball/126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6",
"reference": "126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6",
"url": "https://api.github.com/repos/top-think/framework/zipball/2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210",
"reference": "2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210",
"shasum": "",
"mirrors": [
{
@ -1547,8 +1284,6 @@
"require": {
"ext-json": "*",
"ext-mbstring": "*",
"league/flysystem": "^1.1.4",
"league/flysystem-cached-adapter": "^1.0",
"php": ">=7.2.5",
"psr/container": "~1.0",
"psr/http-message": "^1.0",
@ -1563,7 +1298,7 @@
"mockery/mockery": "^1.2",
"phpunit/phpunit": "^7.0"
},
"time": "2022-07-15T02:52:08+00:00",
"time": "2022-10-26T03:48:53+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -1595,7 +1330,7 @@
],
"support": {
"issues": "https://github.com/top-think/framework/issues",
"source": "https://github.com/top-think/framework/tree/v6.0.13"
"source": "https://github.com/top-think/framework/tree/v6.1.1"
},
"install-path": "../topthink/framework"
},
@ -1656,24 +1391,30 @@
},
{
"name": "topthink/think-multi-app",
"version": "v1.0.14",
"version_normalized": "1.0.14.0",
"version": "v1.0.15",
"version_normalized": "1.0.15.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-multi-app.git",
"reference": "ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3"
"reference": "387e0dac059c20f92cac5da41a871e10829c1c97"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3",
"reference": "ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3",
"shasum": ""
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/387e0dac059c20f92cac5da41a871e10829c1c97",
"reference": "387e0dac059c20f92cac5da41a871e10829c1c97",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.1.0",
"topthink/framework": "^6.0.0"
"topthink/framework": "^6.0"
},
"time": "2020-07-12T13:50:37+00:00",
"time": "2022-10-26T08:03:06+00:00",
"type": "library",
"extra": {
"think": {
@ -1701,7 +1442,7 @@
"description": "thinkphp6 multi app support",
"support": {
"issues": "https://github.com/top-think/think-multi-app/issues",
"source": "https://github.com/top-think/think-multi-app/tree/master"
"source": "https://github.com/top-think/think-multi-app/tree/v1.0.15"
},
"install-path": "../topthink/think-multi-app"
},
@ -1815,24 +1556,30 @@
},
{
"name": "topthink/think-trace",
"version": "v1.4",
"version_normalized": "1.4.0.0",
"version": "v1.5",
"version_normalized": "1.5.0.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-trace.git",
"reference": "9a9fa8f767b6c66c5a133ad21ca1bc96ad329444"
"reference": "55027fd79abb744f32a3be8d9e1ccf873a3ca9b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-trace/zipball/9a9fa8f767b6c66c5a133ad21ca1bc96ad329444",
"reference": "9a9fa8f767b6c66c5a133ad21ca1bc96ad329444",
"shasum": ""
"url": "https://api.github.com/repos/top-think/think-trace/zipball/55027fd79abb744f32a3be8d9e1ccf873a3ca9b7",
"reference": "55027fd79abb744f32a3be8d9e1ccf873a3ca9b7",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.1.0",
"topthink/framework": "^6.0.0"
"topthink/framework": "^6.0"
},
"time": "2020-06-29T05:27:28+00:00",
"time": "2022-10-26T07:56:45+00:00",
"type": "library",
"extra": {
"think": {
@ -1863,7 +1610,7 @@
"description": "thinkphp debug trace",
"support": {
"issues": "https://github.com/top-think/think-trace/issues",
"source": "https://github.com/top-think/think-trace/tree/v1.4"
"source": "https://github.com/top-think/think-trace/tree/v1.5"
},
"install-path": "../topthink/think-trace"
},

View File

@ -5,45 +5,18 @@
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '2a77126a1909be677e6bde7c623bb5a0fb75d32b',
'reference' => 'ec0420fb511804f40321aab88a9025e147cf54f4',
'name' => 'shopxo/shopxo',
'dev' => true,
),
'versions' => array(
'ezyang/htmlpurifier' => array(
'pretty_version' => 'v4.14.0',
'version' => '4.14.0.0',
'pretty_version' => 'v4.16.0',
'version' => '4.16.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../ezyang/htmlpurifier',
'aliases' => array(),
'reference' => '12ab42bd6e742c70c0a52f7b82477fcd44e64b75',
'dev_requirement' => false,
),
'league/flysystem' => array(
'pretty_version' => '1.1.9',
'version' => '1.1.9.0',
'type' => 'library',
'install_path' => __DIR__ . '/../league/flysystem',
'aliases' => array(),
'reference' => '094defdb4a7001845300334e7c1ee2335925ef99',
'dev_requirement' => false,
),
'league/flysystem-cached-adapter' => array(
'pretty_version' => '1.1.0',
'version' => '1.1.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../league/flysystem-cached-adapter',
'aliases' => array(),
'reference' => 'd1925efb2207ac4be3ad0c40b8277175f99ffaff',
'dev_requirement' => false,
),
'league/mime-type-detection' => array(
'pretty_version' => '1.11.0',
'version' => '1.11.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../league/mime-type-detection',
'aliases' => array(),
'reference' => 'ff6248ea87a9f116e78edd6002e39e5128a0d4dd',
'reference' => '523407fb06eb9e5f3d59889b3978d5bfe94299c8',
'dev_requirement' => false,
),
'maennchen/zipstream-php' => array(
@ -92,21 +65,12 @@
'dev_requirement' => false,
),
'phpoffice/phpspreadsheet' => array(
'pretty_version' => '1.24.0',
'version' => '1.24.0.0',
'pretty_version' => '1.25.2',
'version' => '1.25.2.0',
'type' => 'library',
'install_path' => __DIR__ . '/../phpoffice/phpspreadsheet',
'aliases' => array(),
'reference' => 'ebe8745c92a7cac4514d040758393b5399633b83',
'dev_requirement' => false,
),
'psr/cache' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/cache',
'aliases' => array(),
'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8',
'reference' => 'a317a09e7def49852400a4b3eca4a4b0790ceeb5',
'dev_requirement' => false,
),
'psr/container' => array(
@ -169,52 +133,52 @@
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '2a77126a1909be677e6bde7c623bb5a0fb75d32b',
'reference' => 'ec0420fb511804f40321aab88a9025e147cf54f4',
'dev_requirement' => false,
),
'symfony/polyfill-mbstring' => array(
'pretty_version' => 'v1.26.0',
'version' => '1.26.0.0',
'pretty_version' => 'v1.27.0',
'version' => '1.27.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
'aliases' => array(),
'reference' => '9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e',
'reference' => '8ad114f6b39e2c98a8b0e3bd907732c207c2b534',
'dev_requirement' => false,
),
'symfony/polyfill-php72' => array(
'pretty_version' => 'v1.26.0',
'version' => '1.26.0.0',
'pretty_version' => 'v1.27.0',
'version' => '1.27.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php72',
'aliases' => array(),
'reference' => 'bf44a9fd41feaac72b074de600314a93e2ae78e2',
'reference' => '869329b1e9894268a8a61dabb69153029b7a8c97',
'dev_requirement' => true,
),
'symfony/polyfill-php80' => array(
'pretty_version' => 'v1.26.0',
'version' => '1.26.0.0',
'pretty_version' => 'v1.27.0',
'version' => '1.27.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
'aliases' => array(),
'reference' => 'cfa0ae98841b9e461207c13ab093d76b0fa7bace',
'reference' => '7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936',
'dev_requirement' => true,
),
'symfony/var-dumper' => array(
'pretty_version' => 'v4.4.44',
'version' => '4.4.44.0',
'pretty_version' => 'v4.4.47',
'version' => '4.4.47.0',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/var-dumper',
'aliases' => array(),
'reference' => 'f19951007dae942cc79b979c1fe26bfdfbeb54ed',
'reference' => '1069c7a3fca74578022fab6f81643248d02f8e63',
'dev_requirement' => true,
),
'topthink/framework' => array(
'pretty_version' => 'v6.0.13',
'version' => '6.0.13.0',
'pretty_version' => 'v6.1.1',
'version' => '6.1.1.0',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/framework',
'aliases' => array(),
'reference' => '126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6',
'reference' => '2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210',
'dev_requirement' => false,
),
'topthink/think-helper' => array(
@ -227,12 +191,12 @@
'dev_requirement' => false,
),
'topthink/think-multi-app' => array(
'pretty_version' => 'v1.0.14',
'version' => '1.0.14.0',
'pretty_version' => 'v1.0.15',
'version' => '1.0.15.0',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-multi-app',
'aliases' => array(),
'reference' => 'ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3',
'reference' => '387e0dac059c20f92cac5da41a871e10829c1c97',
'dev_requirement' => false,
),
'topthink/think-orm' => array(
@ -254,12 +218,12 @@
'dev_requirement' => false,
),
'topthink/think-trace' => array(
'pretty_version' => 'v1.4',
'version' => '1.4.0.0',
'pretty_version' => 'v1.5',
'version' => '1.5.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-trace',
'aliases' => array(),
'reference' => '9a9fa8f767b6c66c5a133ad21ca1bc96ad329444',
'reference' => '55027fd79abb744f32a3be8d9e1ccf873a3ca9b7',
'dev_requirement' => true,
),
'topthink/think-view' => array(

View File

@ -0,0 +1,6 @@
# [4.16.0](https://github.com/ezyang/htmlpurifier/compare/v4.15.0...v4.16.0) (2022-09-18)
### Features
* add semantic release ([#307](https://github.com/ezyang/htmlpurifier/issues/307)) ([db31243](https://github.com/ezyang/htmlpurifier/commit/db312435cb9d8d73395f75f9642a43ba6de5e903)), closes [#322](https://github.com/ezyang/htmlpurifier/issues/322) [#323](https://github.com/ezyang/htmlpurifier/issues/323) [#326](https://github.com/ezyang/htmlpurifier/issues/326) [#327](https://github.com/ezyang/htmlpurifier/issues/327) [#328](https://github.com/ezyang/htmlpurifier/issues/328) [#329](https://github.com/ezyang/htmlpurifier/issues/329) [#330](https://github.com/ezyang/htmlpurifier/issues/330) [#331](https://github.com/ezyang/htmlpurifier/issues/331) [#332](https://github.com/ezyang/htmlpurifier/issues/332) [#333](https://github.com/ezyang/htmlpurifier/issues/333) [#337](https://github.com/ezyang/htmlpurifier/issues/337) [#335](https://github.com/ezyang/htmlpurifier/issues/335) [ezyang/htmlpurifier#334](https://github.com/ezyang/htmlpurifier/issues/334) [#336](https://github.com/ezyang/htmlpurifier/issues/336) [#338](https://github.com/ezyang/htmlpurifier/issues/338)

View File

@ -1 +1 @@
4.14.0
4.15.0

View File

@ -13,7 +13,11 @@
}
],
"require": {
"php": ">=5.2"
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0"
},
"require-dev": {
"cerdic/css-tidy": "^1.7 || ^2.0",
"simpletest/simpletest": "dev-master"
},
"autoload": {
"psr-0": { "HTMLPurifier": "library/" },
@ -21,5 +25,20 @@
"exclude-from-classmap": [
"/library/HTMLPurifier/Language/"
]
}
},
"suggest": {
"cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.",
"ext-iconv": "Converts text to and from non-UTF-8 encodings",
"ext-bcmath": "Used for unit conversion and imagecrash protection",
"ext-tidy": "Used for pretty-printing HTML"
},
"config": {
"sort-packages": true
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/ezyang/simpletest.git"
}
]
}

View File

@ -7,7 +7,7 @@
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
* FILE, changes will be overwritten the next time the script is run.
*
* @version 4.14.0
* @version 4.15.0
*
* @warning
* You must *not* include any other HTML Purifier files before this file,
@ -107,6 +107,7 @@ require 'HTMLPurifier/AttrDef/HTML/Bool.php';
require 'HTMLPurifier/AttrDef/HTML/Nmtokens.php';
require 'HTMLPurifier/AttrDef/HTML/Class.php';
require 'HTMLPurifier/AttrDef/HTML/Color.php';
require 'HTMLPurifier/AttrDef/HTML/ContentEditable.php';
require 'HTMLPurifier/AttrDef/HTML/FrameTarget.php';
require 'HTMLPurifier/AttrDef/HTML/ID.php';
require 'HTMLPurifier/AttrDef/HTML/Pixels.php';

View File

@ -19,7 +19,7 @@
*/
/*
HTML Purifier 4.14.0 - Standards Compliant HTML Filtering
HTML Purifier 4.15.0 - Standards Compliant HTML Filtering
Copyright (C) 2006-2008 Edward Z. Yang
This library is free software; you can redistribute it and/or
@ -58,12 +58,12 @@ class HTMLPurifier
* Version of HTML Purifier.
* @type string
*/
public $version = '4.14.0';
public $version = '4.15.0';
/**
* Constant with version of HTML Purifier.
*/
const VERSION = '4.14.0';
const VERSION = '4.15.0';
/**
* Global configuration object.

View File

@ -101,6 +101,7 @@ require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Bool.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Nmtokens.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Class.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Color.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ContentEditable.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/FrameTarget.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ID.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Pixels.php';

View File

@ -0,0 +1,16 @@
<?php
class HTMLPurifier_AttrDef_HTML_ContentEditable extends HTMLPurifier_AttrDef
{
public function validate($string, $config, $context)
{
$allowed = array('false');
if ($config->get('HTML.Trusted')) {
$allowed = array('', 'true', 'false');
}
$enum = new HTMLPurifier_AttrDef_Enum($allowed);
return $enum->validate($string, $config, $context);
}
}

View File

@ -8,6 +8,11 @@
class HTMLPurifier_AttrTransform_NameSync extends HTMLPurifier_AttrTransform
{
/**
* @type HTMLPurifier_AttrDef_HTML_ID
*/
public $idDef;
public function __construct()
{
$this->idDef = new HTMLPurifier_AttrDef_HTML_ID();

View File

@ -24,6 +24,11 @@ class HTMLPurifier_AttrTransform_SafeParam extends HTMLPurifier_AttrTransform
*/
private $uri;
/**
* @type HTMLPurifier_AttrDef_Enum
*/
public $wmode;
public function __construct()
{
$this->uri = new HTMLPurifier_AttrDef_URI(true); // embedded

View File

@ -41,6 +41,7 @@ class HTMLPurifier_AttrTypes
$this->info['IAlign'] = self::makeEnum('top,middle,bottom,left,right');
$this->info['LAlign'] = self::makeEnum('top,bottom,left,right');
$this->info['FrameTarget'] = new HTMLPurifier_AttrDef_HTML_FrameTarget();
$this->info['ContentEditable'] = new HTMLPurifier_AttrDef_HTML_ContentEditable();
// unimplemented aliases
$this->info['ContentType'] = new HTMLPurifier_AttrDef_Text();

View File

@ -22,6 +22,8 @@ class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef
// XXX: This whole business with 'wrap' is all a bit unsatisfactory
public $elements = array('li' => true, 'ul' => true, 'ol' => true);
public $whitespace;
/**
* @param array $children
* @param HTMLPurifier_Config $config

View File

@ -21,7 +21,7 @@ class HTMLPurifier_Config
* HTML Purifier's version
* @type string
*/
public $version = '4.14.0';
public $version = '4.15.0';
/**
* Whether or not to automatically finalize

View File

@ -176,7 +176,7 @@ class HTMLPurifier_ElementDef
if (!empty($def->content_model)) {
$this->content_model =
str_replace("#SUPER", $this->content_model, $def->content_model);
str_replace("#SUPER", (string)$this->content_model, $def->content_model);
$this->child = false;
}
if (!empty($def->content_model_type)) {

View File

@ -398,8 +398,8 @@ class HTMLPurifier_Encoder
// characters to their true byte-wise ASCII/UTF-8 equivalents.
$str = strtr($str, self::testEncodingSupportsASCII($encoding));
return $str;
} elseif ($encoding === 'iso-8859-1') {
$str = utf8_encode($str);
} elseif ($encoding === 'iso-8859-1' && function_exists('mb_convert_encoding')) {
$str = mb_convert_encoding($str, 'UTF-8', 'ISO-8859-1');
return $str;
}
$bug = HTMLPurifier_Encoder::testIconvTruncateBug();
@ -450,8 +450,8 @@ class HTMLPurifier_Encoder
// Normal stuff
$str = self::iconv('utf-8', $encoding . '//IGNORE', $str);
return $str;
} elseif ($encoding === 'iso-8859-1') {
$str = utf8_decode($str);
} elseif ($encoding === 'iso-8859-1' && function_exists('mb_convert_encoding')) {
$str = mb_convert_encoding($str, 'ISO-8859-1', 'UTF-8');
return $str;
}
trigger_error('Encoding not supported', E_USER_ERROR);

View File

@ -17,6 +17,7 @@ class HTMLPurifier_HTMLModule_CommonAttributes extends HTMLPurifier_HTMLModule
'class' => 'Class',
'id' => 'ID',
'title' => 'CDATA',
'contenteditable' => 'ContentEditable',
),
'Lang' => array(),
'I18N' => array(

View File

@ -31,6 +31,16 @@ class HTMLPurifier_Injector_RemoveSpansWithoutAttributes extends HTMLPurifier_In
*/
private $context;
/**
* @type SplObjectStorage
*/
private $markForDeletion;
public function __construct()
{
$this->markForDeletion = new SplObjectStorage();
}
public function prepare($config, $context)
{
$this->attrValidator = new HTMLPurifier_AttrValidator();
@ -64,7 +74,7 @@ class HTMLPurifier_Injector_RemoveSpansWithoutAttributes extends HTMLPurifier_In
if ($current instanceof HTMLPurifier_Token_End && $current->name === 'span') {
// Mark closing span tag for deletion
$current->markForDeletion = true;
$this->markForDeletion->attach($current);
// Delete open span tag
$token = false;
}
@ -75,7 +85,8 @@ class HTMLPurifier_Injector_RemoveSpansWithoutAttributes extends HTMLPurifier_In
*/
public function handleEnd(&$token)
{
if ($token->markForDeletion) {
if ($this->markForDeletion->contains($token)) {
$this->markForDeletion->detach($token);
$token = false;
}
}

View File

@ -78,7 +78,7 @@ class HTMLPurifier_Length
if ($this->n === '0' && $this->unit === false) {
return true;
}
if (!ctype_lower($this->unit)) {
if ($this->unit === false || !ctype_lower($this->unit)) {
$this->unit = strtolower($this->unit);
}
if (!isset(HTMLPurifier_Length::$allowedUnits[$this->unit])) {

View File

@ -48,6 +48,11 @@ class HTMLPurifier_Lexer
*/
public $tracksLineNumbers = false;
/**
* @type HTMLPurifier_EntityParser
*/
private $_entity_parser;
// -- STATIC ----------------------------------------------------------
/**
@ -306,8 +311,8 @@ class HTMLPurifier_Lexer
{
// normalize newlines to \n
if ($config->get('Core.NormalizeNewlines')) {
$html = str_replace("\r\n", "\n", $html);
$html = str_replace("\r", "\n", $html);
$html = str_replace("\r\n", "\n", (string)$html);
$html = str_replace("\r", "\n", (string)$html);
}
if ($config->get('HTML.Trusted')) {

View File

@ -4410,7 +4410,7 @@ class HTML5TreeConstructer
foreach ($token['attr'] as $attr) {
if (!$el->hasAttribute($attr['name'])) {
$el->setAttribute($attr['name'], $attr['value']);
$el->setAttribute($attr['name'], (string)$attr['value']);
}
}

View File

@ -29,6 +29,7 @@ class HTMLPurifier_PropertyListIterator extends FilterIterator
/**
* @return bool
*/
#[\ReturnTypeWillChange]
public function accept()
{
$key = $this->getInnerIterator()->key();

View File

@ -20,6 +20,7 @@ class HTMLPurifier_StringHash extends ArrayObject
* @param mixed $index
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet($index)
{
$this->accessed[$index] = true;

View File

@ -35,7 +35,7 @@ class HTMLPurifier_URIFilter_HostBlacklist extends HTMLPurifier_URIFilter
public function filter(&$uri, $config, $context)
{
foreach ($this->blacklist as $blacklisted_host_fragment) {
if (strpos($uri->host, $blacklisted_host_fragment) !== false) {
if ($uri->host !== null && strpos($uri->host, $blacklisted_host_fragment) !== false) {
return false;
}
}

View File

@ -100,11 +100,11 @@ class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter
$string = $uri->toString();
// always available
$this->replace['%s'] = $string;
$this->replace['%r'] = $context->get('EmbeddedURI', true);
$token = $context->get('CurrentToken', true);
$this->replace['%n'] = $token ? $token->name : null;
$this->replace['%m'] = $context->get('CurrentAttr', true);
$this->replace['%p'] = $context->get('CurrentCSSProperty', true);
$this->replace['%r'] = $context->get('EmbeddedURI', true) ?: '';
$token = $context->get('CurrentToken', true) ?: '';
$this->replace['%n'] = $token ? $token->name : '';
$this->replace['%m'] = $context->get('CurrentAttr', true) ?: '';
$this->replace['%p'] = $context->get('CurrentCSSProperty', true) ?: '';
// not always available
if ($this->secretKey) {
$this->replace['%t'] = hash_hmac("sha256", $string, $this->secretKey);

View File

@ -1,10 +0,0 @@
; top-most EditorConfig file
root = true
; Unix-style newlines
[*]
end_of_line = LF
[*.php]
indent_style = space
indent_size = 4

View File

@ -1,4 +0,0 @@
coverage
coverage.xml
composer.lock
vendor

View File

@ -1,7 +0,0 @@
<?php
return Symfony\CS\Config\Config::create()
->level(Symfony\CS\FixerInterface::PSR2_LEVEL)
->fixers(['-yoda_conditions', 'ordered_use', 'short_array_syntax'])
->finder(Symfony\CS\Finder\DefaultFinder::create()
->in(__DIR__.'/src/'));

View File

@ -1,34 +0,0 @@
filter:
paths: [src/*]
checks:
php:
code_rating: true
remove_extra_empty_lines: true
remove_php_closing_tag: true
remove_trailing_whitespace: true
fix_use_statements:
remove_unused: true
preserve_multiple: false
preserve_blanklines: true
order_alphabetically: true
fix_php_opening_tag: true
fix_linefeed: true
fix_line_ending: true
fix_identation_4spaces: true
fix_doc_comments: true
tools:
external_code_coverage:
timeout: 900
runs: 6
php_code_coverage: false
php_code_sniffer:
config:
standard: PSR2
filter:
paths: ['src']
php_loc:
enabled: true
excluded_dirs: [vendor, spec, stubs]
php_cpd:
enabled: true
excluded_dirs: [vendor, spec, stubs]

View File

@ -1,29 +0,0 @@
language: php
php:
- 5.5
- 5.6
- 7.0
- 7.1
- 7.2
matrix:
allow_failures:
- php: 5.5
env:
- COMPOSER_OPTS=""
- COMPOSER_OPTS="--prefer-lowest"
install:
- if [[ "${TRAVIS_PHP_VERSION}" == "5.5" ]]; then composer require phpunit/phpunit:^4.8.36 phpspec/phpspec:^2 --prefer-dist --update-with-dependencies; fi
- if [[ "${TRAVIS_PHP_VERSION}" == "7.2" ]]; then composer require phpunit/phpunit:^6.0 --prefer-dist --update-with-dependencies; fi
- travis_retry composer update --prefer-dist $COMPOSER_OPTS
script:
- vendor/bin/phpspec run
- vendor/bin/phpunit
after_script:
- wget https://scrutinizer-ci.com/ocular.phar'
- php ocular.phar code-coverage:upload --format=php-clover ./clover/phpunit.xml'

View File

@ -1,19 +0,0 @@
Copyright (c) 2015 Frank de Jonge
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.

View File

@ -1,2 +0,0 @@
*
!.gitignore

View File

@ -1,30 +0,0 @@
{
"name": "league/flysystem-cached-adapter",
"description": "An adapter decorator to enable meta-data caching.",
"autoload": {
"psr-4": {
"League\\Flysystem\\Cached\\": "src/"
}
},
"require": {
"league/flysystem": "~1.0",
"psr/cache": "^1.0.0"
},
"require-dev": {
"phpspec/phpspec": "^3.4",
"phpunit/phpunit": "^5.7",
"mockery/mockery": "~0.9",
"predis/predis": "~1.0",
"tedivm/stash": "~0.12"
},
"suggest": {
"ext-phpredis": "Pure C implemented extension for PHP"
},
"license": "MIT",
"authors": [
{
"name": "frankdejonge",
"email": "info@frenky.net"
}
]
}

View File

@ -1,6 +0,0 @@
---
suites:
cached_adapter_suite:
namespace: League\Flysystem\Cached
psr4_prefix: League\Flysystem\Cached
formatter.name: pretty

View File

@ -1,3 +0,0 @@
<?php
include __DIR__.'/vendor/autoload.php';

View File

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="./phpunit.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="true"
verbose="true"
>
<testsuites>
<testsuite name="flysystem/tests">
<directory suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">./src/</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-text" target="php://stdout" showUncoveredFiles="true"/>
<log type="coverage-html" target="coverage" showUncoveredFiles="true"/>
<log type="coverage-clover" target="clover/phpunit.xml" showUncoveredFiles="true"/>
</logging>
</phpunit>

View File

@ -1,20 +0,0 @@
# Flysystem Cached CachedAdapter
[![Author](http://img.shields.io/badge/author-@frankdejonge-blue.svg?style=flat-square)](https://twitter.com/frankdejonge)
[![Build Status](https://img.shields.io/travis/thephpleague/flysystem-cached-adapter/master.svg?style=flat-square)](https://travis-ci.org/thephpleague/flysystem-cached-adapter)
[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/thephpleague/flysystem-cached-adapter.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/flysystem-cached-adapter/code-structure)
[![Quality Score](https://img.shields.io/scrutinizer/g/thephpleague/flysystem-cached-adapter.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/flysystem-cached-adapter)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
[![Packagist Version](https://img.shields.io/packagist/v/league/flysystem-cached-adapter.svg?style=flat-square)](https://packagist.org/packages/league/flysystem-cached-adapter)
[![Total Downloads](https://img.shields.io/packagist/dt/league/flysystem-cached-adapter.svg?style=flat-square)](https://packagist.org/packages/league/flysystem-cached-adapter)
The adapter decorator caches metadata and directory listings.
```bash
composer require league/flysystem-cached-adapter
```
## Usage
[Check out the docs.](https://flysystem.thephpleague.com/docs/advanced/caching/)

View File

@ -1,435 +0,0 @@
<?php
namespace spec\League\Flysystem\Cached;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Cached\CacheInterface;
use League\Flysystem\Config;
use PhpSpec\ObjectBehavior;
class CachedAdapterSpec extends ObjectBehavior
{
/**
* @var AdapterInterface
*/
private $adapter;
/**
* @var CacheInterface
*/
private $cache;
public function let(AdapterInterface $adapter, CacheInterface $cache)
{
$this->adapter = $adapter;
$this->cache = $cache;
$this->cache->load()->shouldBeCalled();
$this->beConstructedWith($adapter, $cache);
}
public function it_is_initializable()
{
$this->shouldHaveType('League\Flysystem\Cached\CachedAdapter');
$this->shouldHaveType('League\Flysystem\AdapterInterface');
}
public function it_should_forward_read_streams()
{
$path = 'path.txt';
$response = ['path' => $path];
$this->adapter->readStream($path)->willReturn($response);
$this->readStream($path)->shouldbe($response);
}
public function it_should_cache_writes()
{
$type = 'file';
$path = 'path.txt';
$contents = 'contents';
$config = new Config();
$response = compact('path', 'contents', 'type');
$this->adapter->write($path, $contents, $config)->willReturn($response);
$this->cache->updateObject($path, $response, true)->shouldBeCalled();
$this->write($path, $contents, $config)->shouldBe($response);
}
public function it_should_cache_streamed_writes()
{
$type = 'file';
$path = 'path.txt';
$stream = tmpfile();
$config = new Config();
$response = compact('path', 'stream', 'type');
$this->adapter->writeStream($path, $stream, $config)->willReturn($response);
$this->cache->updateObject($path, ['contents' => false] + $response, true)->shouldBeCalled();
$this->writeStream($path, $stream, $config)->shouldBe($response);
fclose($stream);
}
public function it_should_cache_streamed_updates()
{
$type = 'file';
$path = 'path.txt';
$stream = tmpfile();
$config = new Config();
$response = compact('path', 'stream', 'type');
$this->adapter->updateStream($path, $stream, $config)->willReturn($response);
$this->cache->updateObject($path, ['contents' => false] + $response, true)->shouldBeCalled();
$this->updateStream($path, $stream, $config)->shouldBe($response);
fclose($stream);
}
public function it_should_ignore_failed_writes()
{
$path = 'path.txt';
$contents = 'contents';
$config = new Config();
$this->adapter->write($path, $contents, $config)->willReturn(false);
$this->write($path, $contents, $config)->shouldBe(false);
}
public function it_should_ignore_failed_streamed_writes()
{
$path = 'path.txt';
$contents = tmpfile();
$config = new Config();
$this->adapter->writeStream($path, $contents, $config)->willReturn(false);
$this->writeStream($path, $contents, $config)->shouldBe(false);
fclose($contents);
}
public function it_should_cache_updated()
{
$type = 'file';
$path = 'path.txt';
$contents = 'contents';
$config = new Config();
$response = compact('path', 'contents', 'type');
$this->adapter->update($path, $contents, $config)->willReturn($response);
$this->cache->updateObject($path, $response, true)->shouldBeCalled();
$this->update($path, $contents, $config)->shouldBe($response);
}
public function it_should_ignore_failed_updates()
{
$path = 'path.txt';
$contents = 'contents';
$config = new Config();
$this->adapter->update($path, $contents, $config)->willReturn(false);
$this->update($path, $contents, $config)->shouldBe(false);
}
public function it_should_ignore_failed_streamed_updates()
{
$path = 'path.txt';
$contents = tmpfile();
$config = new Config();
$this->adapter->updateStream($path, $contents, $config)->willReturn(false);
$this->updateStream($path, $contents, $config)->shouldBe(false);
fclose($contents);
}
public function it_should_cache_renames()
{
$old = 'old.txt';
$new = 'new.txt';
$this->adapter->rename($old, $new)->willReturn(true);
$this->cache->rename($old, $new)->shouldBeCalled();
$this->rename($old, $new)->shouldBe(true);
}
public function it_should_ignore_rename_fails()
{
$old = 'old.txt';
$new = 'new.txt';
$this->adapter->rename($old, $new)->willReturn(false);
$this->rename($old, $new)->shouldBe(false);
}
public function it_should_cache_copies()
{
$old = 'old.txt';
$new = 'new.txt';
$this->adapter->copy($old, $new)->willReturn(true);
$this->cache->copy($old, $new)->shouldBeCalled();
$this->copy($old, $new)->shouldBe(true);
}
public function it_should_ignore_copy_fails()
{
$old = 'old.txt';
$new = 'new.txt';
$this->adapter->copy($old, $new)->willReturn(false);
$this->copy($old, $new)->shouldBe(false);
}
public function it_should_cache_deletes()
{
$delete = 'delete.txt';
$this->adapter->delete($delete)->willReturn(true);
$this->cache->delete($delete)->shouldBeCalled();
$this->delete($delete)->shouldBe(true);
}
public function it_should_ignore_delete_fails()
{
$delete = 'delete.txt';
$this->adapter->delete($delete)->willReturn(false);
$this->delete($delete)->shouldBe(false);
}
public function it_should_cache_dir_deletes()
{
$delete = 'delete';
$this->adapter->deleteDir($delete)->willReturn(true);
$this->cache->deleteDir($delete)->shouldBeCalled();
$this->deleteDir($delete)->shouldBe(true);
}
public function it_should_ignore_delete_dir_fails()
{
$delete = 'delete';
$this->adapter->deleteDir($delete)->willReturn(false);
$this->deleteDir($delete)->shouldBe(false);
}
public function it_should_cache_dir_creates()
{
$dirname = 'dirname';
$config = new Config();
$response = ['path' => $dirname, 'type' => 'dir'];
$this->adapter->createDir($dirname, $config)->willReturn($response);
$this->cache->updateObject($dirname, $response, true)->shouldBeCalled();
$this->createDir($dirname, $config)->shouldBe($response);
}
public function it_should_ignore_create_dir_fails()
{
$dirname = 'dirname';
$config = new Config();
$this->adapter->createDir($dirname, $config)->willReturn(false);
$this->createDir($dirname, $config)->shouldBe(false);
}
public function it_should_cache_set_visibility()
{
$path = 'path.txt';
$visibility = AdapterInterface::VISIBILITY_PUBLIC;
$this->adapter->setVisibility($path, $visibility)->willReturn(true);
$this->cache->updateObject($path, ['path' => $path, 'visibility' => $visibility], true)->shouldBeCalled();
$this->setVisibility($path, $visibility)->shouldBe(true);
}
public function it_should_ignore_set_visibility_fails()
{
$dirname = 'delete';
$visibility = AdapterInterface::VISIBILITY_PUBLIC;
$this->adapter->setVisibility($dirname, $visibility)->willReturn(false);
$this->setVisibility($dirname, $visibility)->shouldBe(false);
}
public function it_should_indicate_missing_files()
{
$this->cache->has($path = 'path.txt')->willReturn(false);
$this->has($path)->shouldBe(false);
}
public function it_should_indicate_file_existance()
{
$this->cache->has($path = 'path.txt')->willReturn(true);
$this->has($path)->shouldBe(true);
}
public function it_should_cache_missing_files()
{
$this->cache->has($path = 'path.txt')->willReturn(null);
$this->adapter->has($path)->willReturn(false);
$this->cache->storeMiss($path)->shouldBeCalled();
$this->has($path)->shouldBe(false);
}
public function it_should_delete_when_metadata_is_missing()
{
$path = 'path.txt';
$this->cache->has($path)->willReturn(true);
$this->cache->getSize($path)->willReturn(['path' => $path]);
$this->adapter->getSize($path)->willReturn($response = ['path' => $path, 'size' => 1024]);
$this->cache->updateObject($path, $response, true)->shouldBeCalled();
$this->getSize($path)->shouldBe($response);
}
public function it_should_cache_has()
{
$this->cache->has($path = 'path.txt')->willReturn(null);
$this->adapter->has($path)->willReturn(true);
$this->cache->updateObject($path, compact('path'), true)->shouldBeCalled();
$this->has($path)->shouldBe(true);
}
public function it_should_list_cached_contents()
{
$this->cache->isComplete($dirname = 'dirname', $recursive = true)->willReturn(true);
$response = [['path' => 'path.txt']];
$this->cache->listContents($dirname, $recursive)->willReturn($response);
$this->listContents($dirname, $recursive)->shouldBe($response);
}
public function it_should_ignore_failed_list_contents()
{
$this->cache->isComplete($dirname = 'dirname', $recursive = true)->willReturn(false);
$this->adapter->listContents($dirname, $recursive)->willReturn(false);
$this->listContents($dirname, $recursive)->shouldBe(false);
}
public function it_should_cache_contents_listings()
{
$this->cache->isComplete($dirname = 'dirname', $recursive = true)->willReturn(false);
$response = [['path' => 'path.txt']];
$this->adapter->listContents($dirname, $recursive)->willReturn($response);
$this->cache->storeContents($dirname, $response, $recursive)->shouldBeCalled();
$this->listContents($dirname, $recursive)->shouldBe($response);
}
public function it_should_use_cached_visibility()
{
$this->make_it_use_getter_cache('getVisibility', 'path.txt', [
'path' => 'path.txt',
'visibility' => AdapterInterface::VISIBILITY_PUBLIC,
]);
}
public function it_should_cache_get_visibility()
{
$path = 'path.txt';
$response = ['visibility' => AdapterInterface::VISIBILITY_PUBLIC, 'path' => $path];
$this->make_it_cache_getter('getVisibility', $path, $response);
}
public function it_should_ignore_failed_get_visibility()
{
$path = 'path.txt';
$this->make_it_ignore_failed_getter('getVisibility', $path);
}
public function it_should_use_cached_timestamp()
{
$this->make_it_use_getter_cache('getTimestamp', 'path.txt', [
'path' => 'path.txt',
'timestamp' => 1234,
]);
}
public function it_should_cache_timestamps()
{
$this->make_it_cache_getter('getTimestamp', 'path.txt', [
'path' => 'path.txt',
'timestamp' => 1234,
]);
}
public function it_should_ignore_failed_get_timestamps()
{
$this->make_it_ignore_failed_getter('getTimestamp', 'path.txt');
}
public function it_should_cache_get_metadata()
{
$path = 'path.txt';
$response = ['visibility' => AdapterInterface::VISIBILITY_PUBLIC, 'path' => $path];
$this->make_it_cache_getter('getMetadata', $path, $response);
}
public function it_should_use_cached_metadata()
{
$this->make_it_use_getter_cache('getMetadata', 'path.txt', [
'path' => 'path.txt',
'timestamp' => 1234,
]);
}
public function it_should_ignore_failed_get_metadata()
{
$this->make_it_ignore_failed_getter('getMetadata', 'path.txt');
}
public function it_should_cache_get_size()
{
$path = 'path.txt';
$response = ['size' => 1234, 'path' => $path];
$this->make_it_cache_getter('getSize', $path, $response);
}
public function it_should_use_cached_size()
{
$this->make_it_use_getter_cache('getSize', 'path.txt', [
'path' => 'path.txt',
'size' => 1234,
]);
}
public function it_should_ignore_failed_get_size()
{
$this->make_it_ignore_failed_getter('getSize', 'path.txt');
}
public function it_should_cache_get_mimetype()
{
$path = 'path.txt';
$response = ['mimetype' => 'text/plain', 'path' => $path];
$this->make_it_cache_getter('getMimetype', $path, $response);
}
public function it_should_use_cached_mimetype()
{
$this->make_it_use_getter_cache('getMimetype', 'path.txt', [
'path' => 'path.txt',
'mimetype' => 'text/plain',
]);
}
public function it_should_ignore_failed_get_mimetype()
{
$this->make_it_ignore_failed_getter('getMimetype', 'path.txt');
}
public function it_should_cache_reads()
{
$path = 'path.txt';
$response = ['path' => $path, 'contents' => 'contents'];
$this->make_it_cache_getter('read', $path, $response);
}
public function it_should_use_cached_file_contents()
{
$this->make_it_use_getter_cache('read', 'path.txt', [
'path' => 'path.txt',
'contents' => 'contents'
]);
}
public function it_should_ignore_failed_reads()
{
$this->make_it_ignore_failed_getter('read', 'path.txt');
}
protected function make_it_use_getter_cache($method, $path, $response)
{
$this->cache->{$method}($path)->willReturn($response);
$this->{$method}($path)->shouldBe($response);
}
protected function make_it_cache_getter($method, $path, $response)
{
$this->cache->{$method}($path)->willReturn(false);
$this->adapter->{$method}($path)->willReturn($response);
$this->cache->updateObject($path, $response, true)->shouldBeCalled();
$this->{$method}($path)->shouldBe($response);
}
protected function make_it_ignore_failed_getter($method, $path)
{
$this->cache->{$method}($path)->willReturn(false);
$this->adapter->{$method}($path)->willReturn(false);
$this->{$method}($path)->shouldBe(false);
}
}

View File

@ -1,101 +0,0 @@
<?php
namespace League\Flysystem\Cached;
use League\Flysystem\ReadInterface;
interface CacheInterface extends ReadInterface
{
/**
* Check whether the directory listing of a given directory is complete.
*
* @param string $dirname
* @param bool $recursive
*
* @return bool
*/
public function isComplete($dirname, $recursive);
/**
* Set a directory to completely listed.
*
* @param string $dirname
* @param bool $recursive
*/
public function setComplete($dirname, $recursive);
/**
* Store the contents of a directory.
*
* @param string $directory
* @param array $contents
* @param bool $recursive
*/
public function storeContents($directory, array $contents, $recursive);
/**
* Flush the cache.
*/
public function flush();
/**
* Autosave trigger.
*/
public function autosave();
/**
* Store the cache.
*/
public function save();
/**
* Load the cache.
*/
public function load();
/**
* Rename a file.
*
* @param string $path
* @param string $newpath
*/
public function rename($path, $newpath);
/**
* Copy a file.
*
* @param string $path
* @param string $newpath
*/
public function copy($path, $newpath);
/**
* Delete an object from cache.
*
* @param string $path object path
*/
public function delete($path);
/**
* Delete all objects from from a directory.
*
* @param string $dirname directory path
*/
public function deleteDir($dirname);
/**
* Update the metadata for an object.
*
* @param string $path object path
* @param array $object object metadata
* @param bool $autosave whether to trigger the autosave routine
*/
public function updateObject($path, array $object, $autosave = false);
/**
* Store object hit miss.
*
* @param string $path
*/
public function storeMiss($path);
}

View File

@ -1,346 +0,0 @@
<?php
namespace League\Flysystem\Cached;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Config;
class CachedAdapter implements AdapterInterface
{
/**
* @var AdapterInterface
*/
private $adapter;
/**
* @var CacheInterface
*/
private $cache;
/**
* Constructor.
*
* @param AdapterInterface $adapter
* @param CacheInterface $cache
*/
public function __construct(AdapterInterface $adapter, CacheInterface $cache)
{
$this->adapter = $adapter;
$this->cache = $cache;
$this->cache->load();
}
/**
* Get the underlying Adapter implementation.
*
* @return AdapterInterface
*/
public function getAdapter()
{
return $this->adapter;
}
/**
* Get the used Cache implementation.
*
* @return CacheInterface
*/
public function getCache()
{
return $this->cache;
}
/**
* {@inheritdoc}
*/
public function write($path, $contents, Config $config)
{
$result = $this->adapter->write($path, $contents, $config);
if ($result !== false) {
$result['type'] = 'file';
$this->cache->updateObject($path, $result + compact('path', 'contents'), true);
}
return $result;
}
/**
* {@inheritdoc}
*/
public function writeStream($path, $resource, Config $config)
{
$result = $this->adapter->writeStream($path, $resource, $config);
if ($result !== false) {
$result['type'] = 'file';
$contents = false;
$this->cache->updateObject($path, $result + compact('path', 'contents'), true);
}
return $result;
}
/**
* {@inheritdoc}
*/
public function update($path, $contents, Config $config)
{
$result = $this->adapter->update($path, $contents, $config);
if ($result !== false) {
$result['type'] = 'file';
$this->cache->updateObject($path, $result + compact('path', 'contents'), true);
}
return $result;
}
/**
* {@inheritdoc}
*/
public function updateStream($path, $resource, Config $config)
{
$result = $this->adapter->updateStream($path, $resource, $config);
if ($result !== false) {
$result['type'] = 'file';
$contents = false;
$this->cache->updateObject($path, $result + compact('path', 'contents'), true);
}
return $result;
}
/**
* {@inheritdoc}
*/
public function rename($path, $newPath)
{
$result = $this->adapter->rename($path, $newPath);
if ($result !== false) {
$this->cache->rename($path, $newPath);
}
return $result;
}
/**
* {@inheritdoc}
*/
public function copy($path, $newpath)
{
$result = $this->adapter->copy($path, $newpath);
if ($result !== false) {
$this->cache->copy($path, $newpath);
}
return $result;
}
/**
* {@inheritdoc}
*/
public function delete($path)
{
$result = $this->adapter->delete($path);
if ($result !== false) {
$this->cache->delete($path);
}
return $result;
}
/**
* {@inheritdoc}
*/
public function deleteDir($dirname)
{
$result = $this->adapter->deleteDir($dirname);
if ($result !== false) {
$this->cache->deleteDir($dirname);
}
return $result;
}
/**
* {@inheritdoc}
*/
public function createDir($dirname, Config $config)
{
$result = $this->adapter->createDir($dirname, $config);
if ($result !== false) {
$type = 'dir';
$path = $dirname;
$this->cache->updateObject($dirname, compact('path', 'type'), true);
}
return $result;
}
/**
* {@inheritdoc}
*/
public function setVisibility($path, $visibility)
{
$result = $this->adapter->setVisibility($path, $visibility);
if ($result !== false) {
$this->cache->updateObject($path, compact('path', 'visibility'), true);
}
return $result;
}
/**
* {@inheritdoc}
*/
public function has($path)
{
$cacheHas = $this->cache->has($path);
if ($cacheHas !== null) {
return $cacheHas;
}
$adapterResponse = $this->adapter->has($path);
if (! $adapterResponse) {
$this->cache->storeMiss($path);
} else {
$cacheEntry = is_array($adapterResponse) ? $adapterResponse : compact('path');
$this->cache->updateObject($path, $cacheEntry, true);
}
return $adapterResponse;
}
/**
* {@inheritdoc}
*/
public function read($path)
{
return $this->callWithFallback('contents', $path, 'read');
}
/**
* {@inheritdoc}
*/
public function readStream($path)
{
return $this->adapter->readStream($path);
}
/**
* Get the path prefix.
*
* @return string|null path prefix or null if pathPrefix is empty
*/
public function getPathPrefix()
{
return $this->adapter->getPathPrefix();
}
/**
* Prefix a path.
*
* @param string $path
*
* @return string prefixed path
*/
public function applyPathPrefix($path)
{
return $this->adapter->applyPathPrefix($path);
}
/**
* {@inheritdoc}
*/
public function listContents($directory = '', $recursive = false)
{
if ($this->cache->isComplete($directory, $recursive)) {
return $this->cache->listContents($directory, $recursive);
}
$result = $this->adapter->listContents($directory, $recursive);
if ($result !== false) {
$this->cache->storeContents($directory, $result, $recursive);
}
return $result;
}
/**
* {@inheritdoc}
*/
public function getMetadata($path)
{
return $this->callWithFallback(null, $path, 'getMetadata');
}
/**
* {@inheritdoc}
*/
public function getSize($path)
{
return $this->callWithFallback('size', $path, 'getSize');
}
/**
* {@inheritdoc}
*/
public function getMimetype($path)
{
return $this->callWithFallback('mimetype', $path, 'getMimetype');
}
/**
* {@inheritdoc}
*/
public function getTimestamp($path)
{
return $this->callWithFallback('timestamp', $path, 'getTimestamp');
}
/**
* {@inheritdoc}
*/
public function getVisibility($path)
{
return $this->callWithFallback('visibility', $path, 'getVisibility');
}
/**
* Call a method and cache the response.
*
* @param string $property
* @param string $path
* @param string $method
*
* @return mixed
*/
protected function callWithFallback($property, $path, $method)
{
$result = $this->cache->{$method}($path);
if ($result !== false && ($property === null || array_key_exists($property, $result))) {
return $result;
}
$result = $this->adapter->{$method}($path);
if ($result) {
$object = $result + compact('path');
$this->cache->updateObject($path, $object, true);
}
return $result;
}
}

View File

@ -1,418 +0,0 @@
<?php
namespace League\Flysystem\Cached\Storage;
use League\Flysystem\Cached\CacheInterface;
use League\Flysystem\Util;
abstract class AbstractCache implements CacheInterface
{
/**
* @var bool
*/
protected $autosave = true;
/**
* @var array
*/
protected $cache = [];
/**
* @var array
*/
protected $complete = [];
/**
* Destructor.
*/
public function __destruct()
{
if (! $this->autosave) {
$this->save();
}
}
/**
* Get the autosave setting.
*
* @return bool autosave
*/
public function getAutosave()
{
return $this->autosave;
}
/**
* Get the autosave setting.
*
* @param bool $autosave
*/
public function setAutosave($autosave)
{
$this->autosave = $autosave;
}
/**
* Store the contents listing.
*
* @param string $directory
* @param array $contents
* @param bool $recursive
*
* @return array contents listing
*/
public function storeContents($directory, array $contents, $recursive = false)
{
$directories = [$directory];
foreach ($contents as $object) {
$this->updateObject($object['path'], $object);
$object = $this->cache[$object['path']];
if ($recursive && $this->pathIsInDirectory($directory, $object['path'])) {
$directories[] = $object['dirname'];
}
}
foreach (array_unique($directories) as $directory) {
$this->setComplete($directory, $recursive);
}
$this->autosave();
}
/**
* Update the metadata for an object.
*
* @param string $path object path
* @param array $object object metadata
* @param bool $autosave whether to trigger the autosave routine
*/
public function updateObject($path, array $object, $autosave = false)
{
if (! $this->has($path)) {
$this->cache[$path] = Util::pathinfo($path);
}
$this->cache[$path] = array_merge($this->cache[$path], $object);
if ($autosave) {
$this->autosave();
}
$this->ensureParentDirectories($path);
}
/**
* Store object hit miss.
*
* @param string $path
*/
public function storeMiss($path)
{
$this->cache[$path] = false;
$this->autosave();
}
/**
* Get the contents listing.
*
* @param string $dirname
* @param bool $recursive
*
* @return array contents listing
*/
public function listContents($dirname = '', $recursive = false)
{
$result = [];
foreach ($this->cache as $object) {
if ($object === false) {
continue;
}
if ($object['dirname'] === $dirname) {
$result[] = $object;
} elseif ($recursive && $this->pathIsInDirectory($dirname, $object['path'])) {
$result[] = $object;
}
}
return $result;
}
/**
* {@inheritdoc}
*/
public function has($path)
{
if ($path !== false && array_key_exists($path, $this->cache)) {
return $this->cache[$path] !== false;
}
if ($this->isComplete(Util::dirname($path), false)) {
return false;
}
}
/**
* {@inheritdoc}
*/
public function read($path)
{
if (isset($this->cache[$path]['contents']) && $this->cache[$path]['contents'] !== false) {
return $this->cache[$path];
}
return false;
}
/**
* {@inheritdoc}
*/
public function readStream($path)
{
return false;
}
/**
* {@inheritdoc}
*/
public function rename($path, $newpath)
{
if ($this->has($path)) {
$object = $this->cache[$path];
unset($this->cache[$path]);
$object['path'] = $newpath;
$object = array_merge($object, Util::pathinfo($newpath));
$this->cache[$newpath] = $object;
$this->autosave();
}
}
/**
* {@inheritdoc}
*/
public function copy($path, $newpath)
{
if ($this->has($path)) {
$object = $this->cache[$path];
$object = array_merge($object, Util::pathinfo($newpath));
$this->updateObject($newpath, $object, true);
}
}
/**
* {@inheritdoc}
*/
public function delete($path)
{
$this->storeMiss($path);
}
/**
* {@inheritdoc}
*/
public function deleteDir($dirname)
{
foreach ($this->cache as $path => $object) {
if ($this->pathIsInDirectory($dirname, $path) || $path === $dirname) {
unset($this->cache[$path]);
}
}
unset($this->complete[$dirname]);
$this->autosave();
}
/**
* {@inheritdoc}
*/
public function getMimetype($path)
{
if (isset($this->cache[$path]['mimetype'])) {
return $this->cache[$path];
}
if (! $result = $this->read($path)) {
return false;
}
$mimetype = Util::guessMimeType($path, $result['contents']);
$this->cache[$path]['mimetype'] = $mimetype;
return $this->cache[$path];
}
/**
* {@inheritdoc}
*/
public function getSize($path)
{
if (isset($this->cache[$path]['size'])) {
return $this->cache[$path];
}
return false;
}
/**
* {@inheritdoc}
*/
public function getTimestamp($path)
{
if (isset($this->cache[$path]['timestamp'])) {
return $this->cache[$path];
}
return false;
}
/**
* {@inheritdoc}
*/
public function getVisibility($path)
{
if (isset($this->cache[$path]['visibility'])) {
return $this->cache[$path];
}
return false;
}
/**
* {@inheritdoc}
*/
public function getMetadata($path)
{
if (isset($this->cache[$path]['type'])) {
return $this->cache[$path];
}
return false;
}
/**
* {@inheritdoc}
*/
public function isComplete($dirname, $recursive)
{
if (! array_key_exists($dirname, $this->complete)) {
return false;
}
if ($recursive && $this->complete[$dirname] !== 'recursive') {
return false;
}
return true;
}
/**
* {@inheritdoc}
*/
public function setComplete($dirname, $recursive)
{
$this->complete[$dirname] = $recursive ? 'recursive' : true;
}
/**
* Filter the contents from a listing.
*
* @param array $contents object listing
*
* @return array filtered contents
*/
public function cleanContents(array $contents)
{
$cachedProperties = array_flip([
'path', 'dirname', 'basename', 'extension', 'filename',
'size', 'mimetype', 'visibility', 'timestamp', 'type',
'md5',
]);
foreach ($contents as $path => $object) {
if (is_array($object)) {
$contents[$path] = array_intersect_key($object, $cachedProperties);
}
}
return $contents;
}
/**
* {@inheritdoc}
*/
public function flush()
{
$this->cache = [];
$this->complete = [];
$this->autosave();
}
/**
* {@inheritdoc}
*/
public function autosave()
{
if ($this->autosave) {
$this->save();
}
}
/**
* Retrieve serialized cache data.
*
* @return string serialized data
*/
public function getForStorage()
{
$cleaned = $this->cleanContents($this->cache);
return json_encode([$cleaned, $this->complete]);
}
/**
* Load from serialized cache data.
*
* @param string $json
*/
public function setFromStorage($json)
{
list($cache, $complete) = json_decode($json, true);
if (json_last_error() === JSON_ERROR_NONE && is_array($cache) && is_array($complete)) {
$this->cache = $cache;
$this->complete = $complete;
}
}
/**
* Ensure parent directories of an object.
*
* @param string $path object path
*/
public function ensureParentDirectories($path)
{
$object = $this->cache[$path];
while ($object['dirname'] !== '' && ! isset($this->cache[$object['dirname']])) {
$object = Util::pathinfo($object['dirname']);
$object['type'] = 'dir';
$this->cache[$object['path']] = $object;
}
}
/**
* Determines if the path is inside the directory.
*
* @param string $directory
* @param string $path
*
* @return bool
*/
protected function pathIsInDirectory($directory, $path)
{
return $directory === '' || strpos($path, $directory . '/') === 0;
}
}

View File

@ -1,115 +0,0 @@
<?php
namespace League\Flysystem\Cached\Storage;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Config;
class Adapter extends AbstractCache
{
/**
* @var AdapterInterface An adapter
*/
protected $adapter;
/**
* @var string the file to cache to
*/
protected $file;
/**
* @var int|null seconds until cache expiration
*/
protected $expire = null;
/**
* Constructor.
*
* @param AdapterInterface $adapter adapter
* @param string $file the file to cache to
* @param int|null $expire seconds until cache expiration
*/
public function __construct(AdapterInterface $adapter, $file, $expire = null)
{
$this->adapter = $adapter;
$this->file = $file;
$this->setExpire($expire);
}
/**
* Set the expiration time in seconds.
*
* @param int $expire relative expiration time
*/
protected function setExpire($expire)
{
if ($expire) {
$this->expire = $this->getTime($expire);
}
}
/**
* Get expiration time in seconds.
*
* @param int $time relative expiration time
*
* @return int actual expiration time
*/
protected function getTime($time = 0)
{
return intval(microtime(true)) + $time;
}
/**
* {@inheritdoc}
*/
public function setFromStorage($json)
{
list($cache, $complete, $expire) = json_decode($json, true);
if (! $expire || $expire > $this->getTime()) {
$this->cache = is_array($cache) ? $cache : [];
$this->complete = is_array($complete) ? $complete : [];
} else {
$this->adapter->delete($this->file);
}
}
/**
* {@inheritdoc}
*/
public function load()
{
if ($this->adapter->has($this->file)) {
$file = $this->adapter->read($this->file);
if ($file && !empty($file['contents'])) {
$this->setFromStorage($file['contents']);
}
}
}
/**
* {@inheritdoc}
*/
public function getForStorage()
{
$cleaned = $this->cleanContents($this->cache);
return json_encode([$cleaned, $this->complete, $this->expire]);
}
/**
* {@inheritdoc}
*/
public function save()
{
$config = new Config();
$contents = $this->getForStorage();
if ($this->adapter->has($this->file)) {
$this->adapter->update($this->file, $contents, $config);
} else {
$this->adapter->write($this->file, $contents, $config);
}
}
}

View File

@ -1,59 +0,0 @@
<?php
namespace League\Flysystem\Cached\Storage;
use Memcached as NativeMemcached;
class Memcached extends AbstractCache
{
/**
* @var string storage key
*/
protected $key;
/**
* @var int|null seconds until cache expiration
*/
protected $expire;
/**
* @var \Memcached Memcached instance
*/
protected $memcached;
/**
* Constructor.
*
* @param \Memcached $memcached
* @param string $key storage key
* @param int|null $expire seconds until cache expiration
*/
public function __construct(NativeMemcached $memcached, $key = 'flysystem', $expire = null)
{
$this->key = $key;
$this->expire = $expire;
$this->memcached = $memcached;
}
/**
* {@inheritdoc}
*/
public function load()
{
$contents = $this->memcached->get($this->key);
if ($contents !== false) {
$this->setFromStorage($contents);
}
}
/**
* {@inheritdoc}
*/
public function save()
{
$contents = $this->getForStorage();
$expiration = $this->expire === null ? 0 : time() + $this->expire;
$this->memcached->set($this->key, $contents, $expiration);
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace League\Flysystem\Cached\Storage;
class Memory extends AbstractCache
{
/**
* {@inheritdoc}
*/
public function save()
{
// There is nothing to save
}
/**
* {@inheritdoc}
*/
public function load()
{
// There is nothing to load
}
}

View File

@ -1,171 +0,0 @@
<?php
namespace League\Flysystem\Cached\Storage;
class Noop extends AbstractCache
{
/**
* {@inheritdoc}
*/
protected $autosave = false;
/**
* {@inheritdoc}
*/
public function updateObject($path, array $object, $autosave = false)
{
return $object;
}
/**
* {@inheritdoc}
*/
public function isComplete($dirname, $recursive)
{
return false;
}
/**
* {@inheritdoc}
*/
public function setComplete($dirname, $recursive)
{
//
}
/**
* {@inheritdoc}
*/
public function copy($path, $newpath)
{
return false;
}
/**
* {@inheritdoc}
*/
public function rename($path, $newpath)
{
return false;
}
/**
* {@inheritdoc}
*/
public function storeContents($directory, array $contents, $recursive = false)
{
return $contents;
}
/**
* {@inheritdoc}
*/
public function storeMiss($path)
{
return $this;
}
/**
* {@inheritdoc}
*/
public function flush()
{
//
}
/**
* {@inheritdoc}
*/
public function autosave()
{
//
}
/**
* {@inheritdoc}
*/
public function save()
{
//
}
/**
* {@inheritdoc}
*/
public function load()
{
//
}
/**
* {@inheritdoc}
*/
public function has($path)
{
return;
}
/**
* {@inheritdoc}
*/
public function read($path)
{
return false;
}
/**
* {@inheritdoc}
*/
public function readStream($path)
{
return false;
}
/**
* {@inheritdoc}
*/
public function listContents($directory = '', $recursive = false)
{
return [];
}
/**
* {@inheritdoc}
*/
public function getMetadata($path)
{
return false;
}
/**
* {@inheritdoc}
*/
public function getSize($path)
{
return false;
}
/**
* {@inheritdoc}
*/
public function getMimetype($path)
{
return false;
}
/**
* {@inheritdoc}
*/
public function getTimestamp($path)
{
return false;
}
/**
* {@inheritdoc}
*/
public function getVisibility($path)
{
return false;
}
}

View File

@ -1,62 +0,0 @@
<?php
namespace League\Flysystem\Cached\Storage;
use Redis;
class PhpRedis extends AbstractCache
{
/**
* @var Redis PhpRedis Client
*/
protected $client;
/**
* @var string storage key
*/
protected $key;
/**
* @var int|null seconds until cache expiration
*/
protected $expire;
/**
* Constructor.
*
* @param Redis|null $client phpredis client
* @param string $key storage key
* @param int|null $expire seconds until cache expiration
*/
public function __construct(Redis $client = null, $key = 'flysystem', $expire = null)
{
$this->client = $client ?: new Redis();
$this->key = $key;
$this->expire = $expire;
}
/**
* {@inheritdoc}
*/
public function load()
{
$contents = $this->client->get($this->key);
if ($contents !== false) {
$this->setFromStorage($contents);
}
}
/**
* {@inheritdoc}
*/
public function save()
{
$contents = $this->getForStorage();
$this->client->set($this->key, $contents);
if ($this->expire !== null) {
$this->client->expire($this->key, $this->expire);
}
}
}

View File

@ -1,75 +0,0 @@
<?php
namespace League\Flysystem\Cached\Storage;
use Predis\Client;
class Predis extends AbstractCache
{
/**
* @var \Predis\Client Predis Client
*/
protected $client;
/**
* @var string storage key
*/
protected $key;
/**
* @var int|null seconds until cache expiration
*/
protected $expire;
/**
* Constructor.
*
* @param \Predis\Client $client predis client
* @param string $key storage key
* @param int|null $expire seconds until cache expiration
*/
public function __construct(Client $client = null, $key = 'flysystem', $expire = null)
{
$this->client = $client ?: new Client();
$this->key = $key;
$this->expire = $expire;
}
/**
* {@inheritdoc}
*/
public function load()
{
if (($contents = $this->executeCommand('get', [$this->key])) !== null) {
$this->setFromStorage($contents);
}
}
/**
* {@inheritdoc}
*/
public function save()
{
$contents = $this->getForStorage();
$this->executeCommand('set', [$this->key, $contents]);
if ($this->expire !== null) {
$this->executeCommand('expire', [$this->key, $this->expire]);
}
}
/**
* Execute a Predis command.
*
* @param string $name
* @param array $arguments
*
* @return string
*/
protected function executeCommand($name, array $arguments)
{
$command = $this->client->createCommand($name, $arguments);
return $this->client->executeCommand($command);
}
}

View File

@ -1,59 +0,0 @@
<?php
namespace League\Flysystem\Cached\Storage;
use Psr\Cache\CacheItemPoolInterface;
class Psr6Cache extends AbstractCache
{
/**
* @var CacheItemPoolInterface
*/
private $pool;
/**
* @var string storage key
*/
protected $key;
/**
* @var int|null seconds until cache expiration
*/
protected $expire;
/**
* Constructor.
*
* @param CacheItemPoolInterface $pool
* @param string $key storage key
* @param int|null $expire seconds until cache expiration
*/
public function __construct(CacheItemPoolInterface $pool, $key = 'flysystem', $expire = null)
{
$this->pool = $pool;
$this->key = $key;
$this->expire = $expire;
}
/**
* {@inheritdoc}
*/
public function save()
{
$item = $this->pool->getItem($this->key);
$item->set($this->getForStorage());
$item->expiresAfter($this->expire);
$this->pool->save($item);
}
/**
* {@inheritdoc}
*/
public function load()
{
$item = $this->pool->getItem($this->key);
if ($item->isHit()) {
$this->setFromStorage($item->get());
}
}
}

View File

@ -1,60 +0,0 @@
<?php
namespace League\Flysystem\Cached\Storage;
use Stash\Pool;
class Stash extends AbstractCache
{
/**
* @var string storage key
*/
protected $key;
/**
* @var int|null seconds until cache expiration
*/
protected $expire;
/**
* @var \Stash\Pool Stash pool instance
*/
protected $pool;
/**
* Constructor.
*
* @param \Stash\Pool $pool
* @param string $key storage key
* @param int|null $expire seconds until cache expiration
*/
public function __construct(Pool $pool, $key = 'flysystem', $expire = null)
{
$this->key = $key;
$this->expire = $expire;
$this->pool = $pool;
}
/**
* {@inheritdoc}
*/
public function load()
{
$item = $this->pool->getItem($this->key);
$contents = $item->get();
if ($item->isMiss() === false) {
$this->setFromStorage($contents);
}
}
/**
* {@inheritdoc}
*/
public function save()
{
$contents = $this->getForStorage();
$item = $this->pool->getItem($this->key);
$item->set($contents, $this->expire);
}
}

View File

@ -1,104 +0,0 @@
<?php
use League\Flysystem\Cached\Storage\Adapter;
use PHPUnit\Framework\TestCase;
class AdapterCacheTests extends TestCase
{
public function testLoadFail()
{
$adapter = Mockery::mock('League\Flysystem\AdapterInterface');
$adapter->shouldReceive('has')->once()->with('file.json')->andReturn(false);
$cache = new Adapter($adapter, 'file.json', 10);
$cache->load();
$this->assertFalse($cache->isComplete('', false));
}
public function testLoadExpired()
{
$response = ['contents' => json_encode([[], ['' => true], 1234567890]), 'path' => 'file.json'];
$adapter = Mockery::mock('League\Flysystem\AdapterInterface');
$adapter->shouldReceive('has')->once()->with('file.json')->andReturn(true);
$adapter->shouldReceive('read')->once()->with('file.json')->andReturn($response);
$adapter->shouldReceive('delete')->once()->with('file.json');
$cache = new Adapter($adapter, 'file.json', 10);
$cache->load();
$this->assertFalse($cache->isComplete('', false));
}
public function testLoadSuccess()
{
$response = ['contents' => json_encode([[], ['' => true], 9876543210]), 'path' => 'file.json'];
$adapter = Mockery::mock('League\Flysystem\AdapterInterface');
$adapter->shouldReceive('has')->once()->with('file.json')->andReturn(true);
$adapter->shouldReceive('read')->once()->with('file.json')->andReturn($response);
$cache = new Adapter($adapter, 'file.json', 10);
$cache->load();
$this->assertTrue($cache->isComplete('', false));
}
public function testSaveExists()
{
$response = json_encode([[], [], null]);
$adapter = Mockery::mock('League\Flysystem\AdapterInterface');
$adapter->shouldReceive('has')->once()->with('file.json')->andReturn(true);
$adapter->shouldReceive('update')->once()->with('file.json', $response, Mockery::any());
$cache = new Adapter($adapter, 'file.json', null);
$cache->save();
}
public function testSaveNew()
{
$response = json_encode([[], [], null]);
$adapter = Mockery::mock('League\Flysystem\AdapterInterface');
$adapter->shouldReceive('has')->once()->with('file.json')->andReturn(false);
$adapter->shouldReceive('write')->once()->with('file.json', $response, Mockery::any());
$cache = new Adapter($adapter, 'file.json', null);
$cache->save();
}
public function testStoreContentsRecursive()
{
$adapter = Mockery::mock('League\Flysystem\AdapterInterface');
$adapter->shouldReceive('has')->once()->with('file.json')->andReturn(false);
$adapter->shouldReceive('write')->once()->with('file.json', Mockery::any(), Mockery::any());
$cache = new Adapter($adapter, 'file.json', null);
$contents = [
['path' => 'foo/bar', 'dirname' => 'foo'],
['path' => 'afoo/bang', 'dirname' => 'afoo'],
];
$cache->storeContents('foo', $contents, true);
$this->assertTrue($cache->isComplete('foo', true));
$this->assertFalse($cache->isComplete('afoo', true));
}
public function testDeleteDir()
{
$cache_data = [
'foo' => ['path' => 'foo', 'type' => 'dir', 'dirname' => ''],
'foo/bar' => ['path' => 'foo/bar', 'type' => 'file', 'dirname' => 'foo'],
'foobaz' => ['path' => 'foobaz', 'type' => 'file', 'dirname' => ''],
];
$response = [
'contents' => json_encode([$cache_data, [], null]),
'path' => 'file.json',
];
$adapter = Mockery::mock('League\Flysystem\AdapterInterface');
$adapter->shouldReceive('has')->zeroOrMoreTimes()->with('file.json')->andReturn(true);
$adapter->shouldReceive('read')->once()->with('file.json')->andReturn($response);
$adapter->shouldReceive('update')->once()->with('file.json', Mockery::any(), Mockery::any())->andReturn(true);
$cache = new Adapter($adapter, 'file.json', null);
$cache->load();
$cache->deleteDir('foo', true);
$this->assertSame(1, count($cache->listContents('', true)));
}
}

View File

@ -1,16 +0,0 @@
<?php
use League\Flysystem\Cached\CachedAdapter;
use PHPUnit\Framework\TestCase;
class InspectionTests extends TestCase {
public function testGetAdapter()
{
$adapter = Mockery::mock('League\Flysystem\AdapterInterface');
$cache = Mockery::mock('League\Flysystem\Cached\CacheInterface');
$cache->shouldReceive('load')->once();
$cached_adapter = new CachedAdapter($adapter, $cache);
$this->assertInstanceOf('League\Flysystem\AdapterInterface', $cached_adapter->getAdapter());
}
}

View File

@ -1,35 +0,0 @@
<?php
use League\Flysystem\Cached\Storage\Memcached;
use PHPUnit\Framework\TestCase;
class MemcachedTests extends TestCase
{
public function testLoadFail()
{
$client = Mockery::mock('Memcached');
$client->shouldReceive('get')->once()->andReturn(false);
$cache = new Memcached($client);
$cache->load();
$this->assertFalse($cache->isComplete('', false));
}
public function testLoadSuccess()
{
$response = json_encode([[], ['' => true]]);
$client = Mockery::mock('Memcached');
$client->shouldReceive('get')->once()->andReturn($response);
$cache = new Memcached($client);
$cache->load();
$this->assertTrue($cache->isComplete('', false));
}
public function testSave()
{
$response = json_encode([[], []]);
$client = Mockery::mock('Memcached');
$client->shouldReceive('set')->once()->andReturn($response);
$cache = new Memcached($client);
$cache->save();
}
}

View File

@ -1,255 +0,0 @@
<?php
use League\Flysystem\Cached\Storage\Memory;
use League\Flysystem\Util;
use PHPUnit\Framework\TestCase;
class MemoryCacheTests extends TestCase
{
public function testAutosave()
{
$cache = new Memory();
$cache->setAutosave(true);
$this->assertTrue($cache->getAutosave());
$cache->setAutosave(false);
$this->assertFalse($cache->getAutosave());
}
public function testCacheMiss()
{
$cache = new Memory();
$cache->storeMiss('path.txt');
$this->assertFalse($cache->has('path.txt'));
}
public function testIsComplete()
{
$cache = new Memory();
$this->assertFalse($cache->isComplete('dirname', false));
$cache->setComplete('dirname', false);
$this->assertFalse($cache->isComplete('dirname', true));
$cache->setComplete('dirname', true);
$this->assertTrue($cache->isComplete('dirname', true));
}
public function testCleanContents()
{
$cache = new Memory();
$input = [[
'path' => 'path.txt',
'visibility' => 'public',
'invalid' => 'thing',
]];
$expected = [[
'path' => 'path.txt',
'visibility' => 'public',
]];
$output = $cache->cleanContents($input);
$this->assertEquals($expected, $output);
}
public function testGetForStorage()
{
$cache = new Memory();
$input = [[
'path' => 'path.txt',
'visibility' => 'public',
'type' => 'file',
]];
$cache->storeContents('', $input, true);
$contents = $cache->listContents('', true);
$cached = [];
foreach ($contents as $item) {
$cached[$item['path']] = $item;
}
$this->assertEquals(json_encode([$cached, ['' => 'recursive']]), $cache->getForStorage());
}
public function testParentCompleteIsUsedDuringHas()
{
$cache = new Memory();
$cache->setComplete('dirname', false);
$this->assertFalse($cache->has('dirname/path.txt'));
}
public function testFlush()
{
$cache = new Memory();
$cache->setComplete('dirname', true);
$cache->updateObject('path.txt', [
'path' => 'path.txt',
'visibility' => 'public',
]);
$cache->flush();
$this->assertFalse($cache->isComplete('dirname', true));
$this->assertNull($cache->has('path.txt'));
}
public function testSetFromStorage()
{
$cache = new Memory();
$json = [[
'path.txt' => ['path' => 'path.txt', 'type' => 'file'],
], ['dirname' => 'recursive']];
$jsonString = json_encode($json);
$cache->setFromStorage($jsonString);
$this->assertTrue($cache->has('path.txt'));
$this->assertTrue($cache->isComplete('dirname', true));
}
public function testGetMetadataFail()
{
$cache = new Memory();
$this->assertFalse($cache->getMetadata('path.txt'));
}
public function metaGetterProvider()
{
return [
['getTimestamp', 'timestamp', 12344],
['getMimetype', 'mimetype', 'text/plain'],
['getSize', 'size', 12],
['getVisibility', 'visibility', 'private'],
['read', 'contents', '__contents__'],
];
}
/**
* @dataProvider metaGetterProvider
*
* @param $method
* @param $key
* @param $value
*/
public function testMetaGetters($method, $key, $value)
{
$cache = new Memory();
$this->assertFalse($cache->{$method}('path.txt'));
$cache->updateObject('path.txt', $object = [
'path' => 'path.txt',
'type' => 'file',
$key => $value,
] + Util::pathinfo('path.txt'), true);
$this->assertEquals($object, $cache->{$method}('path.txt'));
$this->assertEquals($object, $cache->getMetadata('path.txt'));
}
public function testGetDerivedMimetype()
{
$cache = new Memory();
$cache->updateObject('path.txt', [
'contents' => 'something',
]);
$response = $cache->getMimetype('path.txt');
$this->assertEquals('text/plain', $response['mimetype']);
}
public function testCopyFail()
{
$cache = new Memory();
$cache->copy('one', 'two');
$this->assertNull($cache->has('two'));
$this->assertNull($cache->load());
}
public function testStoreContents()
{
$cache = new Memory();
$cache->storeContents('dirname', [
['path' => 'dirname', 'type' => 'dir'],
['path' => 'dirname/nested', 'type' => 'dir'],
['path' => 'dirname/nested/deep', 'type' => 'dir'],
['path' => 'other/nested/deep', 'type' => 'dir'],
], true);
$this->isTrue($cache->isComplete('other/nested', true));
}
public function testDelete()
{
$cache = new Memory();
$cache->updateObject('path.txt', ['type' => 'file']);
$this->assertTrue($cache->has('path.txt'));
$cache->delete('path.txt');
$this->assertFalse($cache->has('path.txt'));
}
public function testDeleteDir()
{
$cache = new Memory();
$cache->storeContents('dirname', [
['path' => 'dirname/path.txt', 'type' => 'file'],
]);
$this->assertTrue($cache->isComplete('dirname', false));
$this->assertTrue($cache->has('dirname/path.txt'));
$cache->deleteDir('dirname');
$this->assertFalse($cache->isComplete('dirname', false));
$this->assertNull($cache->has('dirname/path.txt'));
}
public function testReadStream()
{
$cache = new Memory();
$this->assertFalse($cache->readStream('path.txt'));
}
public function testRename()
{
$cache = new Memory();
$cache->updateObject('path.txt', ['type' => 'file']);
$cache->rename('path.txt', 'newpath.txt');
$this->assertTrue($cache->has('newpath.txt'));
}
public function testCopy()
{
$cache = new Memory();
$cache->updateObject('path.txt', ['type' => 'file']);
$cache->copy('path.txt', 'newpath.txt');
$this->assertTrue($cache->has('newpath.txt'));
}
public function testComplextListContents()
{
$cache = new Memory();
$cache->storeContents('', [
['path' => 'dirname', 'type' => 'dir'],
['path' => 'dirname/file.txt', 'type' => 'file'],
['path' => 'other', 'type' => 'dir'],
['path' => 'other/file.txt', 'type' => 'file'],
['path' => 'other/nested/file.txt', 'type' => 'file'],
]);
$this->assertCount(3, $cache->listContents('other', true));
}
public function testComplextListContentsWithDeletedFile()
{
$cache = new Memory();
$cache->storeContents('', [
['path' => 'dirname', 'type' => 'dir'],
['path' => 'dirname/file.txt', 'type' => 'file'],
['path' => 'other', 'type' => 'dir'],
['path' => 'other/file.txt', 'type' => 'file'],
['path' => 'other/another_file.txt', 'type' => 'file'],
]);
$cache->delete('other/another_file.txt');
$this->assertCount(4, $cache->listContents('', true));
}
public function testCacheMissIfContentsIsFalse()
{
$cache = new Memory();
$cache->updateObject('path.txt', [
'path' => 'path.txt',
'contents' => false,
], true);
$this->assertFalse($cache->read('path.txt'));
}
}

View File

@ -1,35 +0,0 @@
<?php
use League\Flysystem\Cached\Storage\Noop;
use PHPUnit\Framework\TestCase;
class NoopCacheTests extends TestCase
{
public function testNoop()
{
$cache = new Noop();
$this->assertEquals($cache, $cache->storeMiss('file.txt'));
$this->assertNull($cache->setComplete('', false));
$this->assertNull($cache->load());
$this->assertNull($cache->flush());
$this->assertNull($cache->has('path.txt'));
$this->assertNull($cache->autosave());
$this->assertFalse($cache->isComplete('', false));
$this->assertFalse($cache->read('something'));
$this->assertFalse($cache->readStream('something'));
$this->assertFalse($cache->getMetadata('something'));
$this->assertFalse($cache->getMimetype('something'));
$this->assertFalse($cache->getSize('something'));
$this->assertFalse($cache->getTimestamp('something'));
$this->assertFalse($cache->getVisibility('something'));
$this->assertEmpty($cache->listContents('', false));
$this->assertFalse($cache->rename('', ''));
$this->assertFalse($cache->copy('', ''));
$this->assertNull($cache->save());
$object = ['path' => 'path.ext'];
$this->assertEquals($object, $cache->updateObject('path.txt', $object));
$this->assertEquals([['path' => 'some/file.txt']], $cache->storeContents('unknwon', [
['path' => 'some/file.txt'],
], false));
}
}

View File

@ -1,45 +0,0 @@
<?php
use League\Flysystem\Cached\Storage\PhpRedis;
use PHPUnit\Framework\TestCase;
class PhpRedisTests extends TestCase
{
public function testLoadFail()
{
$client = Mockery::mock('Redis');
$client->shouldReceive('get')->with('flysystem')->once()->andReturn(false);
$cache = new PhpRedis($client);
$cache->load();
$this->assertFalse($cache->isComplete('', false));
}
public function testLoadSuccess()
{
$response = json_encode([[], ['' => true]]);
$client = Mockery::mock('Redis');
$client->shouldReceive('get')->with('flysystem')->once()->andReturn($response);
$cache = new PhpRedis($client);
$cache->load();
$this->assertTrue($cache->isComplete('', false));
}
public function testSave()
{
$data = json_encode([[], []]);
$client = Mockery::mock('Redis');
$client->shouldReceive('set')->with('flysystem', $data)->once();
$cache = new PhpRedis($client);
$cache->save();
}
public function testSaveWithExpire()
{
$data = json_encode([[], []]);
$client = Mockery::mock('Redis');
$client->shouldReceive('set')->with('flysystem', $data)->once();
$client->shouldReceive('expire')->with('flysystem', 20)->once();
$cache = new PhpRedis($client, 'flysystem', 20);
$cache->save();
}
}

View File

@ -1,55 +0,0 @@
<?php
use League\Flysystem\Cached\Storage\Predis;
use PHPUnit\Framework\TestCase;
class PredisTests extends TestCase
{
public function testLoadFail()
{
$client = Mockery::mock('Predis\Client');
$command = Mockery::mock('Predis\Command\CommandInterface');
$client->shouldReceive('createCommand')->with('get', ['flysystem'])->once()->andReturn($command);
$client->shouldReceive('executeCommand')->with($command)->andReturn(null);
$cache = new Predis($client);
$cache->load();
$this->assertFalse($cache->isComplete('', false));
}
public function testLoadSuccess()
{
$response = json_encode([[], ['' => true]]);
$client = Mockery::mock('Predis\Client');
$command = Mockery::mock('Predis\Command\CommandInterface');
$client->shouldReceive('createCommand')->with('get', ['flysystem'])->once()->andReturn($command);
$client->shouldReceive('executeCommand')->with($command)->andReturn($response);
$cache = new Predis($client);
$cache->load();
$this->assertTrue($cache->isComplete('', false));
}
public function testSave()
{
$data = json_encode([[], []]);
$client = Mockery::mock('Predis\Client');
$command = Mockery::mock('Predis\Command\CommandInterface');
$client->shouldReceive('createCommand')->with('set', ['flysystem', $data])->once()->andReturn($command);
$client->shouldReceive('executeCommand')->with($command)->once();
$cache = new Predis($client);
$cache->save();
}
public function testSaveWithExpire()
{
$data = json_encode([[], []]);
$client = Mockery::mock('Predis\Client');
$command = Mockery::mock('Predis\Command\CommandInterface');
$client->shouldReceive('createCommand')->with('set', ['flysystem', $data])->once()->andReturn($command);
$client->shouldReceive('executeCommand')->with($command)->once();
$expireCommand = Mockery::mock('Predis\Command\CommandInterface');
$client->shouldReceive('createCommand')->with('expire', ['flysystem', 20])->once()->andReturn($expireCommand);
$client->shouldReceive('executeCommand')->with($expireCommand)->once();
$cache = new Predis($client, 'flysystem', 20);
$cache->save();
}
}

View File

@ -1,45 +0,0 @@
<?php
use League\Flysystem\Cached\Storage\Psr6Cache;
use PHPUnit\Framework\TestCase;
class Psr6CacheTests extends TestCase
{
public function testLoadFail()
{
$pool = Mockery::mock('Psr\Cache\CacheItemPoolInterface');
$item = Mockery::mock('Psr\Cache\CacheItemInterface');
$item->shouldReceive('isHit')->once()->andReturn(false);
$pool->shouldReceive('getItem')->once()->andReturn($item);
$cache = new Psr6Cache($pool);
$cache->load();
$this->assertFalse($cache->isComplete('', false));
}
public function testLoadSuccess()
{
$response = json_encode([[], ['' => true]]);
$pool = Mockery::mock('Psr\Cache\CacheItemPoolInterface');
$item = Mockery::mock('Psr\Cache\CacheItemInterface');
$item->shouldReceive('get')->once()->andReturn($response);
$item->shouldReceive('isHit')->once()->andReturn(true);
$pool->shouldReceive('getItem')->once()->andReturn($item);
$cache = new Psr6Cache($pool);
$cache->load();
$this->assertTrue($cache->isComplete('', false));
}
public function testSave()
{
$response = json_encode([[], []]);
$ttl = 4711;
$pool = Mockery::mock('Psr\Cache\CacheItemPoolInterface');
$item = Mockery::mock('Psr\Cache\CacheItemInterface');
$item->shouldReceive('expiresAfter')->once()->with($ttl);
$item->shouldReceive('set')->once()->andReturn($response);
$pool->shouldReceive('getItem')->once()->andReturn($item);
$pool->shouldReceive('save')->once()->with($item);
$cache = new Psr6Cache($pool, 'foo', $ttl);
$cache->save();
}
}

View File

@ -1,43 +0,0 @@
<?php
use League\Flysystem\Cached\Storage\Stash;
use PHPUnit\Framework\TestCase;
class StashTests extends TestCase
{
public function testLoadFail()
{
$pool = Mockery::mock('Stash\Pool');
$item = Mockery::mock('Stash\Item');
$item->shouldReceive('get')->once()->andReturn(null);
$item->shouldReceive('isMiss')->once()->andReturn(true);
$pool->shouldReceive('getItem')->once()->andReturn($item);
$cache = new Stash($pool);
$cache->load();
$this->assertFalse($cache->isComplete('', false));
}
public function testLoadSuccess()
{
$response = json_encode([[], ['' => true]]);
$pool = Mockery::mock('Stash\Pool');
$item = Mockery::mock('Stash\Item');
$item->shouldReceive('get')->once()->andReturn($response);
$item->shouldReceive('isMiss')->once()->andReturn(false);
$pool->shouldReceive('getItem')->once()->andReturn($item);
$cache = new Stash($pool);
$cache->load();
$this->assertTrue($cache->isComplete('', false));
}
public function testSave()
{
$response = json_encode([[], []]);
$pool = Mockery::mock('Stash\Pool');
$item = Mockery::mock('Stash\Item');
$item->shouldReceive('set')->once()->andReturn($response);
$pool->shouldReceive('getItem')->once()->andReturn($item);
$cache = new Stash($pool);
$cache->save();
}
}

View File

@ -1,76 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at info+flysystem@frankdejonge.nl. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

View File

@ -1,19 +0,0 @@
Copyright (c) 2013-2019 Frank de Jonge
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.

View File

@ -1,16 +0,0 @@
# Security Policy
## Supported Versions
| Version | Supported |
| ------- | ------------------ |
| 1.0.x | :white_check_mark: |
| 2.0.x | :x: |
## Reporting a Vulnerability
When you've encountered a security vulnerability, please disclose it securely.
The security process is described at:
[https://flysystem.thephpleague.com/docs/security/](https://flysystem.thephpleague.com/docs/security/)

View File

@ -1,68 +0,0 @@
{
"name": "league/flysystem",
"type": "library",
"description": "Filesystem abstraction: Many filesystems, one API.",
"keywords": [
"filesystem", "filesystems", "files", "storage", "dropbox", "aws",
"abstraction", "s3", "ftp", "sftp", "remote", "webdav",
"file systems", "cloud", "cloud files", "rackspace", "copy.com"
],
"funding": [
{
"type": "other",
"url": "https://offset.earth/frankdejonge"
}
],
"license": "MIT",
"authors": [
{
"name": "Frank de Jonge",
"email": "info@frenky.net"
}
],
"require": {
"php": "^7.2.5 || ^8.0",
"ext-fileinfo": "*",
"league/mime-type-detection": "^1.3"
},
"require-dev": {
"phpspec/prophecy": "^1.11.1",
"phpunit/phpunit": "^8.5.8"
},
"autoload": {
"psr-4": {
"League\\Flysystem\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"League\\Flysystem\\Stub\\": "stub/"
}
},
"suggest": {
"league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem",
"league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files",
"league/flysystem-azure": "Allows you to use Windows Azure Blob storage",
"league/flysystem-webdav": "Allows you to use WebDAV storage",
"league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2",
"league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3",
"spatie/flysystem-dropbox": "Allows you to use Dropbox storage",
"srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications",
"league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching",
"ext-ftp": "Allows you to use FTP server storage",
"ext-openssl": "Allows you to use FTPS server storage",
"league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib",
"league/flysystem-ziparchive": "Allows you to use ZipArchive adapter"
},
"conflict": {
"league/flysystem-sftp": "<1.0.6"
},
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
}
},
"scripts": {
"phpstan": "php phpstan.php"
}
}

View File

@ -1,19 +0,0 @@
# Deprecations
This document lists all the planned deprecations.
## Handlers will be removed in 2.0
The `Handler` type and associated calls will be removed in version 2.0.
### Upgrade path
You should create your own implementation for handling OOP usage,
but it's recommended to move away from using an OOP-style wrapper entirely.
The reason for this is that it's too easy for implementation details (for
your application this is Flysystem) to leak into the application. The most
important part for Flysystem is that it improves portability and creates a
solid boundary between your application core and the infrastructure you use.
The OOP-style handling breaks this principle, therefore I want to stop
promoting it.

View File

@ -1,72 +0,0 @@
<?php
namespace League\Flysystem\Adapter;
use League\Flysystem\AdapterInterface;
abstract class AbstractAdapter implements AdapterInterface
{
/**
* @var string|null path prefix
*/
protected $pathPrefix;
/**
* @var string
*/
protected $pathSeparator = '/';
/**
* Set the path prefix.
*
* @param string $prefix
*
* @return void
*/
public function setPathPrefix($prefix)
{
$prefix = (string) $prefix;
if ($prefix === '') {
$this->pathPrefix = null;
return;
}
$this->pathPrefix = rtrim($prefix, '\\/') . $this->pathSeparator;
}
/**
* Get the path prefix.
*
* @return string|null path prefix or null if pathPrefix is empty
*/
public function getPathPrefix()
{
return $this->pathPrefix;
}
/**
* Prefix a path.
*
* @param string $path
*
* @return string prefixed path
*/
public function applyPathPrefix($path)
{
return $this->getPathPrefix() . ltrim($path, '\\/');
}
/**
* Remove a path prefix.
*
* @param string $path
*
* @return string path without the prefix
*/
public function removePathPrefix($path)
{
return substr($path, strlen((string) $this->getPathPrefix()));
}
}

View File

@ -1,705 +0,0 @@
<?php
namespace League\Flysystem\Adapter;
use DateTime;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Config;
use League\Flysystem\NotSupportedException;
use League\Flysystem\SafeStorage;
use RuntimeException;
abstract class AbstractFtpAdapter extends AbstractAdapter
{
/**
* @var mixed
*/
protected $connection;
/**
* @var string
*/
protected $host;
/**
* @var int
*/
protected $port = 21;
/**
* @var bool
*/
protected $ssl = false;
/**
* @var int
*/
protected $timeout = 90;
/**
* @var bool
*/
protected $passive = true;
/**
* @var string
*/
protected $separator = '/';
/**
* @var string|null
*/
protected $root;
/**
* @var int
*/
protected $permPublic = 0744;
/**
* @var int
*/
protected $permPrivate = 0700;
/**
* @var array
*/
protected $configurable = [];
/**
* @var string
*/
protected $systemType;
/**
* @var SafeStorage
*/
protected $safeStorage;
/**
* True to enable timestamps for FTP servers that return unix-style listings.
*
* @var bool
*/
protected $enableTimestampsOnUnixListings = false;
/**
* Constructor.
*
* @param array $config
*/
public function __construct(array $config)
{
$this->safeStorage = new SafeStorage();
$this->setConfig($config);
}
/**
* Set the config.
*
* @param array $config
*
* @return $this
*/
public function setConfig(array $config)
{
foreach ($this->configurable as $setting) {
if ( ! isset($config[$setting])) {
continue;
}
$method = 'set' . ucfirst($setting);
if (method_exists($this, $method)) {
$this->$method($config[$setting]);
}
}
return $this;
}
/**
* Returns the host.
*
* @return string
*/
public function getHost()
{
return $this->host;
}
/**
* Set the host.
*
* @param string $host
*
* @return $this
*/
public function setHost($host)
{
$this->host = $host;
return $this;
}
/**
* Set the public permission value.
*
* @param int $permPublic
*
* @return $this
*/
public function setPermPublic($permPublic)
{
$this->permPublic = $permPublic;
return $this;
}
/**
* Set the private permission value.
*
* @param int $permPrivate
*
* @return $this
*/
public function setPermPrivate($permPrivate)
{
$this->permPrivate = $permPrivate;
return $this;
}
/**
* Returns the ftp port.
*
* @return int
*/
public function getPort()
{
return $this->port;
}
/**
* Returns the root folder to work from.
*
* @return string
*/
public function getRoot()
{
return $this->root;
}
/**
* Set the ftp port.
*
* @param int|string $port
*
* @return $this
*/
public function setPort($port)
{
$this->port = (int) $port;
return $this;
}
/**
* Set the root folder to work from.
*
* @param string $root
*
* @return $this
*/
public function setRoot($root)
{
$this->root = rtrim($root, '\\/') . $this->separator;
return $this;
}
/**
* Returns the ftp username.
*
* @return string username
*/
public function getUsername()
{
$username = $this->safeStorage->retrieveSafely('username');
return $username !== null ? $username : 'anonymous';
}
/**
* Set ftp username.
*
* @param string $username
*
* @return $this
*/
public function setUsername($username)
{
$this->safeStorage->storeSafely('username', $username);
return $this;
}
/**
* Returns the password.
*
* @return string password
*/
public function getPassword()
{
return $this->safeStorage->retrieveSafely('password');
}
/**
* Set the ftp password.
*
* @param string $password
*
* @return $this
*/
public function setPassword($password)
{
$this->safeStorage->storeSafely('password', $password);
return $this;
}
/**
* Returns the amount of seconds before the connection will timeout.
*
* @return int
*/
public function getTimeout()
{
return $this->timeout;
}
/**
* Set the amount of seconds before the connection should timeout.
*
* @param int $timeout
*
* @return $this
*/
public function setTimeout($timeout)
{
$this->timeout = (int) $timeout;
return $this;
}
/**
* Return the FTP system type.
*
* @return string
*/
public function getSystemType()
{
return $this->systemType;
}
/**
* Set the FTP system type (windows or unix).
*
* @param string $systemType
*
* @return $this
*/
public function setSystemType($systemType)
{
$this->systemType = strtolower($systemType);
return $this;
}
/**
* True to enable timestamps for FTP servers that return unix-style listings.
*
* @param bool $bool
*
* @return $this
*/
public function setEnableTimestampsOnUnixListings($bool = false)
{
$this->enableTimestampsOnUnixListings = $bool;
return $this;
}
/**
* @inheritdoc
*/
public function listContents($directory = '', $recursive = false)
{
return $this->listDirectoryContents($directory, $recursive);
}
abstract protected function listDirectoryContents($directory, $recursive = false);
/**
* Normalize a directory listing.
*
* @param array $listing
* @param string $prefix
*
* @return array directory listing
*/
protected function normalizeListing(array $listing, $prefix = '')
{
$base = $prefix;
$result = [];
$listing = $this->removeDotDirectories($listing);
while ($item = array_shift($listing)) {
if (preg_match('#^.*:$#', $item)) {
$base = preg_replace('~^\./*|:$~', '', $item);
continue;
}
$result[] = $this->normalizeObject($item, $base);
}
return $this->sortListing($result);
}
/**
* Sort a directory listing.
*
* @param array $result
*
* @return array sorted listing
*/
protected function sortListing(array $result)
{
$compare = function ($one, $two) {
return strnatcmp($one['path'], $two['path']);
};
usort($result, $compare);
return $result;
}
/**
* Normalize a file entry.
*
* @param string $item
* @param string $base
*
* @return array normalized file array
*
* @throws NotSupportedException
*/
protected function normalizeObject($item, $base)
{
$systemType = $this->systemType ?: $this->detectSystemType($item);
if ($systemType === 'unix') {
return $this->normalizeUnixObject($item, $base);
} elseif ($systemType === 'windows') {
return $this->normalizeWindowsObject($item, $base);
}
throw NotSupportedException::forFtpSystemType($systemType);
}
/**
* Normalize a Unix file entry.
*
* Given $item contains:
* '-rw-r--r-- 1 ftp ftp 409 Aug 19 09:01 file1.txt'
*
* This function will return:
* [
* 'type' => 'file',
* 'path' => 'file1.txt',
* 'visibility' => 'public',
* 'size' => 409,
* 'timestamp' => 1566205260
* ]
*
* @param string $item
* @param string $base
*
* @return array normalized file array
*/
protected function normalizeUnixObject($item, $base)
{
$item = preg_replace('#\s+#', ' ', trim($item), 7);
if (count(explode(' ', $item, 9)) !== 9) {
throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts.");
}
list($permissions, /* $number */, /* $owner */, /* $group */, $size, $month, $day, $timeOrYear, $name) = explode(' ', $item, 9);
$type = $this->detectType($permissions);
$path = $base === '' ? $name : $base . $this->separator . $name;
if ($type === 'dir') {
$result = compact('type', 'path');
if ($this->enableTimestampsOnUnixListings) {
$timestamp = $this->normalizeUnixTimestamp($month, $day, $timeOrYear);
$result += compact('timestamp');
}
return $result;
}
$permissions = $this->normalizePermissions($permissions);
$visibility = $permissions & 0044 ? AdapterInterface::VISIBILITY_PUBLIC : AdapterInterface::VISIBILITY_PRIVATE;
$size = (int) $size;
$result = compact('type', 'path', 'visibility', 'size');
if ($this->enableTimestampsOnUnixListings) {
$timestamp = $this->normalizeUnixTimestamp($month, $day, $timeOrYear);
$result += compact('timestamp');
}
return $result;
}
/**
* Only accurate to the minute (current year), or to the day.
*
* Inadequacies in timestamp accuracy are due to limitations of the FTP 'LIST' command
*
* Note: The 'MLSD' command is a machine-readable replacement for 'LIST'
* but many FTP servers do not support it :(
*
* @param string $month e.g. 'Aug'
* @param string $day e.g. '19'
* @param string $timeOrYear e.g. '09:01' OR '2015'
*
* @return int
*/
protected function normalizeUnixTimestamp($month, $day, $timeOrYear)
{
if (is_numeric($timeOrYear)) {
$year = $timeOrYear;
$hour = '00';
$minute = '00';
$seconds = '00';
} else {
$year = date('Y');
list($hour, $minute) = explode(':', $timeOrYear);
$seconds = '00';
}
$dateTime = DateTime::createFromFormat('Y-M-j-G:i:s', "{$year}-{$month}-{$day}-{$hour}:{$minute}:{$seconds}");
return $dateTime->getTimestamp();
}
/**
* Normalize a Windows/DOS file entry.
*
* @param string $item
* @param string $base
*
* @return array normalized file array
*/
protected function normalizeWindowsObject($item, $base)
{
$item = preg_replace('#\s+#', ' ', trim($item), 3);
if (count(explode(' ', $item, 4)) !== 4) {
throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts.");
}
list($date, $time, $size, $name) = explode(' ', $item, 4);
$path = $base === '' ? $name : $base . $this->separator . $name;
// Check for the correct date/time format
$format = strlen($date) === 8 ? 'm-d-yH:iA' : 'Y-m-dH:i';
$dt = DateTime::createFromFormat($format, $date . $time);
$timestamp = $dt ? $dt->getTimestamp() : (int) strtotime("$date $time");
if ($size === '<DIR>') {
$type = 'dir';
return compact('type', 'path', 'timestamp');
}
$type = 'file';
$visibility = AdapterInterface::VISIBILITY_PUBLIC;
$size = (int) $size;
return compact('type', 'path', 'visibility', 'size', 'timestamp');
}
/**
* Get the system type from a listing item.
*
* @param string $item
*
* @return string the system type
*/
protected function detectSystemType($item)
{
return preg_match('/^[0-9]{2,4}-[0-9]{2}-[0-9]{2}/', trim($item)) ? 'windows' : 'unix';
}
/**
* Get the file type from the permissions.
*
* @param string $permissions
*
* @return string file type
*/
protected function detectType($permissions)
{
return substr($permissions, 0, 1) === 'd' ? 'dir' : 'file';
}
/**
* Normalize a permissions string.
*
* @param string $permissions
*
* @return int
*/
protected function normalizePermissions($permissions)
{
if (is_numeric($permissions)) {
return ((int) $permissions) & 0777;
}
// remove the type identifier
$permissions = substr($permissions, 1);
// map the string rights to the numeric counterparts
$map = ['-' => '0', 'r' => '4', 'w' => '2', 'x' => '1'];
$permissions = strtr($permissions, $map);
// split up the permission groups
$parts = str_split($permissions, 3);
// convert the groups
$mapper = function ($part) {
return array_sum(str_split($part));
};
// converts to decimal number
return octdec(implode('', array_map($mapper, $parts)));
}
/**
* Filter out dot-directories.
*
* @param array $list
*
* @return array
*/
public function removeDotDirectories(array $list)
{
$filter = function ($line) {
return $line !== '' && ! preg_match('#.* \.(\.)?$|^total#', $line);
};
return array_filter($list, $filter);
}
/**
* @inheritdoc
*/
public function has($path)
{
return $this->getMetadata($path);
}
/**
* @inheritdoc
*/
public function getSize($path)
{
return $this->getMetadata($path);
}
/**
* @inheritdoc
*/
public function getVisibility($path)
{
return $this->getMetadata($path);
}
/**
* Ensure a directory exists.
*
* @param string $dirname
*/
public function ensureDirectory($dirname)
{
$dirname = (string) $dirname;
if ($dirname !== '' && ! $this->has($dirname)) {
$this->createDir($dirname, new Config());
}
}
/**
* @return mixed
*/
public function getConnection()
{
if ( ! $this->isConnected()) {
$this->disconnect();
$this->connect();
}
return $this->connection;
}
/**
* Get the public permission value.
*
* @return int
*/
public function getPermPublic()
{
return $this->permPublic;
}
/**
* Get the private permission value.
*
* @return int
*/
public function getPermPrivate()
{
return $this->permPrivate;
}
/**
* Disconnect on destruction.
*/
public function __destruct()
{
$this->disconnect();
}
/**
* Establish a connection.
*/
abstract public function connect();
/**
* Close the connection.
*/
abstract public function disconnect();
/**
* Check if a connection is active.
*
* @return bool
*/
abstract public function isConnected();
protected function escapePath($path)
{
return str_replace(['*', '[', ']'], ['\\*', '\\[', '\\]'], $path);
}
}

View File

@ -1,12 +0,0 @@
<?php
namespace League\Flysystem\Adapter;
/**
* Adapters that implement this interface let the Filesystem know that files can be overwritten using the write
* functions and don't need the update function to be called. This can help improve performance when asserts are disabled.
*/
interface CanOverwriteFiles
{
}

View File

@ -1,584 +0,0 @@
<?php
namespace League\Flysystem\Adapter;
use League\Flysystem\Adapter\Polyfill\StreamedCopyTrait;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Config;
use League\Flysystem\ConnectionErrorException;
use League\Flysystem\ConnectionRuntimeException;
use League\Flysystem\InvalidRootException;
use League\Flysystem\Util;
use League\Flysystem\Util\MimeType;
use function in_array;
class Ftp extends AbstractFtpAdapter
{
use StreamedCopyTrait;
/**
* @var int
*/
protected $transferMode = FTP_BINARY;
/**
* @var null|bool
*/
protected $ignorePassiveAddress = null;
/**
* @var bool
*/
protected $recurseManually = false;
/**
* @var bool
*/
protected $utf8 = false;
/**
* @var array
*/
protected $configurable = [
'host',
'port',
'username',
'password',
'ssl',
'timeout',
'root',
'permPrivate',
'permPublic',
'passive',
'transferMode',
'systemType',
'ignorePassiveAddress',
'recurseManually',
'utf8',
'enableTimestampsOnUnixListings',
];
/**
* @var bool
*/
protected $isPureFtpd;
/**
* Set the transfer mode.
*
* @param int $mode
*
* @return $this
*/
public function setTransferMode($mode)
{
$this->transferMode = $mode;
return $this;
}
/**
* Set if Ssl is enabled.
*
* @param bool $ssl
*
* @return $this
*/
public function setSsl($ssl)
{
$this->ssl = (bool) $ssl;
return $this;
}
/**
* Set if passive mode should be used.
*
* @param bool $passive
*/
public function setPassive($passive = true)
{
$this->passive = $passive;
}
/**
* @param bool $ignorePassiveAddress
*/
public function setIgnorePassiveAddress($ignorePassiveAddress)
{
$this->ignorePassiveAddress = $ignorePassiveAddress;
}
/**
* @param bool $recurseManually
*/
public function setRecurseManually($recurseManually)
{
$this->recurseManually = $recurseManually;
}
/**
* @param bool $utf8
*/
public function setUtf8($utf8)
{
$this->utf8 = (bool) $utf8;
}
/**
* Connect to the FTP server.
*/
public function connect()
{
$tries = 3;
start_connecting:
if ($this->ssl) {
$this->connection = @ftp_ssl_connect($this->getHost(), $this->getPort(), $this->getTimeout());
} else {
$this->connection = @ftp_connect($this->getHost(), $this->getPort(), $this->getTimeout());
}
if ( ! $this->connection) {
$tries--;
if ($tries > 0) goto start_connecting;
throw new ConnectionRuntimeException('Could not connect to host: ' . $this->getHost() . ', port:' . $this->getPort());
}
$this->login();
$this->setUtf8Mode();
$this->setConnectionPassiveMode();
$this->setConnectionRoot();
$this->isPureFtpd = $this->isPureFtpdServer();
}
/**
* Set the connection to UTF-8 mode.
*/
protected function setUtf8Mode()
{
if ($this->utf8) {
$response = ftp_raw($this->connection, "OPTS UTF8 ON");
if (!in_array(substr($response[0], 0, 3), ['200', '202'])) {
throw new ConnectionRuntimeException(
'Could not set UTF-8 mode for connection: ' . $this->getHost() . '::' . $this->getPort()
);
}
}
}
/**
* Set the connections to passive mode.
*
* @throws ConnectionRuntimeException
*/
protected function setConnectionPassiveMode()
{
if (is_bool($this->ignorePassiveAddress) && defined('FTP_USEPASVADDRESS')) {
ftp_set_option($this->connection, FTP_USEPASVADDRESS, ! $this->ignorePassiveAddress);
}
if ( ! ftp_pasv($this->connection, $this->passive)) {
throw new ConnectionRuntimeException(
'Could not set passive mode for connection: ' . $this->getHost() . '::' . $this->getPort()
);
}
}
/**
* Set the connection root.
*/
protected function setConnectionRoot()
{
$root = $this->getRoot();
$connection = $this->connection;
if ($root && ! ftp_chdir($connection, $root)) {
throw new InvalidRootException('Root is invalid or does not exist: ' . $this->getRoot());
}
// Store absolute path for further reference.
// This is needed when creating directories and
// initial root was a relative path, else the root
// would be relative to the chdir'd path.
$this->root = ftp_pwd($connection);
}
/**
* Login.
*
* @throws ConnectionRuntimeException
*/
protected function login()
{
set_error_handler(function () {
});
$isLoggedIn = ftp_login(
$this->connection,
$this->getUsername(),
$this->getPassword()
);
restore_error_handler();
if ( ! $isLoggedIn) {
$this->disconnect();
throw new ConnectionRuntimeException(
'Could not login with connection: ' . $this->getHost() . '::' . $this->getPort(
) . ', username: ' . $this->getUsername()
);
}
}
/**
* Disconnect from the FTP server.
*/
public function disconnect()
{
if ($this->hasFtpConnection()) {
@ftp_close($this->connection);
}
$this->connection = null;
}
/**
* @inheritdoc
*/
public function write($path, $contents, Config $config)
{
$stream = fopen('php://temp', 'w+b');
fwrite($stream, $contents);
rewind($stream);
$result = $this->writeStream($path, $stream, $config);
fclose($stream);
if ($result === false) {
return false;
}
$result['contents'] = $contents;
$result['mimetype'] = $config->get('mimetype') ?: Util::guessMimeType($path, $contents);
return $result;
}
/**
* @inheritdoc
*/
public function writeStream($path, $resource, Config $config)
{
$this->ensureDirectory(Util::dirname($path));
if ( ! ftp_fput($this->getConnection(), $path, $resource, $this->transferMode)) {
return false;
}
if ($visibility = $config->get('visibility')) {
$this->setVisibility($path, $visibility);
}
$type = 'file';
return compact('type', 'path', 'visibility');
}
/**
* @inheritdoc
*/
public function update($path, $contents, Config $config)
{
return $this->write($path, $contents, $config);
}
/**
* @inheritdoc
*/
public function updateStream($path, $resource, Config $config)
{
return $this->writeStream($path, $resource, $config);
}
/**
* @inheritdoc
*/
public function rename($path, $newpath)
{
return ftp_rename($this->getConnection(), $path, $newpath);
}
/**
* @inheritdoc
*/
public function delete($path)
{
return ftp_delete($this->getConnection(), $path);
}
/**
* @inheritdoc
*/
public function deleteDir($dirname)
{
$connection = $this->getConnection();
$contents = array_reverse($this->listDirectoryContents($dirname, false));
foreach ($contents as $object) {
if ($object['type'] === 'file') {
if ( ! ftp_delete($connection, $object['path'])) {
return false;
}
} elseif ( ! $this->deleteDir($object['path'])) {
return false;
}
}
return ftp_rmdir($connection, $dirname);
}
/**
* @inheritdoc
*/
public function createDir($dirname, Config $config)
{
$connection = $this->getConnection();
$directories = explode('/', $dirname);
foreach ($directories as $directory) {
if (false === $this->createActualDirectory($directory, $connection)) {
$this->setConnectionRoot();
return false;
}
ftp_chdir($connection, $directory);
}
$this->setConnectionRoot();
return ['type' => 'dir', 'path' => $dirname];
}
/**
* Create a directory.
*
* @param string $directory
* @param resource $connection
*
* @return bool
*/
protected function createActualDirectory($directory, $connection)
{
// List the current directory
$listing = ftp_nlist($connection, '.') ?: [];
foreach ($listing as $key => $item) {
if (preg_match('~^\./.*~', $item)) {
$listing[$key] = substr($item, 2);
}
}
if (in_array($directory, $listing, true)) {
return true;
}
return (boolean) ftp_mkdir($connection, $directory);
}
/**
* @inheritdoc
*/
public function getMetadata($path)
{
if ($path === '') {
return ['type' => 'dir', 'path' => ''];
}
if (@ftp_chdir($this->getConnection(), $path) === true) {
$this->setConnectionRoot();
return ['type' => 'dir', 'path' => $path];
}
$listing = $this->ftpRawlist('-A', $path);
if (empty($listing) || in_array('total 0', $listing, true)) {
return false;
}
if (preg_match('/.* not found/', $listing[0])) {
return false;
}
if (preg_match('/^total [0-9]*$/', $listing[0])) {
array_shift($listing);
}
return $this->normalizeObject($listing[0], '');
}
/**
* @inheritdoc
*/
public function getMimetype($path)
{
if ( ! $metadata = $this->getMetadata($path)) {
return false;
}
$metadata['mimetype'] = MimeType::detectByFilename($path);
return $metadata;
}
/**
* @inheritdoc
*/
public function getTimestamp($path)
{
$timestamp = ftp_mdtm($this->getConnection(), $path);
return ($timestamp !== -1) ? ['path' => $path, 'timestamp' => $timestamp] : false;
}
/**
* @inheritdoc
*/
public function read($path)
{
if ( ! $object = $this->readStream($path)) {
return false;
}
$object['contents'] = stream_get_contents($object['stream']);
fclose($object['stream']);
unset($object['stream']);
return $object;
}
/**
* @inheritdoc
*/
public function readStream($path)
{
$stream = fopen('php://temp', 'w+b');
$result = ftp_fget($this->getConnection(), $stream, $path, $this->transferMode);
rewind($stream);
if ( ! $result) {
fclose($stream);
return false;
}
return ['type' => 'file', 'path' => $path, 'stream' => $stream];
}
/**
* @inheritdoc
*/
public function setVisibility($path, $visibility)
{
$mode = $visibility === AdapterInterface::VISIBILITY_PUBLIC ? $this->getPermPublic() : $this->getPermPrivate();
if ( ! ftp_chmod($this->getConnection(), $mode, $path)) {
return false;
}
return compact('path', 'visibility');
}
/**
* @inheritdoc
*
* @param string $directory
*/
protected function listDirectoryContents($directory, $recursive = true)
{
if ($recursive && $this->recurseManually) {
return $this->listDirectoryContentsRecursive($directory);
}
$options = $recursive ? '-alnR' : '-aln';
$listing = $this->ftpRawlist($options, $directory);
return $listing ? $this->normalizeListing($listing, $directory) : [];
}
/**
* @inheritdoc
*
* @param string $directory
*/
protected function listDirectoryContentsRecursive($directory)
{
$listing = $this->normalizeListing($this->ftpRawlist('-aln', $directory) ?: [], $directory);
$output = [];
foreach ($listing as $item) {
$output[] = $item;
if ($item['type'] !== 'dir') {
continue;
}
$output = array_merge($output, $this->listDirectoryContentsRecursive($item['path']));
}
return $output;
}
/**
* Check if the connection is open.
*
* @return bool
*
* @throws ConnectionErrorException
*/
public function isConnected()
{
return $this->hasFtpConnection() && $this->getRawExecResponseCode('NOOP') === 200;
}
/**
* @return bool
*/
protected function isPureFtpdServer()
{
$response = ftp_raw($this->connection, 'HELP');
return stripos(implode(' ', $response), 'Pure-FTPd') !== false;
}
/**
* The ftp_rawlist function with optional escaping.
*
* @param string $options
* @param string $path
*
* @return array
*/
protected function ftpRawlist($options, $path)
{
$connection = $this->getConnection();
if ($this->isPureFtpd) {
$path = str_replace([' ', '[', ']'], ['\ ', '\\[', '\\]'], $path);
}
return ftp_rawlist($connection, $options . ' ' . $this->escapePath($path));
}
private function getRawExecResponseCode($command)
{
$response = @ftp_raw($this->connection, trim($command));
return (int) preg_replace('/\D/', '', implode(' ', $response));
}
private function hasFtpConnection(): bool
{
return is_resource($this->connection) || $this->connection instanceof \FTP\Connection;
}
}

View File

@ -1,48 +0,0 @@
<?php
namespace League\Flysystem\Adapter;
class Ftpd extends Ftp
{
/**
* @inheritdoc
*/
public function getMetadata($path)
{
if ($path === '') {
return ['type' => 'dir', 'path' => ''];
}
if (@ftp_chdir($this->getConnection(), $path) === true) {
$this->setConnectionRoot();
return ['type' => 'dir', 'path' => $path];
}
$object = ftp_raw($this->getConnection(), 'STAT ' . $this->escapePath($path));
if ( ! $object || count($object) < 3) {
return false;
}
if (substr($object[1], 0, 5) === "ftpd:") {
return false;
}
return $this->normalizeObject($object[1], '');
}
/**
* @inheritdoc
*/
protected function listDirectoryContents($directory, $recursive = true)
{
$listing = ftp_rawlist($this->getConnection(), $this->escapePath($directory), $recursive);
if ($listing === false || ( ! empty($listing) && substr($listing[0], 0, 5) === "ftpd:")) {
return [];
}
return $this->normalizeListing($listing, $directory);
}
}

View File

@ -1,533 +0,0 @@
<?php
namespace League\Flysystem\Adapter;
use DirectoryIterator;
use FilesystemIterator;
use finfo as Finfo;
use League\Flysystem\Config;
use League\Flysystem\Exception;
use League\Flysystem\NotSupportedException;
use League\Flysystem\UnreadableFileException;
use League\Flysystem\Util;
use LogicException;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use SplFileInfo;
class Local extends AbstractAdapter
{
/**
* @var int
*/
const SKIP_LINKS = 0001;
/**
* @var int
*/
const DISALLOW_LINKS = 0002;
/**
* @var array
*/
protected static $permissions = [
'file' => [
'public' => 0644,
'private' => 0600,
],
'dir' => [
'public' => 0755,
'private' => 0700,
],
];
/**
* @var string
*/
protected $pathSeparator = DIRECTORY_SEPARATOR;
/**
* @var array
*/
protected $permissionMap;
/**
* @var int
*/
protected $writeFlags;
/**
* @var int
*/
private $linkHandling;
/**
* Constructor.
*
* @param string $root
* @param int $writeFlags
* @param int $linkHandling
* @param array $permissions
*
* @throws LogicException
*/
public function __construct($root, $writeFlags = LOCK_EX, $linkHandling = self::DISALLOW_LINKS, array $permissions = [])
{
$root = is_link($root) ? realpath($root) : $root;
$this->permissionMap = array_replace_recursive(static::$permissions, $permissions);
$this->ensureDirectory($root);
if ( ! is_dir($root) || ! is_readable($root)) {
throw new LogicException('The root path ' . $root . ' is not readable.');
}
$this->setPathPrefix($root);
$this->writeFlags = $writeFlags;
$this->linkHandling = $linkHandling;
}
/**
* Ensure the root directory exists.
*
* @param string $root root directory path
*
* @return void
*
* @throws Exception in case the root directory can not be created
*/
protected function ensureDirectory($root)
{
if ( ! is_dir($root)) {
$umask = umask(0);
if ( ! @mkdir($root, $this->permissionMap['dir']['public'], true)) {
$mkdirError = error_get_last();
}
umask($umask);
clearstatcache(false, $root);
if ( ! is_dir($root)) {
$errorMessage = isset($mkdirError['message']) ? $mkdirError['message'] : '';
throw new Exception(sprintf('Impossible to create the root directory "%s". %s', $root, $errorMessage));
}
}
}
/**
* @inheritdoc
*/
public function has($path)
{
$location = $this->applyPathPrefix($path);
return file_exists($location);
}
/**
* @inheritdoc
*/
public function write($path, $contents, Config $config)
{
$location = $this->applyPathPrefix($path);
$this->ensureDirectory(dirname($location));
if (($size = file_put_contents($location, $contents, $this->writeFlags)) === false) {
return false;
}
$type = 'file';
$result = compact('contents', 'type', 'size', 'path');
if ($visibility = $config->get('visibility')) {
$result['visibility'] = $visibility;
$this->setVisibility($path, $visibility);
}
return $result;
}
/**
* @inheritdoc
*/
public function writeStream($path, $resource, Config $config)
{
$location = $this->applyPathPrefix($path);
$this->ensureDirectory(dirname($location));
$stream = fopen($location, 'w+b');
if ( ! $stream || stream_copy_to_stream($resource, $stream) === false || ! fclose($stream)) {
return false;
}
$type = 'file';
$result = compact('type', 'path');
if ($visibility = $config->get('visibility')) {
$this->setVisibility($path, $visibility);
$result['visibility'] = $visibility;
}
return $result;
}
/**
* @inheritdoc
*/
public function readStream($path)
{
$location = $this->applyPathPrefix($path);
$stream = fopen($location, 'rb');
return ['type' => 'file', 'path' => $path, 'stream' => $stream];
}
/**
* @inheritdoc
*/
public function updateStream($path, $resource, Config $config)
{
return $this->writeStream($path, $resource, $config);
}
/**
* @inheritdoc
*/
public function update($path, $contents, Config $config)
{
$location = $this->applyPathPrefix($path);
$size = file_put_contents($location, $contents, $this->writeFlags);
if ($size === false) {
return false;
}
$type = 'file';
$result = compact('type', 'path', 'size', 'contents');
if ($visibility = $config->get('visibility')) {
$this->setVisibility($path, $visibility);
$result['visibility'] = $visibility;
}
return $result;
}
/**
* @inheritdoc
*/
public function read($path)
{
$location = $this->applyPathPrefix($path);
$contents = @file_get_contents($location);
if ($contents === false) {
return false;
}
return ['type' => 'file', 'path' => $path, 'contents' => $contents];
}
/**
* @inheritdoc
*/
public function rename($path, $newpath)
{
$location = $this->applyPathPrefix($path);
$destination = $this->applyPathPrefix($newpath);
$parentDirectory = $this->applyPathPrefix(Util::dirname($newpath));
$this->ensureDirectory($parentDirectory);
return rename($location, $destination);
}
/**
* @inheritdoc
*/
public function copy($path, $newpath)
{
$location = $this->applyPathPrefix($path);
$destination = $this->applyPathPrefix($newpath);
$this->ensureDirectory(dirname($destination));
return copy($location, $destination);
}
/**
* @inheritdoc
*/
public function delete($path)
{
$location = $this->applyPathPrefix($path);
return @unlink($location);
}
/**
* @inheritdoc
*/
public function listContents($directory = '', $recursive = false)
{
$result = [];
$location = $this->applyPathPrefix($directory);
if ( ! is_dir($location)) {
return [];
}
$iterator = $recursive ? $this->getRecursiveDirectoryIterator($location) : $this->getDirectoryIterator($location);
foreach ($iterator as $file) {
$path = $this->getFilePath($file);
if (preg_match('#(^|/|\\\\)\.{1,2}$#', $path)) {
continue;
}
$result[] = $this->normalizeFileInfo($file);
}
unset($iterator);
return array_filter($result);
}
/**
* @inheritdoc
*/
public function getMetadata($path)
{
$location = $this->applyPathPrefix($path);
clearstatcache(false, $location);
$info = new SplFileInfo($location);
return $this->normalizeFileInfo($info);
}
/**
* @inheritdoc
*/
public function getSize($path)
{
return $this->getMetadata($path);
}
/**
* @inheritdoc
*/
public function getMimetype($path)
{
$location = $this->applyPathPrefix($path);
$finfo = new Finfo(FILEINFO_MIME_TYPE);
$mimetype = $finfo->file($location);
if (in_array($mimetype, ['application/octet-stream', 'inode/x-empty', 'application/x-empty'])) {
$mimetype = Util\MimeType::detectByFilename($location);
}
return ['path' => $path, 'type' => 'file', 'mimetype' => $mimetype];
}
/**
* @inheritdoc
*/
public function getTimestamp($path)
{
return $this->getMetadata($path);
}
/**
* @inheritdoc
*/
public function getVisibility($path)
{
$location = $this->applyPathPrefix($path);
clearstatcache(false, $location);
$permissions = octdec(substr(sprintf('%o', fileperms($location)), -4));
$type = is_dir($location) ? 'dir' : 'file';
foreach ($this->permissionMap[$type] as $visibility => $visibilityPermissions) {
if ($visibilityPermissions == $permissions) {
return compact('path', 'visibility');
}
}
$visibility = substr(sprintf('%o', fileperms($location)), -4);
return compact('path', 'visibility');
}
/**
* @inheritdoc
*/
public function setVisibility($path, $visibility)
{
$location = $this->applyPathPrefix($path);
$type = is_dir($location) ? 'dir' : 'file';
$success = chmod($location, $this->permissionMap[$type][$visibility]);
if ($success === false) {
return false;
}
return compact('path', 'visibility');
}
/**
* @inheritdoc
*/
public function createDir($dirname, Config $config)
{
$location = $this->applyPathPrefix($dirname);
$umask = umask(0);
$visibility = $config->get('visibility', 'public');
$return = ['path' => $dirname, 'type' => 'dir'];
if ( ! is_dir($location)) {
if (false === @mkdir($location, $this->permissionMap['dir'][$visibility], true)
|| false === is_dir($location)) {
$return = false;
}
}
umask($umask);
return $return;
}
/**
* @inheritdoc
*/
public function deleteDir($dirname)
{
$location = $this->applyPathPrefix($dirname);
if ( ! is_dir($location)) {
return false;
}
$contents = $this->getRecursiveDirectoryIterator($location, RecursiveIteratorIterator::CHILD_FIRST);
/** @var SplFileInfo $file */
foreach ($contents as $file) {
$this->guardAgainstUnreadableFileInfo($file);
$this->deleteFileInfoObject($file);
}
unset($contents);
return rmdir($location);
}
/**
* @param SplFileInfo $file
*/
protected function deleteFileInfoObject(SplFileInfo $file)
{
switch ($file->getType()) {
case 'dir':
rmdir($file->getRealPath());
break;
case 'link':
unlink($file->getPathname());
break;
default:
unlink($file->getRealPath());
}
}
/**
* Normalize the file info.
*
* @param SplFileInfo $file
*
* @return array|void
*
* @throws NotSupportedException
*/
protected function normalizeFileInfo(SplFileInfo $file)
{
if ( ! $file->isLink()) {
return $this->mapFileInfo($file);
}
if ($this->linkHandling & self::DISALLOW_LINKS) {
throw NotSupportedException::forLink($file);
}
}
/**
* Get the normalized path from a SplFileInfo object.
*
* @param SplFileInfo $file
*
* @return string
*/
protected function getFilePath(SplFileInfo $file)
{
$location = $file->getPathname();
$path = $this->removePathPrefix($location);
return trim(str_replace('\\', '/', $path), '/');
}
/**
* @param string $path
* @param int $mode
*
* @return RecursiveIteratorIterator
*/
protected function getRecursiveDirectoryIterator($path, $mode = RecursiveIteratorIterator::SELF_FIRST)
{
return new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
$mode
);
}
/**
* @param string $path
*
* @return DirectoryIterator
*/
protected function getDirectoryIterator($path)
{
$iterator = new DirectoryIterator($path);
return $iterator;
}
/**
* @param SplFileInfo $file
*
* @return array
*/
protected function mapFileInfo(SplFileInfo $file)
{
$normalized = [
'type' => $file->getType(),
'path' => $this->getFilePath($file),
];
$normalized['timestamp'] = $file->getMTime();
if ($normalized['type'] === 'file') {
$normalized['size'] = $file->getSize();
}
return $normalized;
}
/**
* @param SplFileInfo $file
*
* @throws UnreadableFileException
*/
protected function guardAgainstUnreadableFileInfo(SplFileInfo $file)
{
if ( ! $file->isReadable()) {
throw UnreadableFileException::forFileInfo($file);
}
}
}

View File

@ -1,144 +0,0 @@
<?php
namespace League\Flysystem\Adapter;
use League\Flysystem\Adapter\Polyfill\StreamedCopyTrait;
use League\Flysystem\Adapter\Polyfill\StreamedTrait;
use League\Flysystem\Config;
class NullAdapter extends AbstractAdapter
{
use StreamedTrait;
use StreamedCopyTrait;
/**
* Check whether a file is present.
*
* @param string $path
*
* @return bool
*/
public function has($path)
{
return false;
}
/**
* @inheritdoc
*/
public function write($path, $contents, Config $config)
{
$type = 'file';
$result = compact('contents', 'type', 'path');
if ($visibility = $config->get('visibility')) {
$result['visibility'] = $visibility;
}
return $result;
}
/**
* @inheritdoc
*/
public function update($path, $contents, Config $config)
{
return false;
}
/**
* @inheritdoc
*/
public function read($path)
{
return false;
}
/**
* @inheritdoc
*/
public function rename($path, $newpath)
{
return false;
}
/**
* @inheritdoc
*/
public function delete($path)
{
return false;
}
/**
* @inheritdoc
*/
public function listContents($directory = '', $recursive = false)
{
return [];
}
/**
* @inheritdoc
*/
public function getMetadata($path)
{
return false;
}
/**
* @inheritdoc
*/
public function getSize($path)
{
return false;
}
/**
* @inheritdoc
*/
public function getMimetype($path)
{
return false;
}
/**
* @inheritdoc
*/
public function getTimestamp($path)
{
return false;
}
/**
* @inheritdoc
*/
public function getVisibility($path)
{
return false;
}
/**
* @inheritdoc
*/
public function setVisibility($path, $visibility)
{
return compact('visibility');
}
/**
* @inheritdoc
*/
public function createDir($dirname, Config $config)
{
return ['path' => $dirname, 'type' => 'dir'];
}
/**
* @inheritdoc
*/
public function deleteDir($dirname)
{
return false;
}
}

View File

@ -1,33 +0,0 @@
<?php
namespace League\Flysystem\Adapter\Polyfill;
use LogicException;
trait NotSupportingVisibilityTrait
{
/**
* Get the visibility of a file.
*
* @param string $path
*
* @throws LogicException
*/
public function getVisibility($path)
{
throw new LogicException(get_class($this) . ' does not support visibility. Path: ' . $path);
}
/**
* Set the visibility for a file.
*
* @param string $path
* @param string $visibility
*
* @throws LogicException
*/
public function setVisibility($path, $visibility)
{
throw new LogicException(get_class($this) . ' does not support visibility. Path: ' . $path . ', visibility: ' . $visibility);
}
}

View File

@ -1,51 +0,0 @@
<?php
namespace League\Flysystem\Adapter\Polyfill;
use League\Flysystem\Config;
trait StreamedCopyTrait
{
/**
* Copy a file.
*
* @param string $path
* @param string $newpath
*
* @return bool
*/
public function copy($path, $newpath)
{
$response = $this->readStream($path);
if ($response === false || ! is_resource($response['stream'])) {
return false;
}
$result = $this->writeStream($newpath, $response['stream'], new Config());
if ($result !== false && is_resource($response['stream'])) {
fclose($response['stream']);
}
return $result !== false;
}
// Required abstract method
/**
* @param string $path
*
* @return resource
*/
abstract public function readStream($path);
/**
* @param string $path
* @param resource $resource
* @param Config $config
*
* @return resource
*/
abstract public function writeStream($path, $resource, Config $config);
}

View File

@ -1,44 +0,0 @@
<?php
namespace League\Flysystem\Adapter\Polyfill;
/**
* A helper for adapters that only handle strings to provide read streams.
*/
trait StreamedReadingTrait
{
/**
* Reads a file as a stream.
*
* @param string $path
*
* @return array|false
*
* @see League\Flysystem\ReadInterface::readStream()
*/
public function readStream($path)
{
if ( ! $data = $this->read($path)) {
return false;
}
$stream = fopen('php://temp', 'w+b');
fwrite($stream, $data['contents']);
rewind($stream);
$data['stream'] = $stream;
unset($data['contents']);
return $data;
}
/**
* Reads a file.
*
* @param string $path
*
* @return array|false
*
* @see League\Flysystem\ReadInterface::read()
*/
abstract public function read($path);
}

View File

@ -1,9 +0,0 @@
<?php
namespace League\Flysystem\Adapter\Polyfill;
trait StreamedTrait
{
use StreamedReadingTrait;
use StreamedWritingTrait;
}

View File

@ -1,60 +0,0 @@
<?php
namespace League\Flysystem\Adapter\Polyfill;
use League\Flysystem\Config;
use League\Flysystem\Util;
trait StreamedWritingTrait
{
/**
* Stream fallback delegator.
*
* @param string $path
* @param resource $resource
* @param Config $config
* @param string $fallback
*
* @return mixed fallback result
*/
protected function stream($path, $resource, Config $config, $fallback)
{
Util::rewindStream($resource);
$contents = stream_get_contents($resource);
$fallbackCall = [$this, $fallback];
return call_user_func($fallbackCall, $path, $contents, $config);
}
/**
* Write using a stream.
*
* @param string $path
* @param resource $resource
* @param Config $config
*
* @return mixed false or file metadata
*/
public function writeStream($path, $resource, Config $config)
{
return $this->stream($path, $resource, $config, 'write');
}
/**
* Update a file using a stream.
*
* @param string $path
* @param resource $resource
* @param Config $config Config object or visibility setting
*
* @return mixed false of file metadata
*/
public function updateStream($path, $resource, Config $config)
{
return $this->stream($path, $resource, $config, 'update');
}
// Required abstract methods
abstract public function write($pash, $contents, Config $config);
abstract public function update($pash, $contents, Config $config);
}

View File

@ -1,8 +0,0 @@
<?php
namespace League\Flysystem\Adapter;
class SynologyFtp extends Ftpd
{
// This class merely exists because of BC.
}

View File

@ -1,118 +0,0 @@
<?php
namespace League\Flysystem;
interface AdapterInterface extends ReadInterface
{
/**
* @const VISIBILITY_PUBLIC public visibility
*/
const VISIBILITY_PUBLIC = 'public';
/**
* @const VISIBILITY_PRIVATE private visibility
*/
const VISIBILITY_PRIVATE = 'private';
/**
* Write a new file.
*
* @param string $path
* @param string $contents
* @param Config $config Config object
*
* @return array|false false on failure file meta data on success
*/
public function write($path, $contents, Config $config);
/**
* Write a new file using a stream.
*
* @param string $path
* @param resource $resource
* @param Config $config Config object
*
* @return array|false false on failure file meta data on success
*/
public function writeStream($path, $resource, Config $config);
/**
* Update a file.
*
* @param string $path
* @param string $contents
* @param Config $config Config object
*
* @return array|false false on failure file meta data on success
*/
public function update($path, $contents, Config $config);
/**
* Update a file using a stream.
*
* @param string $path
* @param resource $resource
* @param Config $config Config object
*
* @return array|false false on failure file meta data on success
*/
public function updateStream($path, $resource, Config $config);
/**
* Rename a file.
*
* @param string $path
* @param string $newpath
*
* @return bool
*/
public function rename($path, $newpath);
/**
* Copy a file.
*
* @param string $path
* @param string $newpath
*
* @return bool
*/
public function copy($path, $newpath);
/**
* Delete a file.
*
* @param string $path
*
* @return bool
*/
public function delete($path);
/**
* Delete a directory.
*
* @param string $dirname
*
* @return bool
*/
public function deleteDir($dirname);
/**
* Create a directory.
*
* @param string $dirname directory name
* @param Config $config
*
* @return array|false
*/
public function createDir($dirname, Config $config);
/**
* Set the visibility for a file.
*
* @param string $path
* @param string $visibility
*
* @return array|false file meta data
*/
public function setVisibility($path, $visibility);
}

View File

@ -1,107 +0,0 @@
<?php
namespace League\Flysystem;
class Config
{
/**
* @var array
*/
protected $settings = [];
/**
* @var Config|null
*/
protected $fallback;
/**
* Constructor.
*
* @param array $settings
*/
public function __construct(array $settings = [])
{
$this->settings = $settings;
}
/**
* Get a setting.
*
* @param string $key
* @param mixed $default
*
* @return mixed config setting or default when not found
*/
public function get($key, $default = null)
{
if ( ! array_key_exists($key, $this->settings)) {
return $this->getDefault($key, $default);
}
return $this->settings[$key];
}
/**
* Check if an item exists by key.
*
* @param string $key
*
* @return bool
*/
public function has($key)
{
if (array_key_exists($key, $this->settings)) {
return true;
}
return $this->fallback instanceof Config
? $this->fallback->has($key)
: false;
}
/**
* Try to retrieve a default setting from a config fallback.
*
* @param string $key
* @param mixed $default
*
* @return mixed config setting or default when not found
*/
protected function getDefault($key, $default)
{
if ( ! $this->fallback) {
return $default;
}
return $this->fallback->get($key, $default);
}
/**
* Set a setting.
*
* @param string $key
* @param mixed $value
*
* @return $this
*/
public function set($key, $value)
{
$this->settings[$key] = $value;
return $this;
}
/**
* Set the fallback.
*
* @param Config $fallback
*
* @return $this
*/
public function setFallback(Config $fallback)
{
$this->fallback = $fallback;
return $this;
}
}

View File

@ -1,49 +0,0 @@
<?php
namespace League\Flysystem;
/**
* @internal
*/
trait ConfigAwareTrait
{
/**
* @var Config
*/
protected $config;
/**
* Set the config.
*
* @param Config|array|null $config
*/
protected function setConfig($config)
{
$this->config = $config ? Util::ensureConfig($config) : new Config;
}
/**
* Get the Config.
*
* @return Config config object
*/
public function getConfig()
{
return $this->config;
}
/**
* Convert a config array to a Config object with the correct fallback.
*
* @param array $config
*
* @return Config
*/
protected function prepareConfig(array $config)
{
$config = new Config($config);
$config->setFallback($this->getConfig());
return $config;
}
}

View File

@ -1,9 +0,0 @@
<?php
namespace League\Flysystem;
use ErrorException;
class ConnectionErrorException extends ErrorException implements FilesystemException
{
}

View File

@ -1,9 +0,0 @@
<?php
namespace League\Flysystem;
use RuntimeException;
class ConnectionRuntimeException extends RuntimeException implements FilesystemException
{
}

View File

@ -1,17 +0,0 @@
<?php
namespace League\Flysystem;
use LogicException;
class CorruptedPathDetected extends LogicException implements FilesystemException
{
/**
* @param string $path
* @return CorruptedPathDetected
*/
public static function forPath($path)
{
return new CorruptedPathDetected("Corrupted path detected: " . $path);
}
}

View File

@ -1,31 +0,0 @@
<?php
namespace League\Flysystem;
/**
* @deprecated
*/
class Directory extends Handler
{
/**
* Delete the directory.
*
* @return bool
*/
public function delete()
{
return $this->filesystem->deleteDir($this->path);
}
/**
* List the directory contents.
*
* @param bool $recursive
*
* @return array|bool directory contents or false
*/
public function getContents($recursive = false)
{
return $this->filesystem->listContents($this->path, $recursive);
}
}

View File

@ -1,8 +0,0 @@
<?php
namespace League\Flysystem;
class Exception extends \Exception implements FilesystemException
{
//
}

View File

@ -1,205 +0,0 @@
<?php
namespace League\Flysystem;
/**
* @deprecated
*/
class File extends Handler
{
/**
* Check whether the file exists.
*
* @return bool
*/
public function exists()
{
return $this->filesystem->has($this->path);
}
/**
* Read the file.
*
* @return string|false file contents
*/
public function read()
{
return $this->filesystem->read($this->path);
}
/**
* Read the file as a stream.
*
* @return resource|false file stream
*/
public function readStream()
{
return $this->filesystem->readStream($this->path);
}
/**
* Write the new file.
*
* @param string $content
*
* @return bool success boolean
*/
public function write($content)
{
return $this->filesystem->write($this->path, $content);
}
/**
* Write the new file using a stream.
*
* @param resource $resource
*
* @return bool success boolean
*/
public function writeStream($resource)
{
return $this->filesystem->writeStream($this->path, $resource);
}
/**
* Update the file contents.
*
* @param string $content
*
* @return bool success boolean
*/
public function update($content)
{
return $this->filesystem->update($this->path, $content);
}
/**
* Update the file contents with a stream.
*
* @param resource $resource
*
* @return bool success boolean
*/
public function updateStream($resource)
{
return $this->filesystem->updateStream($this->path, $resource);
}
/**
* Create the file or update if exists.
*
* @param string $content
*
* @return bool success boolean
*/
public function put($content)
{
return $this->filesystem->put($this->path, $content);
}
/**
* Create the file or update if exists using a stream.
*
* @param resource $resource
*
* @return bool success boolean
*/
public function putStream($resource)
{
return $this->filesystem->putStream($this->path, $resource);
}
/**
* Rename the file.
*
* @param string $newpath
*
* @return bool success boolean
*/
public function rename($newpath)
{
if ($this->filesystem->rename($this->path, $newpath)) {
$this->path = $newpath;
return true;
}
return false;
}
/**
* Copy the file.
*
* @param string $newpath
*
* @return File|false new file or false
*/
public function copy($newpath)
{
if ($this->filesystem->copy($this->path, $newpath)) {
return new File($this->filesystem, $newpath);
}
return false;
}
/**
* Get the file's timestamp.
*
* @return string|false The timestamp or false on failure.
*/
public function getTimestamp()
{
return $this->filesystem->getTimestamp($this->path);
}
/**
* Get the file's mimetype.
*
* @return string|false The file mime-type or false on failure.
*/
public function getMimetype()
{
return $this->filesystem->getMimetype($this->path);
}
/**
* Get the file's visibility.
*
* @return string|false The visibility (public|private) or false on failure.
*/
public function getVisibility()
{
return $this->filesystem->getVisibility($this->path);
}
/**
* Get the file's metadata.
*
* @return array|false The file metadata or false on failure.
*/
public function getMetadata()
{
return $this->filesystem->getMetadata($this->path);
}
/**
* Get the file size.
*
* @return int|false The file size or false on failure.
*/
public function getSize()
{
return $this->filesystem->getSize($this->path);
}
/**
* Delete the file.
*
* @return bool success boolean
*/
public function delete()
{
return $this->filesystem->delete($this->path);
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace League\Flysystem;
use Exception as BaseException;
class FileExistsException extends Exception
{
/**
* @var string
*/
protected $path;
/**
* Constructor.
*
* @param string $path
* @param int $code
* @param BaseException $previous
*/
public function __construct($path, $code = 0, BaseException $previous = null)
{
$this->path = $path;
parent::__construct('File already exists at path: ' . $this->getPath(), $code, $previous);
}
/**
* Get the path which was found.
*
* @return string
*/
public function getPath()
{
return $this->path;
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace League\Flysystem;
use Exception as BaseException;
class FileNotFoundException extends Exception
{
/**
* @var string
*/
protected $path;
/**
* Constructor.
*
* @param string $path
* @param int $code
* @param \Exception $previous
*/
public function __construct($path, $code = 0, BaseException $previous = null)
{
$this->path = $path;
parent::__construct('File not found at path: ' . $this->getPath(), $code, $previous);
}
/**
* Get the path which was not found.
*
* @return string
*/
public function getPath()
{
return $this->path;
}
}

View File

@ -1,409 +0,0 @@
<?php
namespace League\Flysystem;
use InvalidArgumentException;
use League\Flysystem\Adapter\CanOverwriteFiles;
use League\Flysystem\Plugin\PluggableTrait;
use League\Flysystem\Util\ContentListingFormatter;
/**
* @method void emptyDir(string $dirname)
* @method array|false getWithMetadata(string $path, string[] $metadata)
* @method bool forceCopy(string $path, string $newpath)
* @method bool forceRename(string $path, string $newpath)
* @method array listFiles(string $path = '', boolean $recursive = false)
* @method string[] listPaths(string $path = '', boolean $recursive = false)
* @method array listWith(string[] $keys = [], $directory = '', $recursive = false)
*/
class Filesystem implements FilesystemInterface
{
use PluggableTrait;
use ConfigAwareTrait;
/**
* @var AdapterInterface
*/
protected $adapter;
/**
* Constructor.
*
* @param AdapterInterface $adapter
* @param Config|array $config
*/
public function __construct(AdapterInterface $adapter, $config = null)
{
$this->adapter = $adapter;
$this->setConfig($config);
}
/**
* Get the Adapter.
*
* @return AdapterInterface adapter
*/
public function getAdapter()
{
return $this->adapter;
}
/**
* @inheritdoc
*/
public function has($path)
{
$path = Util::normalizePath($path);
return strlen($path) === 0 ? false : (bool) $this->getAdapter()->has($path);
}
/**
* @inheritdoc
*/
public function write($path, $contents, array $config = [])
{
$path = Util::normalizePath($path);
$this->assertAbsent($path);
$config = $this->prepareConfig($config);
return (bool) $this->getAdapter()->write($path, $contents, $config);
}
/**
* @inheritdoc
*/
public function writeStream($path, $resource, array $config = [])
{
if ( ! is_resource($resource) || get_resource_type($resource) !== 'stream') {
throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.');
}
$path = Util::normalizePath($path);
$this->assertAbsent($path);
$config = $this->prepareConfig($config);
Util::rewindStream($resource);
return (bool) $this->getAdapter()->writeStream($path, $resource, $config);
}
/**
* @inheritdoc
*/
public function put($path, $contents, array $config = [])
{
$path = Util::normalizePath($path);
$config = $this->prepareConfig($config);
if ( ! $this->getAdapter() instanceof CanOverwriteFiles && $this->has($path)) {
return (bool) $this->getAdapter()->update($path, $contents, $config);
}
return (bool) $this->getAdapter()->write($path, $contents, $config);
}
/**
* @inheritdoc
*/
public function putStream($path, $resource, array $config = [])
{
if ( ! is_resource($resource) || get_resource_type($resource) !== 'stream') {
throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.');
}
$path = Util::normalizePath($path);
$config = $this->prepareConfig($config);
Util::rewindStream($resource);
if ( ! $this->getAdapter() instanceof CanOverwriteFiles && $this->has($path)) {
return (bool) $this->getAdapter()->updateStream($path, $resource, $config);
}
return (bool) $this->getAdapter()->writeStream($path, $resource, $config);
}
/**
* @inheritdoc
*/
public function readAndDelete($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
$contents = $this->read($path);
if ($contents === false) {
return false;
}
$this->delete($path);
return $contents;
}
/**
* @inheritdoc
*/
public function update($path, $contents, array $config = [])
{
$path = Util::normalizePath($path);
$config = $this->prepareConfig($config);
$this->assertPresent($path);
return (bool) $this->getAdapter()->update($path, $contents, $config);
}
/**
* @inheritdoc
*/
public function updateStream($path, $resource, array $config = [])
{
if ( ! is_resource($resource) || get_resource_type($resource) !== 'stream') {
throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.');
}
$path = Util::normalizePath($path);
$config = $this->prepareConfig($config);
$this->assertPresent($path);
Util::rewindStream($resource);
return (bool) $this->getAdapter()->updateStream($path, $resource, $config);
}
/**
* @inheritdoc
*/
public function read($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
if ( ! ($object = $this->getAdapter()->read($path))) {
return false;
}
return $object['contents'];
}
/**
* @inheritdoc
*/
public function readStream($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
if ( ! $object = $this->getAdapter()->readStream($path)) {
return false;
}
return $object['stream'];
}
/**
* @inheritdoc
*/
public function rename($path, $newpath)
{
$path = Util::normalizePath($path);
$newpath = Util::normalizePath($newpath);
$this->assertPresent($path);
$this->assertAbsent($newpath);
return (bool) $this->getAdapter()->rename($path, $newpath);
}
/**
* @inheritdoc
*/
public function copy($path, $newpath)
{
$path = Util::normalizePath($path);
$newpath = Util::normalizePath($newpath);
$this->assertPresent($path);
$this->assertAbsent($newpath);
return $this->getAdapter()->copy($path, $newpath);
}
/**
* @inheritdoc
*/
public function delete($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
return $this->getAdapter()->delete($path);
}
/**
* @inheritdoc
*/
public function deleteDir($dirname)
{
$dirname = Util::normalizePath($dirname);
if ($dirname === '') {
throw new RootViolationException('Root directories can not be deleted.');
}
return (bool) $this->getAdapter()->deleteDir($dirname);
}
/**
* @inheritdoc
*/
public function createDir($dirname, array $config = [])
{
$dirname = Util::normalizePath($dirname);
$config = $this->prepareConfig($config);
return (bool) $this->getAdapter()->createDir($dirname, $config);
}
/**
* @inheritdoc
*/
public function listContents($directory = '', $recursive = false)
{
$directory = Util::normalizePath($directory);
$contents = $this->getAdapter()->listContents($directory, $recursive);
return (new ContentListingFormatter($directory, $recursive, $this->config->get('case_sensitive', true)))
->formatListing($contents);
}
/**
* @inheritdoc
*/
public function getMimetype($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
if (( ! $object = $this->getAdapter()->getMimetype($path)) || ! array_key_exists('mimetype', $object)) {
return false;
}
return $object['mimetype'];
}
/**
* @inheritdoc
*/
public function getTimestamp($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
if (( ! $object = $this->getAdapter()->getTimestamp($path)) || ! array_key_exists('timestamp', $object)) {
return false;
}
return (int) $object['timestamp'];
}
/**
* @inheritdoc
*/
public function getVisibility($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
if (( ! $object = $this->getAdapter()->getVisibility($path)) || ! array_key_exists('visibility', $object)) {
return false;
}
return $object['visibility'];
}
/**
* @inheritdoc
*/
public function getSize($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
if (( ! $object = $this->getAdapter()->getSize($path)) || ! array_key_exists('size', $object)) {
return false;
}
return (int) $object['size'];
}
/**
* @inheritdoc
*/
public function setVisibility($path, $visibility)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
return (bool) $this->getAdapter()->setVisibility($path, $visibility);
}
/**
* @inheritdoc
*/
public function getMetadata($path)
{
$path = Util::normalizePath($path);
$this->assertPresent($path);
return $this->getAdapter()->getMetadata($path);
}
/**
* @inheritdoc
*/
public function get($path, Handler $handler = null)
{
$path = Util::normalizePath($path);
if ( ! $handler) {
$metadata = $this->getMetadata($path);
$handler = ($metadata && $metadata['type'] === 'file') ? new File($this, $path) : new Directory($this, $path);
}
$handler->setPath($path);
$handler->setFilesystem($this);
return $handler;
}
/**
* Assert a file is present.
*
* @param string $path path to file
*
* @throws FileNotFoundException
*
* @return void
*/
public function assertPresent($path)
{
if ($this->config->get('disable_asserts', false) === false && ! $this->has($path)) {
throw new FileNotFoundException($path);
}
}
/**
* Assert a file is absent.
*
* @param string $path path to file
*
* @throws FileExistsException
*
* @return void
*/
public function assertAbsent($path)
{
if ($this->config->get('disable_asserts', false) === false && $this->has($path)) {
throw new FileExistsException($path);
}
}
}

View File

@ -1,7 +0,0 @@
<?php
namespace League\Flysystem;
interface FilesystemException
{
}

View File

@ -1,284 +0,0 @@
<?php
namespace League\Flysystem;
use InvalidArgumentException;
interface FilesystemInterface
{
/**
* Check whether a file exists.
*
* @param string $path
*
* @return bool
*/
public function has($path);
/**
* Read a file.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return string|false The file contents or false on failure.
*/
public function read($path);
/**
* Retrieves a read-stream for a path.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return resource|false The path resource or false on failure.
*/
public function readStream($path);
/**
* List contents of a directory.
*
* @param string $directory The directory to list.
* @param bool $recursive Whether to list recursively.
*
* @return array A list of file metadata.
*/
public function listContents($directory = '', $recursive = false);
/**
* Get a file's metadata.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return array|false The file metadata or false on failure.
*/
public function getMetadata($path);
/**
* Get a file's size.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return int|false The file size or false on failure.
*/
public function getSize($path);
/**
* Get a file's mime-type.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return string|false The file mime-type or false on failure.
*/
public function getMimetype($path);
/**
* Get a file's timestamp.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return int|false The timestamp or false on failure.
*/
public function getTimestamp($path);
/**
* Get a file's visibility.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return string|false The visibility (public|private) or false on failure.
*/
public function getVisibility($path);
/**
* Write a new file.
*
* @param string $path The path of the new file.
* @param string $contents The file contents.
* @param array $config An optional configuration array.
*
* @throws FileExistsException
*
* @return bool True on success, false on failure.
*/
public function write($path, $contents, array $config = []);
/**
* Write a new file using a stream.
*
* @param string $path The path of the new file.
* @param resource $resource The file handle.
* @param array $config An optional configuration array.
*
* @throws InvalidArgumentException If $resource is not a file handle.
* @throws FileExistsException
*
* @return bool True on success, false on failure.
*/
public function writeStream($path, $resource, array $config = []);
/**
* Update an existing file.
*
* @param string $path The path of the existing file.
* @param string $contents The file contents.
* @param array $config An optional configuration array.
*
* @throws FileNotFoundException
*
* @return bool True on success, false on failure.
*/
public function update($path, $contents, array $config = []);
/**
* Update an existing file using a stream.
*
* @param string $path The path of the existing file.
* @param resource $resource The file handle.
* @param array $config An optional configuration array.
*
* @throws InvalidArgumentException If $resource is not a file handle.
* @throws FileNotFoundException
*
* @return bool True on success, false on failure.
*/
public function updateStream($path, $resource, array $config = []);
/**
* Rename a file.
*
* @param string $path Path to the existing file.
* @param string $newpath The new path of the file.
*
* @throws FileExistsException Thrown if $newpath exists.
* @throws FileNotFoundException Thrown if $path does not exist.
*
* @return bool True on success, false on failure.
*/
public function rename($path, $newpath);
/**
* Copy a file.
*
* @param string $path Path to the existing file.
* @param string $newpath The new path of the file.
*
* @throws FileExistsException Thrown if $newpath exists.
* @throws FileNotFoundException Thrown if $path does not exist.
*
* @return bool True on success, false on failure.
*/
public function copy($path, $newpath);
/**
* Delete a file.
*
* @param string $path
*
* @throws FileNotFoundException
*
* @return bool True on success, false on failure.
*/
public function delete($path);
/**
* Delete a directory.
*
* @param string $dirname
*
* @throws RootViolationException Thrown if $dirname is empty.
*
* @return bool True on success, false on failure.
*/
public function deleteDir($dirname);
/**
* Create a directory.
*
* @param string $dirname The name of the new directory.
* @param array $config An optional configuration array.
*
* @return bool True on success, false on failure.
*/
public function createDir($dirname, array $config = []);
/**
* Set the visibility for a file.
*
* @param string $path The path to the file.
* @param string $visibility One of 'public' or 'private'.
*
* @throws FileNotFoundException
*
* @return bool True on success, false on failure.
*/
public function setVisibility($path, $visibility);
/**
* Create a file or update if exists.
*
* @param string $path The path to the file.
* @param string $contents The file contents.
* @param array $config An optional configuration array.
*
* @return bool True on success, false on failure.
*/
public function put($path, $contents, array $config = []);
/**
* Create a file or update if exists.
*
* @param string $path The path to the file.
* @param resource $resource The file handle.
* @param array $config An optional configuration array.
*
* @throws InvalidArgumentException Thrown if $resource is not a resource.
*
* @return bool True on success, false on failure.
*/
public function putStream($path, $resource, array $config = []);
/**
* Read and delete a file.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return string|false The file contents, or false on failure.
*/
public function readAndDelete($path);
/**
* Get a file/directory handler.
*
* @deprecated
*
* @param string $path The path to the file.
* @param Handler $handler An optional existing handler to populate.
*
* @return Handler Either a file or directory handler.
*/
public function get($path, Handler $handler = null);
/**
* Register a plugin.
*
* @param PluginInterface $plugin The plugin to register.
*
* @return $this
*/
public function addPlugin(PluginInterface $plugin);
}

View File

@ -1,12 +0,0 @@
<?php
namespace League\Flysystem;
use LogicException;
/**
* Thrown when the MountManager cannot find a filesystem.
*/
class FilesystemNotFoundException extends LogicException implements FilesystemException
{
}

View File

@ -1,137 +0,0 @@
<?php
namespace League\Flysystem;
use BadMethodCallException;
/**
* @deprecated
*/
abstract class Handler
{
/**
* @var string
*/
protected $path;
/**
* @var FilesystemInterface
*/
protected $filesystem;
/**
* Constructor.
*
* @param FilesystemInterface $filesystem
* @param string $path
*/
public function __construct(FilesystemInterface $filesystem = null, $path = null)
{
$this->path = $path;
$this->filesystem = $filesystem;
}
/**
* Check whether the entree is a directory.
*
* @return bool
*/
public function isDir()
{
return $this->getType() === 'dir';
}
/**
* Check whether the entree is a file.
*
* @return bool
*/
public function isFile()
{
return $this->getType() === 'file';
}
/**
* Retrieve the entree type (file|dir).
*
* @return string file or dir
*/
public function getType()
{
$metadata = $this->filesystem->getMetadata($this->path);
return $metadata ? $metadata['type'] : 'dir';
}
/**
* Set the Filesystem object.
*
* @param FilesystemInterface $filesystem
*
* @return $this
*/
public function setFilesystem(FilesystemInterface $filesystem)
{
$this->filesystem = $filesystem;
return $this;
}
/**
* Retrieve the Filesystem object.
*
* @return FilesystemInterface
*/
public function getFilesystem()
{
return $this->filesystem;
}
/**
* Set the entree path.
*
* @param string $path
*
* @return $this
*/
public function setPath($path)
{
$this->path = $path;
return $this;
}
/**
* Retrieve the entree path.
*
* @return string path
*/
public function getPath()
{
return $this->path;
}
/**
* Plugins pass-through.
*
* @param string $method
* @param array $arguments
*
* @return mixed
*/
public function __call($method, array $arguments)
{
array_unshift($arguments, $this->path);
$callback = [$this->filesystem, $method];
try {
return call_user_func_array($callback, $arguments);
} catch (BadMethodCallException $e) {
throw new BadMethodCallException(
'Call to undefined method '
. get_called_class()
. '::' . $method
);
}
}
}

View File

@ -1,9 +0,0 @@
<?php
namespace League\Flysystem;
use RuntimeException;
class InvalidRootException extends RuntimeException implements FilesystemException
{
}

View File

@ -1,648 +0,0 @@
<?php
namespace League\Flysystem;
use InvalidArgumentException;
use League\Flysystem\Plugin\PluggableTrait;
use League\Flysystem\Plugin\PluginNotFoundException;
/**
* Class MountManager.
*
* Proxies methods to Filesystem (@see __call):
*
* @method AdapterInterface getAdapter($prefix)
* @method Config getConfig($prefix)
* @method array listFiles($directory = '', $recursive = false)
* @method array listPaths($directory = '', $recursive = false)
* @method array getWithMetadata($path, array $metadata)
* @method Filesystem flushCache()
* @method void assertPresent($path)
* @method void assertAbsent($path)
* @method Filesystem addPlugin(PluginInterface $plugin)
*/
class MountManager implements FilesystemInterface
{
use PluggableTrait;
/**
* @var FilesystemInterface[]
*/
protected $filesystems = [];
/**
* Constructor.
*
* @param FilesystemInterface[] $filesystems [:prefix => Filesystem,]
*
* @throws InvalidArgumentException
*/
public function __construct(array $filesystems = [])
{
$this->mountFilesystems($filesystems);
}
/**
* Mount filesystems.
*
* @param FilesystemInterface[] $filesystems [:prefix => Filesystem,]
*
* @throws InvalidArgumentException
*
* @return $this
*/
public function mountFilesystems(array $filesystems)
{
foreach ($filesystems as $prefix => $filesystem) {
$this->mountFilesystem($prefix, $filesystem);
}
return $this;
}
/**
* Mount filesystems.
*
* @param string $prefix
* @param FilesystemInterface $filesystem
*
* @throws InvalidArgumentException
*
* @return $this
*/
public function mountFilesystem($prefix, FilesystemInterface $filesystem)
{
if ( ! is_string($prefix)) {
throw new InvalidArgumentException(__METHOD__ . ' expects argument #1 to be a string.');
}
$this->filesystems[$prefix] = $filesystem;
return $this;
}
/**
* Get the filesystem with the corresponding prefix.
*
* @param string $prefix
*
* @throws FilesystemNotFoundException
*
* @return FilesystemInterface
*/
public function getFilesystem($prefix)
{
if ( ! isset($this->filesystems[$prefix])) {
throw new FilesystemNotFoundException('No filesystem mounted with prefix ' . $prefix);
}
return $this->filesystems[$prefix];
}
/**
* Retrieve the prefix from an arguments array.
*
* @param array $arguments
*
* @throws InvalidArgumentException
*
* @return array [:prefix, :arguments]
*/
public function filterPrefix(array $arguments)
{
if (empty($arguments)) {
throw new InvalidArgumentException('At least one argument needed');
}
$path = array_shift($arguments);
if ( ! is_string($path)) {
throw new InvalidArgumentException('First argument should be a string');
}
list($prefix, $path) = $this->getPrefixAndPath($path);
array_unshift($arguments, $path);
return [$prefix, $arguments];
}
/**
* @param string $directory
* @param bool $recursive
*
* @throws InvalidArgumentException
* @throws FilesystemNotFoundException
*
* @return array
*/
public function listContents($directory = '', $recursive = false)
{
list($prefix, $directory) = $this->getPrefixAndPath($directory);
$filesystem = $this->getFilesystem($prefix);
$result = $filesystem->listContents($directory, $recursive);
foreach ($result as &$file) {
$file['filesystem'] = $prefix;
}
return $result;
}
/**
* Call forwarder.
*
* @param string $method
* @param array $arguments
*
* @throws InvalidArgumentException
* @throws FilesystemNotFoundException
*
* @return mixed
*/
public function __call($method, $arguments)
{
list($prefix, $arguments) = $this->filterPrefix($arguments);
return $this->invokePluginOnFilesystem($method, $arguments, $prefix);
}
/**
* @param string $from
* @param string $to
* @param array $config
*
* @throws InvalidArgumentException
* @throws FilesystemNotFoundException
* @throws FileExistsException
*
* @return bool
*/
public function copy($from, $to, array $config = [])
{
list($prefixFrom, $from) = $this->getPrefixAndPath($from);
$buffer = $this->getFilesystem($prefixFrom)->readStream($from);
if ($buffer === false) {
return false;
}
list($prefixTo, $to) = $this->getPrefixAndPath($to);
$result = $this->getFilesystem($prefixTo)->writeStream($to, $buffer, $config);
if (is_resource($buffer)) {
fclose($buffer);
}
return $result;
}
/**
* List with plugin adapter.
*
* @param array $keys
* @param string $directory
* @param bool $recursive
*
* @throws InvalidArgumentException
* @throws FilesystemNotFoundException
*
* @return array
*/
public function listWith(array $keys = [], $directory = '', $recursive = false)
{
list($prefix, $directory) = $this->getPrefixAndPath($directory);
$arguments = [$keys, $directory, $recursive];
return $this->invokePluginOnFilesystem('listWith', $arguments, $prefix);
}
/**
* Move a file.
*
* @param string $from
* @param string $to
* @param array $config
*
* @throws InvalidArgumentException
* @throws FilesystemNotFoundException
*
* @return bool
*/
public function move($from, $to, array $config = [])
{
list($prefixFrom, $pathFrom) = $this->getPrefixAndPath($from);
list($prefixTo, $pathTo) = $this->getPrefixAndPath($to);
if ($prefixFrom === $prefixTo) {
$filesystem = $this->getFilesystem($prefixFrom);
$renamed = $filesystem->rename($pathFrom, $pathTo);
if ($renamed && isset($config['visibility'])) {
return $filesystem->setVisibility($pathTo, $config['visibility']);
}
return $renamed;
}
$copied = $this->copy($from, $to, $config);
if ($copied) {
return $this->delete($from);
}
return false;
}
/**
* Invoke a plugin on a filesystem mounted on a given prefix.
*
* @param string $method
* @param array $arguments
* @param string $prefix
*
* @throws FilesystemNotFoundException
*
* @return mixed
*/
public function invokePluginOnFilesystem($method, $arguments, $prefix)
{
$filesystem = $this->getFilesystem($prefix);
try {
return $this->invokePlugin($method, $arguments, $filesystem);
} catch (PluginNotFoundException $e) {
// Let it pass, it's ok, don't panic.
}
$callback = [$filesystem, $method];
return call_user_func_array($callback, $arguments);
}
/**
* @param string $path
*
* @throws InvalidArgumentException
*
* @return string[] [:prefix, :path]
*/
protected function getPrefixAndPath($path)
{
if (strpos($path, '://') < 1) {
throw new InvalidArgumentException('No prefix detected in path: ' . $path);
}
return explode('://', $path, 2);
}
/**
* Check whether a file exists.
*
* @param string $path
*
* @return bool
*/
public function has($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->has($path);
}
/**
* Read a file.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return string|false The file contents or false on failure.
*/
public function read($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->read($path);
}
/**
* Retrieves a read-stream for a path.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return resource|false The path resource or false on failure.
*/
public function readStream($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->readStream($path);
}
/**
* Get a file's metadata.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return array|false The file metadata or false on failure.
*/
public function getMetadata($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->getMetadata($path);
}
/**
* Get a file's size.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return int|false The file size or false on failure.
*/
public function getSize($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->getSize($path);
}
/**
* Get a file's mime-type.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return string|false The file mime-type or false on failure.
*/
public function getMimetype($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->getMimetype($path);
}
/**
* Get a file's timestamp.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return string|false The timestamp or false on failure.
*/
public function getTimestamp($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->getTimestamp($path);
}
/**
* Get a file's visibility.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return string|false The visibility (public|private) or false on failure.
*/
public function getVisibility($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->getVisibility($path);
}
/**
* Write a new file.
*
* @param string $path The path of the new file.
* @param string $contents The file contents.
* @param array $config An optional configuration array.
*
* @throws FileExistsException
*
* @return bool True on success, false on failure.
*/
public function write($path, $contents, array $config = [])
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->write($path, $contents, $config);
}
/**
* Write a new file using a stream.
*
* @param string $path The path of the new file.
* @param resource $resource The file handle.
* @param array $config An optional configuration array.
*
* @throws InvalidArgumentException If $resource is not a file handle.
* @throws FileExistsException
*
* @return bool True on success, false on failure.
*/
public function writeStream($path, $resource, array $config = [])
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->writeStream($path, $resource, $config);
}
/**
* Update an existing file.
*
* @param string $path The path of the existing file.
* @param string $contents The file contents.
* @param array $config An optional configuration array.
*
* @throws FileNotFoundException
*
* @return bool True on success, false on failure.
*/
public function update($path, $contents, array $config = [])
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->update($path, $contents, $config);
}
/**
* Update an existing file using a stream.
*
* @param string $path The path of the existing file.
* @param resource $resource The file handle.
* @param array $config An optional configuration array.
*
* @throws InvalidArgumentException If $resource is not a file handle.
* @throws FileNotFoundException
*
* @return bool True on success, false on failure.
*/
public function updateStream($path, $resource, array $config = [])
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->updateStream($path, $resource, $config);
}
/**
* Rename a file.
*
* @param string $path Path to the existing file.
* @param string $newpath The new path of the file.
*
* @throws FileExistsException Thrown if $newpath exists.
* @throws FileNotFoundException Thrown if $path does not exist.
*
* @return bool True on success, false on failure.
*/
public function rename($path, $newpath)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->rename($path, $newpath);
}
/**
* Delete a file.
*
* @param string $path
*
* @throws FileNotFoundException
*
* @return bool True on success, false on failure.
*/
public function delete($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->delete($path);
}
/**
* Delete a directory.
*
* @param string $dirname
*
* @throws RootViolationException Thrown if $dirname is empty.
*
* @return bool True on success, false on failure.
*/
public function deleteDir($dirname)
{
list($prefix, $dirname) = $this->getPrefixAndPath($dirname);
return $this->getFilesystem($prefix)->deleteDir($dirname);
}
/**
* Create a directory.
*
* @param string $dirname The name of the new directory.
* @param array $config An optional configuration array.
*
* @return bool True on success, false on failure.
*/
public function createDir($dirname, array $config = [])
{
list($prefix, $dirname) = $this->getPrefixAndPath($dirname);
return $this->getFilesystem($prefix)->createDir($dirname);
}
/**
* Set the visibility for a file.
*
* @param string $path The path to the file.
* @param string $visibility One of 'public' or 'private'.
*
* @throws FileNotFoundException
*
* @return bool True on success, false on failure.
*/
public function setVisibility($path, $visibility)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->setVisibility($path, $visibility);
}
/**
* Create a file or update if exists.
*
* @param string $path The path to the file.
* @param string $contents The file contents.
* @param array $config An optional configuration array.
*
* @return bool True on success, false on failure.
*/
public function put($path, $contents, array $config = [])
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->put($path, $contents, $config);
}
/**
* Create a file or update if exists.
*
* @param string $path The path to the file.
* @param resource $resource The file handle.
* @param array $config An optional configuration array.
*
* @throws InvalidArgumentException Thrown if $resource is not a resource.
*
* @return bool True on success, false on failure.
*/
public function putStream($path, $resource, array $config = [])
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->putStream($path, $resource, $config);
}
/**
* Read and delete a file.
*
* @param string $path The path to the file.
*
* @throws FileNotFoundException
*
* @return string|false The file contents, or false on failure.
*/
public function readAndDelete($path)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->readAndDelete($path);
}
/**
* Get a file/directory handler.
*
* @deprecated
*
* @param string $path The path to the file.
* @param Handler $handler An optional existing handler to populate.
*
* @return Handler Either a file or directory handler.
*/
public function get($path, Handler $handler = null)
{
list($prefix, $path) = $this->getPrefixAndPath($path);
return $this->getFilesystem($prefix)->get($path);
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace League\Flysystem;
use RuntimeException;
use SplFileInfo;
class NotSupportedException extends RuntimeException implements FilesystemException
{
/**
* Create a new exception for a link.
*
* @param SplFileInfo $file
*
* @return static
*/
public static function forLink(SplFileInfo $file)
{
$message = 'Links are not supported, encountered link at ';
return new static($message . $file->getPathname());
}
/**
* Create a new exception for a link.
*
* @param string $systemType
*
* @return static
*/
public static function forFtpSystemType($systemType)
{
$message = "The FTP system type '$systemType' is currently not supported.";
return new static($message);
}
}

Some files were not shown because too many files have changed in this diff Show More