From a5f3b8cb78bb276114810f543bda83de86f345d1 Mon Sep 17 00:00:00 2001 From: Anyon Date: Tue, 29 Sep 2020 13:24:46 +0800 Subject: [PATCH] ComposerUpdate --- app/admin/view/auth/index.html | 31 +- app/admin/view/menu/index.html | 20 +- app/admin/view/module/index.html | 2 - app/admin/view/oplog/index.html | 2 - app/admin/view/queue/index.html | 28 +- vendor/composer/autoload_classmap.php | 10 - vendor/composer/autoload_files.php | 1 - vendor/composer/autoload_psr4.php | 1 - vendor/composer/autoload_static.php | 19 - vendor/composer/installed.json | 102 +- .../opis/closure/.github/workflows/tests.yml | 43 - vendor/opis/closure/CHANGELOG.md | 247 ---- vendor/opis/closure/LICENSE | 20 - vendor/opis/closure/NOTICE | 9 - vendor/opis/closure/README.md | 92 -- vendor/opis/closure/autoload.php | 39 - vendor/opis/closure/composer.json | 40 - vendor/opis/closure/functions.php | 41 - vendor/opis/closure/src/Analyzer.php | 62 - vendor/opis/closure/src/ClosureContext.php | 34 - vendor/opis/closure/src/ClosureScope.php | 25 - vendor/opis/closure/src/ClosureStream.php | 99 -- vendor/opis/closure/src/ISecurityProvider.php | 25 - vendor/opis/closure/src/ReflectionClosure.php | 1042 ----------------- vendor/opis/closure/src/SecurityException.php | 18 - vendor/opis/closure/src/SecurityProvider.php | 42 - vendor/opis/closure/src/SelfReference.php | 31 - .../opis/closure/src/SerializableClosure.php | 678 ----------- vendor/services.php | 2 +- vendor/topthink/framework/README.md | 2 +- vendor/topthink/framework/composer.json | 1 - vendor/topthink/framework/src/think/App.php | 2 +- .../topthink/framework/src/think/Config.php | 4 + .../topthink/framework/src/think/Console.php | 83 +- .../framework/src/think/Container.php | 9 +- vendor/topthink/framework/src/think/Http.php | 12 +- vendor/topthink/framework/src/think/Lang.php | 12 + vendor/topthink/framework/src/think/Route.php | 18 +- .../topthink/framework/src/think/Validate.php | 3 +- .../src/think/cache/driver/Redis.php | 2 +- .../console/command/make/stubs/command.stub | 6 +- .../console/command/make/stubs/listener.stub | 2 +- .../console/command/make/stubs/service.stub | 4 +- .../console/command/make/stubs/validate.stub | 12 +- .../think/console/command/optimize/Route.php | 7 +- .../src/think/console/input/Option.php | 33 +- .../think/middleware/CheckRequestCache.php | 40 +- .../framework/src/think/route/Rule.php | 82 +- .../framework/src/think/route/RuleGroup.php | 18 +- .../framework/src/think/route/RuleItem.php | 16 +- .../framework/src/think/route/RuleName.php | 24 +- .../framework/src/think/route/Url.php | 6 +- .../src/think/session/driver/File.php | 2 +- .../framework/tests/ContainerTest.php | 1 + vendor/topthink/framework/tests/HttpTest.php | 1 + .../think-orm/src/db/PDOConnection.php | 32 +- .../think-orm/src/db/concern/WhereQuery.php | 14 +- .../src/db/exception/DbException.php | 135 ++- .../topthink/think-orm/src/model/Relation.php | 20 + .../think-orm/src/model/concern/Attribute.php | 8 +- .../src/model/concern/Conversion.php | 28 + .../src/model/relation/BelongsToMany.php | 31 +- .../think-orm/src/model/relation/HasOne.php | 2 +- .../think-orm/src/model/relation/OneToOne.php | 4 - .../zoujingli/think-library/src/Library.php | 2 +- .../src/storage/AliossStorage.php | 4 +- .../src/storage/LocalStorage.php | 4 +- .../src/storage/QiniuStorage.php | 4 +- 68 files changed, 511 insertions(+), 2984 deletions(-) delete mode 100644 vendor/opis/closure/.github/workflows/tests.yml delete mode 100644 vendor/opis/closure/CHANGELOG.md delete mode 100644 vendor/opis/closure/LICENSE delete mode 100644 vendor/opis/closure/NOTICE delete mode 100644 vendor/opis/closure/README.md delete mode 100644 vendor/opis/closure/autoload.php delete mode 100644 vendor/opis/closure/composer.json delete mode 100644 vendor/opis/closure/functions.php delete mode 100644 vendor/opis/closure/src/Analyzer.php delete mode 100644 vendor/opis/closure/src/ClosureContext.php delete mode 100644 vendor/opis/closure/src/ClosureScope.php delete mode 100644 vendor/opis/closure/src/ClosureStream.php delete mode 100644 vendor/opis/closure/src/ISecurityProvider.php delete mode 100644 vendor/opis/closure/src/ReflectionClosure.php delete mode 100644 vendor/opis/closure/src/SecurityException.php delete mode 100644 vendor/opis/closure/src/SecurityProvider.php delete mode 100644 vendor/opis/closure/src/SelfReference.php delete mode 100644 vendor/opis/closure/src/SerializableClosure.php diff --git a/app/admin/view/auth/index.html b/app/admin/view/auth/index.html index 2aac8b572..da18d377f 100644 --- a/app/admin/view/auth/index.html +++ b/app/admin/view/auth/index.html @@ -38,35 +38,26 @@ {$vo.create_at|format_datetime} {eq name='vo.status' value='0'}已禁用{else}使用中{/eq} - - {if auth("edit")} + 编 辑 - {/if} - - {if auth("apply")} + + 授 权 - {/if} - - {if $vo.status eq 1 and auth("state")} + + 禁 用 - {/if} - - {if $vo.status eq 0 and auth("state")} + + 启 用 - {/if} - - {if auth("remove")} + + 删 除 - {/if} - + {/foreach} - {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} - - -{/block} +{/block} \ No newline at end of file diff --git a/app/admin/view/menu/index.html b/app/admin/view/menu/index.html index 8162224c3..3d7c8ce76 100644 --- a/app/admin/view/menu/index.html +++ b/app/admin/view/menu/index.html @@ -43,7 +43,6 @@ {$vo.url} {eq name='vo.status' value='0'}已禁用{else}使用中{/eq} - {if auth("add")} 添 加 @@ -51,21 +50,18 @@ 添 加 {/if} - - {if auth("edit")} + 编 辑 - {/if} - - {if $vo.status eq 1 and auth("state")} + + 禁 用 - {elseif auth("state")} + + 启 用 - {/if} - - {if auth("remove")} + + 删 除 - {/if} - + {/foreach} diff --git a/app/admin/view/module/index.html b/app/admin/view/module/index.html index 363c6c8f1..8e05b3c0a 100644 --- a/app/admin/view/module/index.html +++ b/app/admin/view/module/index.html @@ -37,8 +37,6 @@ {/foreach} - {empty name='modules'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} - {/block} \ No newline at end of file diff --git a/app/admin/view/oplog/index.html b/app/admin/view/oplog/index.html index 349514f69..1203b1cf7 100644 --- a/app/admin/view/oplog/index.html +++ b/app/admin/view/oplog/index.html @@ -4,11 +4,9 @@ 日志配置 - - diff --git a/app/admin/view/queue/index.html b/app/admin/view/queue/index.html index 374115a4e..a0b655689 100644 --- a/app/admin/view/queue/index.html +++ b/app/admin/view/queue/index.html @@ -84,33 +84,35 @@
- {if isset($vo.loops_time) and $vo.loops_time > 0} + - {/if} + - {if $vo.rscript eq 1} + - {else} + - {/if} + - {if $vo.status eq 1} + 等待处理 - {elseif $vo.status eq 2} + 正在处理 - {elseif $vo.status eq 3} + 处理完成 - {elseif $vo.status eq 4 and auth('redo')} + 处理失败 - {/if} - {if auth("remove") } + + + - {/if} + + @@ -121,8 +123,6 @@ {/foreach} - {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} -
{/block} \ No newline at end of file diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index f57abcb4d..39394c13c 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -96,16 +96,6 @@ return array( 'League\\MimeTypeDetection\\FinfoMimeTypeDetector' => $vendorDir . '/league/mime-type-detection/src/FinfoMimeTypeDetector.php', 'League\\MimeTypeDetection\\GeneratedExtensionToMimeTypeMap' => $vendorDir . '/league/mime-type-detection/src/GeneratedExtensionToMimeTypeMap.php', 'League\\MimeTypeDetection\\MimeTypeDetector' => $vendorDir . '/league/mime-type-detection/src/MimeTypeDetector.php', - 'Opis\\Closure\\Analyzer' => $vendorDir . '/opis/closure/src/Analyzer.php', - 'Opis\\Closure\\ClosureContext' => $vendorDir . '/opis/closure/src/ClosureContext.php', - 'Opis\\Closure\\ClosureScope' => $vendorDir . '/opis/closure/src/ClosureScope.php', - 'Opis\\Closure\\ClosureStream' => $vendorDir . '/opis/closure/src/ClosureStream.php', - 'Opis\\Closure\\ISecurityProvider' => $vendorDir . '/opis/closure/src/ISecurityProvider.php', - 'Opis\\Closure\\ReflectionClosure' => $vendorDir . '/opis/closure/src/ReflectionClosure.php', - 'Opis\\Closure\\SecurityException' => $vendorDir . '/opis/closure/src/SecurityException.php', - 'Opis\\Closure\\SecurityProvider' => $vendorDir . '/opis/closure/src/SecurityProvider.php', - 'Opis\\Closure\\SelfReference' => $vendorDir . '/opis/closure/src/SelfReference.php', - 'Opis\\Closure\\SerializableClosure' => $vendorDir . '/opis/closure/src/SerializableClosure.php', 'Psr\\Cache\\CacheException' => $vendorDir . '/psr/cache/src/CacheException.php', 'Psr\\Cache\\CacheItemInterface' => $vendorDir . '/psr/cache/src/CacheItemInterface.php', 'Psr\\Cache\\CacheItemPoolInterface' => $vendorDir . '/psr/cache/src/CacheItemPoolInterface.php', diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index b5149744b..04528d5a0 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -7,6 +7,5 @@ $baseDir = dirname($vendorDir); return array( '9b552a3cc426e3287cc811caefa3cf53' => $vendorDir . '/topthink/think-helper/src/helper.php', - '538ca81a9a966a6716601ecf48f4eaef' => $vendorDir . '/opis/closure/functions.php', '8dafcc6956460bc297e00381fed53e11' => $vendorDir . '/zoujingli/think-library/src/common.php', ); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index d9212d078..5cd697a96 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -18,7 +18,6 @@ return array( 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), - 'Opis\\Closure\\' => array($vendorDir . '/opis/closure/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'), diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 49c6c8b81..a7dfbdd96 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -8,7 +8,6 @@ class ComposerStaticInit33b66ed99ea8fcca84c95dfb0e7ed409 { public static $files = array ( '9b552a3cc426e3287cc811caefa3cf53' => __DIR__ . '/..' . '/topthink/think-helper/src/helper.php', - '538ca81a9a966a6716601ecf48f4eaef' => __DIR__ . '/..' . '/opis/closure/functions.php', '8dafcc6956460bc297e00381fed53e11' => __DIR__ . '/..' . '/zoujingli/think-library/src/common.php', ); @@ -40,10 +39,6 @@ class ComposerStaticInit33b66ed99ea8fcca84c95dfb0e7ed409 'Psr\\Container\\' => 14, 'Psr\\Cache\\' => 10, ), - 'O' => - array ( - 'Opis\\Closure\\' => 13, - ), 'L' => array ( 'League\\MimeTypeDetection\\' => 25, @@ -112,10 +107,6 @@ class ComposerStaticInit33b66ed99ea8fcca84c95dfb0e7ed409 array ( 0 => __DIR__ . '/..' . '/psr/cache/src', ), - 'Opis\\Closure\\' => - array ( - 0 => __DIR__ . '/..' . '/opis/closure/src', - ), 'League\\MimeTypeDetection\\' => array ( 0 => __DIR__ . '/..' . '/league/mime-type-detection/src', @@ -233,16 +224,6 @@ class ComposerStaticInit33b66ed99ea8fcca84c95dfb0e7ed409 'League\\MimeTypeDetection\\FinfoMimeTypeDetector' => __DIR__ . '/..' . '/league/mime-type-detection/src/FinfoMimeTypeDetector.php', 'League\\MimeTypeDetection\\GeneratedExtensionToMimeTypeMap' => __DIR__ . '/..' . '/league/mime-type-detection/src/GeneratedExtensionToMimeTypeMap.php', 'League\\MimeTypeDetection\\MimeTypeDetector' => __DIR__ . '/..' . '/league/mime-type-detection/src/MimeTypeDetector.php', - 'Opis\\Closure\\Analyzer' => __DIR__ . '/..' . '/opis/closure/src/Analyzer.php', - 'Opis\\Closure\\ClosureContext' => __DIR__ . '/..' . '/opis/closure/src/ClosureContext.php', - 'Opis\\Closure\\ClosureScope' => __DIR__ . '/..' . '/opis/closure/src/ClosureScope.php', - 'Opis\\Closure\\ClosureStream' => __DIR__ . '/..' . '/opis/closure/src/ClosureStream.php', - 'Opis\\Closure\\ISecurityProvider' => __DIR__ . '/..' . '/opis/closure/src/ISecurityProvider.php', - 'Opis\\Closure\\ReflectionClosure' => __DIR__ . '/..' . '/opis/closure/src/ReflectionClosure.php', - 'Opis\\Closure\\SecurityException' => __DIR__ . '/..' . '/opis/closure/src/SecurityException.php', - 'Opis\\Closure\\SecurityProvider' => __DIR__ . '/..' . '/opis/closure/src/SecurityProvider.php', - 'Opis\\Closure\\SelfReference' => __DIR__ . '/..' . '/opis/closure/src/SelfReference.php', - 'Opis\\Closure\\SerializableClosure' => __DIR__ . '/..' . '/opis/closure/src/SerializableClosure.php', 'Psr\\Cache\\CacheException' => __DIR__ . '/..' . '/psr/cache/src/CacheException.php', 'Psr\\Cache\\CacheItemInterface' => __DIR__ . '/..' . '/psr/cache/src/CacheItemInterface.php', 'Psr\\Cache\\CacheItemPoolInterface' => __DIR__ . '/..' . '/psr/cache/src/CacheItemPoolInterface.php', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 145caaa0c..9063162f2 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -280,75 +280,6 @@ } ] }, - { - "name": "opis/closure", - "version": "3.5.7", - "version_normalized": "3.5.7.0", - "source": { - "type": "git", - "url": "https://github.com/opis/closure.git", - "reference": "4531e53afe2fc660403e76fb7644e95998bff7bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/opis/closure/zipball/4531e53afe2fc660403e76fb7644e95998bff7bf", - "reference": "4531e53afe2fc660403e76fb7644e95998bff7bf", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^5.4 || ^7.0" - }, - "require-dev": { - "jeremeamia/superclosure": "^2.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "time": "2020-09-06T17:02:15+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.5.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Opis\\Closure\\": "src/" - }, - "files": [ - "functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marius Sarca", - "email": "marius.sarca@gmail.com" - }, - { - "name": "Sorin Sarca", - "email": "sarca_sorin@hotmail.com" - } - ], - "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", - "homepage": "https://opis.io/closure", - "keywords": [ - "anonymous functions", - "closure", - "function", - "serializable", - "serialization", - "serialize" - ] - }, { "name": "psr/cache", "version": "1.0.1", @@ -649,17 +580,17 @@ }, { "name": "topthink/framework", - "version": "v6.0.3", - "version_normalized": "6.0.3.0", + "version": "v6.0.4", + "version_normalized": "6.0.4.0", "source": { "type": "git", "url": "https://github.com/top-think/framework.git", - "reference": "b4046fb21e6163ba23a792b694162693dbe71b4b" + "reference": "4b252d78562d4a51a501651f837c26cb9d91624f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/framework/zipball/b4046fb21e6163ba23a792b694162693dbe71b4b", - "reference": "b4046fb21e6163ba23a792b694162693dbe71b4b", + "url": "https://api.github.com/repos/top-think/framework/zipball/4b252d78562d4a51a501651f837c26cb9d91624f", + "reference": "4b252d78562d4a51a501651f837c26cb9d91624f", "shasum": "", "mirrors": [ { @@ -673,7 +604,6 @@ "ext-mbstring": "*", "league/flysystem": "^1.0", "league/flysystem-cached-adapter": "^1.0", - "opis/closure": "^3.1", "php": ">=7.1.0", "psr/container": "~1.0", "psr/log": "~1.0", @@ -686,7 +616,7 @@ "mockery/mockery": "^1.2", "phpunit/phpunit": "^7.0" }, - "time": "2020-06-26T16:03:10+00:00", + "time": "2020-09-29T02:19:59+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -766,17 +696,17 @@ }, { "name": "topthink/think-orm", - "version": "v2.0.33", - "version_normalized": "2.0.33.0", + "version": "v2.0.34", + "version_normalized": "2.0.34.0", "source": { "type": "git", "url": "https://github.com/top-think/think-orm.git", - "reference": "35ca511a1e4d671b39f7afb4c887703c16ef6957" + "reference": "57f9b98895b0ff4ae7b7b75e51456fd8cb8fb629" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/think-orm/zipball/35ca511a1e4d671b39f7afb4c887703c16ef6957", - "reference": "35ca511a1e4d671b39f7afb4c887703c16ef6957", + "url": "https://api.github.com/repos/top-think/think-orm/zipball/57f9b98895b0ff4ae7b7b75e51456fd8cb8fb629", + "reference": "57f9b98895b0ff4ae7b7b75e51456fd8cb8fb629", "shasum": "", "mirrors": [ { @@ -792,7 +722,7 @@ "psr/simple-cache": "^1.0", "topthink/think-helper": "^3.1" }, - "time": "2020-06-22T14:57:28+00:00", + "time": "2020-09-28T08:24:57+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -963,12 +893,12 @@ "source": { "type": "git", "url": "https://github.com/zoujingli/ThinkLibrary.git", - "reference": "3a7ff93e03acdcf5c723c7c4edcb36c9c9828e6a" + "reference": "141fa175f3cdbdb4ad2e9927d6de379fb618e75a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/3a7ff93e03acdcf5c723c7c4edcb36c9c9828e6a", - "reference": "3a7ff93e03acdcf5c723c7c4edcb36c9c9828e6a", + "url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/141fa175f3cdbdb4ad2e9927d6de379fb618e75a", + "reference": "141fa175f3cdbdb4ad2e9927d6de379fb618e75a", "shasum": "", "mirrors": [ { @@ -985,7 +915,7 @@ "ext-mbstring": "*", "topthink/framework": "^6.0" }, - "time": "2020-09-27T03:40:51+00:00", + "time": "2020-09-29T05:20:22+00:00", "type": "library", "extra": { "think": { diff --git a/vendor/opis/closure/.github/workflows/tests.yml b/vendor/opis/closure/.github/workflows/tests.yml deleted file mode 100644 index b71e6e4aa..000000000 --- a/vendor/opis/closure/.github/workflows/tests.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: "Tests" -on: - push: - paths-ignore: - - '**.md' - pull_request: - paths-ignore: - - '**.md' -jobs: - tests: - runs-on: ubuntu-latest - strategy: - fail-fast: true - matrix: - php: [5.4, 5.5, 5.6, 7.0, 7.1, 7.2, 7.3, 7.4] - stability: [prefer-stable] - - name: PHP ${{ matrix.php }} - - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ~/.composer/cache/files - key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - coverage: none - - - name: Update composer - run: composer self-update - - - name: Install dependencies - run: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress - - - name: Execute tests - run: vendor/bin/phpunit --verbose \ No newline at end of file diff --git a/vendor/opis/closure/CHANGELOG.md b/vendor/opis/closure/CHANGELOG.md deleted file mode 100644 index bcf1a3510..000000000 --- a/vendor/opis/closure/CHANGELOG.md +++ /dev/null @@ -1,247 +0,0 @@ -CHANGELOG ---------- -### v3.5.7, 2020.09.06 - -- Fixed issue [#76](https://github.com/opis/closure/issues/76). -- Fixed issue [#78](https://github.com/opis/closure/issues/78). - -### v3.5.6, 2020.08.11 - -- Fixed issue [#70](https://github.com/opis/closure/issues/70) - -### v3.5.5, 2020.06.17 - -- Fixed a false-positive when using `Opis\Closure\ReflectionClosure::isScopeRequired` method - -### v3.5.4, 2020.06.07 - -- Fixed a false-positive when using `Opis\Closure\ReflectionClosure::isScopeRequired` method -- Fixed a bug related to `T_STRING_VARNAME` - -### v3.5.3, 2020.05.25 - -- Improved parser -- The class scope optimisation is no longer used. We always bind now to the closure's original class scope. -When the class scope was `null`, the optimisation failed to work as expected and kept the wrong `SerializableClosure` scope. - -### v3.5.2, 2020.05.21 - -- Removed extra semicolon in short closures, since is not part of the closure's body. - -### v3.5.1, 2019.11.30 - -- Bugfix. See #47 - -### v3.5.0, 2019.11.29 - -- Added support for short closures (arrow functions) -- Added `isShortClosure` method to `Opis\Closure\ReflectionClosure` - -### v3.4.2, 2019.11.29 - -- Added `stream_set_option()` - -### v3.4.1, 2019.10.19 - -- Fixed a [bug](https://github.com/opis/closure/issues/40) that prevented serialization to work correctly. - -### v3.4.0, 2019.09.03 - -- Added `createClosure` static method in `Opis\Closure\SerializableClosure`. -This method creates a new closure from arbitrary code, emulating `create_function`, -but without using eval - -### v3.3.1, 2019.07.10 - -- Use `sha1` instead of `md5` for hashing file names in `Opis\Closure\ReflectionClosure` class - -### v3.3.0, 2019.05.31 - -- Fixed a bug that prevented signed closures to properly work when the serialized string -contains invalid UTF-8 chars. Starting with this version `json_encode` is no longer used -when signing a closure. Backward compatibility is maintained and all closures that were -previously signed using the old method will continue to work. - -### v3.2.0, 2019.05.05 - -- Since an unsigned closure can be unserialized when no security provider is set, -there is no reason to treat differently a signed closure in the same situation. -Therefore, the `Opis\Closure\SecurityException` exception is no longer thrown when -unserializing a signed closure, if no security provider is set. - -### v3.1.6, 2019.02.22 - -- Fixed a bug that occurred when trying to set properties of classes that were not defined in user-land. -Those properties are now ignored. - -### v3.1.5, 2019.01.14 - -- Improved parser - -### v3.1.4, 2019.01.14 - -- Added support for static methods that are named using PHP keywords or magic constants. -Ex: `A::new()`, `A::use()`, `A::if()`, `A::function()`, `A::__DIR__()`, etc. -- Used `@internal` to mark classes & methods that are for internal use only and -backward compatibility is not guaranteed. - -### v3.1.3, 2019.01.07 - -- Fixed a bug that prevented traits to be correctly resolved when used by an -anonymous class -- Fixed a bug that occurred when `$this` keyword was used inside an anonymous class - -### v3.1.2, 2018.12.16 - -* Fixed a bug regarding comma trail in group-use statements. See [issue 23](https://github.com/opis/closure/issues/23) - -### v3.1.1, 2018.10.02 - -* Fixed a bug where `parent` keyword was treated like a class-name and scope was not added to the -serialized closure -* Fixed a bug where return type was not properly handled for nested closures -* Support for anonymous classes was improved - -### v3.1.0, 2018.09.20 - -* Added `transformUseVariables` and `resolveUseVariables` to -`Opis\Closure\SerializableClosure` class. -* Added `removeSecurityProvider` static method to -`Opis\Closure\SerializableClosure` class. -* Fixed some security related issues where a user was able to unserialize an unsigned -closure, even when a security provider was in use. - -### v3.0.12, 2018.02.23 - -* Bugfix. See [issue 20](https://github.com/opis/closure/issues/20) - -### v3.0.11, 2018.01.22 - -* Bugfix. See [issue 18](https://github.com/opis/closure/issues/18) - -### v3.0.10, 2018.01.04 - -* Improved support for PHP 7.1 & 7.2 - -### v3.0.9, 2018.01.04 - -* Fixed a bug where the return type was not properly resolved. -See [issue 17](https://github.com/opis/closure/issues/17) -* Added more tests - -### v3.0.8, 2017.12.18 - -* Fixed a bug. See [issue 16](https://github.com/opis/closure/issues/16) - -### v3.0.7, 2017.10.31 - -* Bugfix: static properties are ignored now, since they are not serializable - -### v3.0.6, 2017.10.06 - -* Fixed a bug introduced by accident in 3.0.5 - -### v3.0.5, 2017.09.18 - -* Fixed a bug related to nested references - -### v3.0.4, 2017.09.18 - -* \[*internal*\] Refactored `SerializableClosure::mapPointers` method -* \[*internal*\] Added a new optional argument to `SerializableClosure::unwrapClosures` -* \[*internal*\] Removed `SerializableClosure::getClosurePointer` method -* Fixed various bugs - -### v3.0.3, 2017.09.06 - -* Fixed a bug related to nested object references -* \[*internal*\] `Opis\Closure\ClosureScope` now extends `SplObjectStorage` -* \[*internal*\] The `storage` property was removed from `Opis\Closure\ClosureScope` -* \[*internal*\] The `instances` and `objects` properties were removed from `Opis\Closure\ClosureContext` - -### v3.0.2, 2017.08.28 - -* Fixed a bug where `$this` object was not handled properly inside the -`SerializableClosre::serialize` method. - -### v3.0.1, 2017.04.13 - -* Fixed a bug in 'ignore_next' state - -### v3.0.0, 2017.04.07 - -* Dropped PHP 5.3 support -* Moved source files from `lib` to `src` folder -* Removed second parameter from `Opis\Closure\SerializableClosure::from` method and from constructor -* Removed `Opis\Closure\{SecurityProviderInterface, DefaultSecurityProvider, SecureClosure}` classes -* Refactored how signed closures were handled -* Added `wrapClosures` and `unwrapClosures` static methods to `Opis\Closure\SerializableClosure` class -* Added `Opis\Colosure\serialize` and `Opis\Closure\unserialize` functions -* Improved serialization. You can now serialize arbitrary objects and the library will automatically wrap all closures - -### v2.4.0, 2016.12.16 - -* The parser was refactored and improved -* Refactored `Opis\Closure\SerializableClosure::__invoke` method -* `Opis\Closure\{ISecurityProvider, SecurityProvider}` were added -* `Opis\Closure\{SecurityProviderInterface, DefaultSecurityProvider, SecureClosure}` were deprecated -and they will be removed in the next major version -* `setSecretKey` and `addSecurityProvider` static methods were added to `Opis\Closure\SerializableClosure` - -### v2.3.2, 2016.12.15 - -* Fixed a bug that prevented namespace resolution to be done properly - -### v2.3.1, 2016.12.13 - -* Hotfix. See [PR](https://github.com/opis/closure/pull/7) - -### v2.3.0, 2016.11.17 - -* Added `isBindingRequired` and `isScopeRequired` to the `Opis\Closure\ReflectionClosure` class -* Automatically detects when the scope and/or the bound object of a closure needs to be serialized. - -### v2.2.1, 2016.08.20 - -* Fixed a bug in `Opis\Closure\ReflectionClosure::fetchItems` - -### v2.2.0, 2016.07.26 - -* Fixed CS -* `Opis\Closure\ClosureContext`, `Opis\Closure\ClosureScope`, `Opis\Closure\SelfReference` - and `Opis\Closure\SecurityException` classes were moved into separate files -* Added support for PHP7 syntax -* Fixed some bugs in `Opis\Closure\ReflectionClosure` class -* Improved closure parser -* Added an analyzer for SuperClosure library - -### v2.1.0, 2015.09.30 - -* Added support for the missing `__METHOD__`, `__FUNCTION__` and `__TRAIT__` magic constants -* Added some security related classes and interfaces: `Opis\Closure\SecurityProviderInterface`, -`Opis\Closure\DefaultSecurityProvider`, `Opis\Closure\SecureClosure`, `Opis\Closure\SecurityException`. -* Fiexed a bug in `Opis\Closure\ReflectionClosure::getClasses` method -* Other minor bugfixes -* Added support for static closures -* Added public `isStatic` method to `Opis\Closure\ReflectionClosure` class - - -### v2.0.1, 2015.09.23 - -* Removed `branch-alias` property from `composer.json` -* Bugfix. See [issue #6](https://github.com/opis/closure/issues/6) - -### v2.0.0, 2015.07.31 - -* The closure parser was improved -* Class names are now automatically resolved -* Added support for the `#trackme` directive which allows tracking closure's residing source - -### v1.3.0, 2014.10.18 - -* Added autoload file -* Changed README file - -### Opis Closure 1.2.2 - -* Started changelog diff --git a/vendor/opis/closure/LICENSE b/vendor/opis/closure/LICENSE deleted file mode 100644 index 9c0a19ba2..000000000 --- a/vendor/opis/closure/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2018-2019 Zindex Software - -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. diff --git a/vendor/opis/closure/NOTICE b/vendor/opis/closure/NOTICE deleted file mode 100644 index ae5caa628..000000000 --- a/vendor/opis/closure/NOTICE +++ /dev/null @@ -1,9 +0,0 @@ -Opis Closure -Copyright 2018-2019 Zindex Software - -This product includes software developed at -Zindex Software (http://zindex.software). - -This software was originally developed by Marius Sarca and Sorin Sarca -(Copyright 2014-2018). The copyright info was changed with the permission -of the original authors. \ No newline at end of file diff --git a/vendor/opis/closure/README.md b/vendor/opis/closure/README.md deleted file mode 100644 index 193380065..000000000 --- a/vendor/opis/closure/README.md +++ /dev/null @@ -1,92 +0,0 @@ -Opis Closure -==================== -[![Tests](https://github.com/opis/closure/workflows/Tests/badge.svg)](https://github.com/opis/closure/actions) -[![Latest Stable Version](https://poser.pugx.org/opis/closure/v/stable.png)](https://packagist.org/packages/opis/closure) -[![Latest Unstable Version](https://poser.pugx.org/opis/closure/v/unstable.png)](https://packagist.org/packages/opis/closure) -[![License](https://poser.pugx.org/opis/closure/license.png)](https://packagist.org/packages/opis/closure) - -Serializable closures ---------------------- -**Opis Closure** is a library that aims to overcome PHP's limitations regarding closure -serialization by providing a wrapper that will make all closures serializable. - -**The library's key features:** - -- Serialize any closure -- Serialize arbitrary objects -- Doesn't use `eval` for closure serialization or unserialization -- Works with any PHP version that has support for closures -- Supports PHP 7 syntax -- Handles all variables referenced/imported in `use()` and automatically wraps all referenced/imported closures for -proper serialization -- Handles recursive closures -- Handles magic constants like `__FILE__`, `__DIR__`, `__LINE__`, `__NAMESPACE__`, `__CLASS__`, -`__TRAIT__`, `__METHOD__` and `__FUNCTION__`. -- Automatically resolves all class names, function names and constant names used inside the closure -- Track closure's residing source by using the `#trackme` directive -- Simple and very fast parser -- Any error or exception, that might occur when executing an unserialized closure, can be caught and treated properly -- You can serialize/unserialize any closure unlimited times, even those previously unserialized -(this is possible because `eval()` is not used for unserialization) -- Handles static closures -- Supports cryptographically signed closures -- Provides a reflector that can give you information about the serialized closure -- Provides an analyzer for *SuperClosure* library -- Automatically detects when the scope and/or the bound object of a closure needs to be serialized -in order for the closure to work after deserialization - -## Documentation - -The full documentation for this library can be found [here][documentation]. - -## License - -**Opis Closure** is licensed under the [MIT License (MIT)][license]. - -## Requirements - -* PHP ^5.4 || ^7.0 - -## Installation - -**Opis Closure** is available on [Packagist] and it can be installed from a -command line interface by using [Composer]. - -```bash -composer require opis/closure -``` - -Or you could directly reference it into your `composer.json` file as a dependency - -```json -{ - "require": { - "opis/closure": "^3.5" - } -} -``` - -### Migrating from 2.x - -If your project needs to support PHP 5.3 you can continue using the `2.x` version -of **Opis Closure**. Otherwise, assuming you are not using one of the removed/refactored classes or features(see -[CHANGELOG]), migrating to version `3.x` is simply a matter of updating your `composer.json` file. - -### Semantic versioning - -**Opis Closure** follows [semantic versioning][SemVer] specifications. - -### Arbitrary object serialization - -We've added this feature in order to be able to support the serialization of a closure's bound object. -The implementation is far from being perfect, and it's really hard to make it work flawless. -We will try to improve this, but we can't guarantee anything. -So our advice regarding the `Opis\Closure\serialize|unserialize` functions is to use them with caution. - - -[documentation]: https://www.opis.io/closure "Opis Closure" -[license]: http://opensource.org/licenses/MIT "MIT License" -[Packagist]: https://packagist.org/packages/opis/closure "Packagist" -[Composer]: https://getcomposer.org "Composer" -[SemVer]: http://semver.org/ "Semantic versioning" -[CHANGELOG]: https://github.com/opis/closure/blob/master/CHANGELOG.md "Changelog" \ No newline at end of file diff --git a/vendor/opis/closure/autoload.php b/vendor/opis/closure/autoload.php deleted file mode 100644 index a928014fd..000000000 --- a/vendor/opis/closure/autoload.php +++ /dev/null @@ -1,39 +0,0 @@ -getClosureScopeClass(); - - $data = [ - 'reflection' => $reflection, - 'code' => $reflection->getCode(), - 'hasThis' => $reflection->isBindingRequired(), - 'context' => $reflection->getUseVariables(), - 'hasRefs' => false, - 'binding' => $reflection->getClosureThis(), - 'scope' => $scope ? $scope->getName() : null, - 'isStatic' => $reflection->isStatic(), - ]; - - return $data; - } - - /** - * @param array $data - * @return mixed - */ - protected function determineCode(array &$data) - { - return null; - } - - /** - * @param array $data - * @return mixed - */ - protected function determineContext(array &$data) - { - return null; - } - -} diff --git a/vendor/opis/closure/src/ClosureContext.php b/vendor/opis/closure/src/ClosureContext.php deleted file mode 100644 index d68cf9887..000000000 --- a/vendor/opis/closure/src/ClosureContext.php +++ /dev/null @@ -1,34 +0,0 @@ -scope = new ClosureScope(); - $this->locks = 0; - } -} \ No newline at end of file diff --git a/vendor/opis/closure/src/ClosureScope.php b/vendor/opis/closure/src/ClosureScope.php deleted file mode 100644 index 71ad4148f..000000000 --- a/vendor/opis/closure/src/ClosureScope.php +++ /dev/null @@ -1,25 +0,0 @@ -content = "length = strlen($this->content); - return true; - } - - public function stream_read($count) - { - $value = substr($this->content, $this->pointer, $count); - $this->pointer += $count; - return $value; - } - - public function stream_eof() - { - return $this->pointer >= $this->length; - } - - public function stream_set_option($option, $arg1, $arg2) - { - return false; - } - - public function stream_stat() - { - $stat = stat(__FILE__); - $stat[7] = $stat['size'] = $this->length; - return $stat; - } - - public function url_stat($path, $flags) - { - $stat = stat(__FILE__); - $stat[7] = $stat['size'] = $this->length; - return $stat; - } - - public function stream_seek($offset, $whence = SEEK_SET) - { - $crt = $this->pointer; - - switch ($whence) { - case SEEK_SET: - $this->pointer = $offset; - break; - case SEEK_CUR: - $this->pointer += $offset; - break; - case SEEK_END: - $this->pointer = $this->length + $offset; - break; - } - - if ($this->pointer < 0 || $this->pointer >= $this->length) { - $this->pointer = $crt; - return false; - } - - return true; - } - - public function stream_tell() - { - return $this->pointer; - } - - public static function register() - { - if (!static::$isRegistered) { - static::$isRegistered = stream_wrapper_register(static::STREAM_PROTO, __CLASS__); - } - } - -} diff --git a/vendor/opis/closure/src/ISecurityProvider.php b/vendor/opis/closure/src/ISecurityProvider.php deleted file mode 100644 index d3b0a2931..000000000 --- a/vendor/opis/closure/src/ISecurityProvider.php +++ /dev/null @@ -1,25 +0,0 @@ -code = $code; - parent::__construct($closure); - } - - /** - * @return bool - */ - public function isStatic() - { - if ($this->isStaticClosure === null) { - $this->isStaticClosure = strtolower(substr($this->getCode(), 0, 6)) === 'static'; - } - - return $this->isStaticClosure; - } - - public function isShortClosure() - { - if ($this->isShortClosure === null) { - $code = $this->getCode(); - if ($this->isStatic()) { - $code = substr($code, 6); - } - $this->isShortClosure = strtolower(substr(trim($code), 0, 2)) === 'fn'; - } - - return $this->isShortClosure; - } - - /** - * @return string - */ - public function getCode() - { - if($this->code !== null){ - return $this->code; - } - - $fileName = $this->getFileName(); - $line = $this->getStartLine() - 1; - - $match = ClosureStream::STREAM_PROTO . '://'; - - if ($line === 1 && substr($fileName, 0, strlen($match)) === $match) { - return $this->code = substr($fileName, strlen($match)); - } - - $className = null; - $fn = false; - - - if (null !== $className = $this->getClosureScopeClass()) { - $className = '\\' . trim($className->getName(), '\\'); - } - - - if($php7 = PHP_MAJOR_VERSION === 7){ - switch (PHP_MINOR_VERSION){ - case 0: - $php7_types = array('string', 'int', 'bool', 'float'); - break; - case 1: - $php7_types = array('string', 'int', 'bool', 'float', 'void'); - break; - case 2: - default: - $php7_types = array('string', 'int', 'bool', 'float', 'void', 'object'); - } - $fn = PHP_MINOR_VERSION === 4; - } - - $class_keywords = ['self', 'static', 'parent']; - - $ns = $this->getNamespaceName(); - $nsf = $ns == '' ? '' : ($ns[0] == '\\' ? $ns : '\\' . $ns); - - $_file = var_export($fileName, true); - $_dir = var_export(dirname($fileName), true); - $_namespace = var_export($ns, true); - $_class = var_export(trim($className, '\\'), true); - $_function = $ns . ($ns == '' ? '' : '\\') . '{closure}'; - $_method = ($className == '' ? '' : trim($className, '\\') . '::') . $_function; - $_function = var_export($_function, true); - $_method = var_export($_method, true); - $_trait = null; - - $tokens = $this->getTokens(); - $state = $lastState = 'start'; - $inside_structure = false; - $isShortClosure = false; - $inside_structure_mark = 0; - $open = 0; - $code = ''; - $id_start = $id_start_ci = $id_name = $context = ''; - $classes = $functions = $constants = null; - $use = array(); - $lineAdd = 0; - $isUsingScope = false; - $isUsingThisObject = false; - - for($i = 0, $l = count($tokens); $i < $l; $i++) { - $token = $tokens[$i]; - switch ($state) { - case 'start': - if ($token[0] === T_FUNCTION || $token[0] === T_STATIC) { - $code .= $token[1]; - $state = $token[0] === T_FUNCTION ? 'function' : 'static'; - } elseif ($fn && $token[0] === T_FN) { - $isShortClosure = true; - $code .= $token[1]; - $state = 'closure_args'; - } - break; - case 'static': - if ($token[0] === T_WHITESPACE || $token[0] === T_COMMENT || $token[0] === T_FUNCTION) { - $code .= $token[1]; - if ($token[0] === T_FUNCTION) { - $state = 'function'; - } - } elseif ($fn && $token[0] === T_FN) { - $isShortClosure = true; - $code .= $token[1]; - $state = 'closure_args'; - } else { - $code = ''; - $state = 'start'; - } - break; - case 'function': - switch ($token[0]){ - case T_STRING: - $code = ''; - $state = 'named_function'; - break; - case '(': - $code .= '('; - $state = 'closure_args'; - break; - default: - $code .= is_array($token) ? $token[1] : $token; - } - break; - case 'named_function': - if($token[0] === T_FUNCTION || $token[0] === T_STATIC){ - $code = $token[1]; - $state = $token[0] === T_FUNCTION ? 'function' : 'static'; - } elseif ($fn && $token[0] === T_FN) { - $isShortClosure = true; - $code .= $token[1]; - $state = 'closure_args'; - } - break; - case 'closure_args': - switch ($token[0]){ - case T_NS_SEPARATOR: - case T_STRING: - $id_start = $token[1]; - $id_start_ci = strtolower($id_start); - $id_name = ''; - $context = 'args'; - $state = 'id_name'; - $lastState = 'closure_args'; - break; - case T_USE: - $code .= $token[1]; - $state = 'use'; - break; - case T_DOUBLE_ARROW: - $code .= $token[1]; - if ($isShortClosure) { - $state = 'closure'; - } - break; - case ':': - $code .= ':'; - $state = 'return'; - break; - case '{': - $code .= '{'; - $state = 'closure'; - $open++; - break; - default: - $code .= is_array($token) ? $token[1] : $token; - } - break; - case 'use': - switch ($token[0]){ - case T_VARIABLE: - $use[] = substr($token[1], 1); - $code .= $token[1]; - break; - case '{': - $code .= '{'; - $state = 'closure'; - $open++; - break; - case ':': - $code .= ':'; - $state = 'return'; - break; - default: - $code .= is_array($token) ? $token[1] : $token; - break; - } - break; - case 'return': - switch ($token[0]){ - case T_WHITESPACE: - case T_COMMENT: - case T_DOC_COMMENT: - $code .= $token[1]; - break; - case T_NS_SEPARATOR: - case T_STRING: - $id_start = $token[1]; - $id_start_ci = strtolower($id_start); - $id_name = ''; - $context = 'return_type'; - $state = 'id_name'; - $lastState = 'return'; - break 2; - case T_DOUBLE_ARROW: - $code .= $token[1]; - if ($isShortClosure) { - $state = 'closure'; - } - break; - case '{': - $code .= '{'; - $state = 'closure'; - $open++; - break; - default: - $code .= is_array($token) ? $token[1] : $token; - break; - } - break; - case 'closure': - switch ($token[0]){ - case T_CURLY_OPEN: - case T_DOLLAR_OPEN_CURLY_BRACES: - case '{': - $code .= '{'; - $open++; - break; - case '}': - $code .= '}'; - if(--$open === 0 && !$isShortClosure){ - break 3; - } elseif ($inside_structure) { - $inside_structure = !($open === $inside_structure_mark); - } - break; - case '(': - case '[': - $code .= $token[0]; - if ($isShortClosure) { - $open++; - } - break; - case ')': - case ']': - if ($isShortClosure) { - if ($open === 0) { - break 3; - } - --$open; - } - $code .= $token[0]; - break; - case ',': - case ';': - if ($isShortClosure && $open === 0) { - break 3; - } - $code .= $token[0]; - break; - case T_LINE: - $code .= $token[2] - $line + $lineAdd; - break; - case T_FILE: - $code .= $_file; - break; - case T_DIR: - $code .= $_dir; - break; - case T_NS_C: - $code .= $_namespace; - break; - case T_CLASS_C: - $code .= $inside_structure ? $token[1] : $_class; - break; - case T_FUNC_C: - $code .= $inside_structure ? $token[1] : $_function; - break; - case T_METHOD_C: - $code .= $inside_structure ? $token[1] : $_method; - break; - case T_COMMENT: - if (substr($token[1], 0, 8) === '#trackme') { - $timestamp = time(); - $code .= '/**' . PHP_EOL; - $code .= '* Date : ' . date(DATE_W3C, $timestamp) . PHP_EOL; - $code .= '* Timestamp : ' . $timestamp . PHP_EOL; - $code .= '* Line : ' . ($line + 1) . PHP_EOL; - $code .= '* File : ' . $_file . PHP_EOL . '*/' . PHP_EOL; - $lineAdd += 5; - } else { - $code .= $token[1]; - } - break; - case T_VARIABLE: - if($token[1] == '$this' && !$inside_structure){ - $isUsingThisObject = true; - } - $code .= $token[1]; - break; - case T_STATIC: - case T_NS_SEPARATOR: - case T_STRING: - $id_start = $token[1]; - $id_start_ci = strtolower($id_start); - $id_name = ''; - $context = 'root'; - $state = 'id_name'; - $lastState = 'closure'; - break 2; - case T_NEW: - $code .= $token[1]; - $context = 'new'; - $state = 'id_start'; - $lastState = 'closure'; - break 2; - case T_USE: - $code .= $token[1]; - $context = 'use'; - $state = 'id_start'; - $lastState = 'closure'; - break; - case T_INSTANCEOF: - case T_INSTEADOF: - $code .= $token[1]; - $context = 'instanceof'; - $state = 'id_start'; - $lastState = 'closure'; - break; - case T_OBJECT_OPERATOR: - case T_DOUBLE_COLON: - $code .= $token[1]; - $lastState = 'closure'; - $state = 'ignore_next'; - break; - case T_FUNCTION: - $code .= $token[1]; - $state = 'closure_args'; - if (!$inside_structure) { - $inside_structure = true; - $inside_structure_mark = $open; - } - break; - case T_TRAIT_C: - if ($_trait === null) { - $startLine = $this->getStartLine(); - $endLine = $this->getEndLine(); - $structures = $this->getStructures(); - - $_trait = ''; - - foreach ($structures as &$struct) { - if ($struct['type'] === 'trait' && - $struct['start'] <= $startLine && - $struct['end'] >= $endLine - ) { - $_trait = ($ns == '' ? '' : $ns . '\\') . $struct['name']; - break; - } - } - - $_trait = var_export($_trait, true); - } - - $code .= $_trait; - break; - default: - $code .= is_array($token) ? $token[1] : $token; - } - break; - case 'ignore_next': - switch ($token[0]){ - case T_WHITESPACE: - case T_COMMENT: - case T_DOC_COMMENT: - $code .= $token[1]; - break; - case T_CLASS: - case T_NEW: - case T_STATIC: - case T_VARIABLE: - case T_STRING: - case T_CLASS_C: - case T_FILE: - case T_DIR: - case T_METHOD_C: - case T_FUNC_C: - case T_FUNCTION: - case T_INSTANCEOF: - case T_LINE: - case T_NS_C: - case T_TRAIT_C: - case T_USE: - $code .= $token[1]; - $state = $lastState; - break; - default: - $state = $lastState; - $i--; - } - break; - case 'id_start': - switch ($token[0]){ - case T_WHITESPACE: - case T_COMMENT: - case T_DOC_COMMENT: - $code .= $token[1]; - break; - case T_NS_SEPARATOR: - case T_STRING: - case T_STATIC: - $id_start = $token[1]; - $id_start_ci = strtolower($id_start); - $id_name = ''; - $state = 'id_name'; - break 2; - case T_VARIABLE: - $code .= $token[1]; - $state = $lastState; - break; - case T_CLASS: - $code .= $token[1]; - $state = 'anonymous'; - break; - default: - $i--;//reprocess last - $state = 'id_name'; - } - break; - case 'id_name': - switch ($token[0]){ - case T_NS_SEPARATOR: - case T_STRING: - $id_name .= $token[1]; - break; - case T_WHITESPACE: - case T_COMMENT: - case T_DOC_COMMENT: - $id_name .= $token[1]; - break; - case '(': - if ($isShortClosure) { - $open++; - } - if($context === 'new' || false !== strpos($id_name, '\\')){ - if($id_start_ci === 'self' || $id_start_ci === 'static') { - if (!$inside_structure) { - $isUsingScope = true; - } - } elseif ($id_start !== '\\' && !in_array($id_start_ci, $class_keywords)) { - if ($classes === null) { - $classes = $this->getClasses(); - } - if (isset($classes[$id_start_ci])) { - $id_start = $classes[$id_start_ci]; - } - if($id_start[0] !== '\\'){ - $id_start = $nsf . '\\' . $id_start; - } - } - } else { - if($id_start !== '\\'){ - if($functions === null){ - $functions = $this->getFunctions(); - } - if(isset($functions[$id_start_ci])){ - $id_start = $functions[$id_start_ci]; - } elseif ($nsf !== '\\' && function_exists($nsf . '\\' . $id_start)) { - $id_start = $nsf . '\\' . $id_start; - // Cache it to functions array - $functions[$id_start_ci] = $id_start; - } - } - } - $code .= $id_start . $id_name . '('; - $state = $lastState; - break; - case T_VARIABLE: - case T_DOUBLE_COLON: - if($id_start !== '\\') { - if($id_start_ci === 'self' || $id_start_ci === 'parent'){ - if (!$inside_structure) { - $isUsingScope = true; - } - } elseif ($id_start_ci === 'static') { - if (!$inside_structure) { - $isUsingScope = $token[0] === T_DOUBLE_COLON; - } - } elseif (!($php7 && in_array($id_start_ci, $php7_types))){ - if ($classes === null) { - $classes = $this->getClasses(); - } - if (isset($classes[$id_start_ci])) { - $id_start = $classes[$id_start_ci]; - } - if($id_start[0] !== '\\'){ - $id_start = $nsf . '\\' . $id_start; - } - } - } - - $code .= $id_start . $id_name . $token[1]; - $state = $token[0] === T_DOUBLE_COLON ? 'ignore_next' : $lastState; - break; - default: - if($id_start !== '\\' && !defined($id_start)){ - if($constants === null){ - $constants = $this->getConstants(); - } - if(isset($constants[$id_start])){ - $id_start = $constants[$id_start]; - } elseif($context === 'new'){ - if(in_array($id_start_ci, $class_keywords)) { - if (!$inside_structure) { - $isUsingScope = true; - } - } else { - if ($classes === null) { - $classes = $this->getClasses(); - } - if (isset($classes[$id_start_ci])) { - $id_start = $classes[$id_start_ci]; - } - if ($id_start[0] !== '\\') { - $id_start = $nsf . '\\' . $id_start; - } - } - } elseif($context === 'use' || - $context === 'instanceof' || - $context === 'args' || - $context === 'return_type' || - $context === 'extends' || - $context === 'root' - ){ - if(in_array($id_start_ci, $class_keywords)){ - if (!$inside_structure && !$id_start_ci === 'static') { - $isUsingScope = true; - } - } elseif (!($php7 && in_array($id_start_ci, $php7_types))){ - if($classes === null){ - $classes = $this->getClasses(); - } - if(isset($classes[$id_start_ci])){ - $id_start = $classes[$id_start_ci]; - } - if($id_start[0] !== '\\'){ - $id_start = $nsf . '\\' . $id_start; - } - } - } - } - $code .= $id_start . $id_name; - $state = $lastState; - $i--;//reprocess last token - } - break; - case 'anonymous': - switch ($token[0]) { - case T_NS_SEPARATOR: - case T_STRING: - $id_start = $token[1]; - $id_start_ci = strtolower($id_start); - $id_name = ''; - $state = 'id_name'; - $context = 'extends'; - $lastState = 'anonymous'; - break; - case '{': - $state = 'closure'; - if (!$inside_structure) { - $inside_structure = true; - $inside_structure_mark = $open; - } - $i--; - break; - default: - $code .= is_array($token) ? $token[1] : $token; - } - break; - } - } - - if ($isShortClosure) { - $this->useVariables = $this->getStaticVariables(); - } else { - $this->useVariables = empty($use) ? $use : array_intersect_key($this->getStaticVariables(), array_flip($use)); - } - - $this->isShortClosure = $isShortClosure; - $this->isBindingRequired = $isUsingThisObject; - $this->isScopeRequired = $isUsingScope; - $this->code = $code; - - return $this->code; - } - - /** - * @return array - */ - public function getUseVariables() - { - if($this->useVariables !== null){ - return $this->useVariables; - } - - $tokens = $this->getTokens(); - $use = array(); - $state = 'start'; - - foreach ($tokens as &$token) { - $is_array = is_array($token); - - switch ($state) { - case 'start': - if ($is_array && $token[0] === T_USE) { - $state = 'use'; - } - break; - case 'use': - if ($is_array) { - if ($token[0] === T_VARIABLE) { - $use[] = substr($token[1], 1); - } - } elseif ($token == ')') { - break 2; - } - break; - } - } - - $this->useVariables = empty($use) ? $use : array_intersect_key($this->getStaticVariables(), array_flip($use)); - - return $this->useVariables; - } - - /** - * return bool - */ - public function isBindingRequired() - { - if($this->isBindingRequired === null){ - $this->getCode(); - } - - return $this->isBindingRequired; - } - - /** - * return bool - */ - public function isScopeRequired() - { - if($this->isScopeRequired === null){ - $this->getCode(); - } - - return $this->isScopeRequired; - } - - /** - * @return string - */ - protected function getHashedFileName() - { - if ($this->hashedName === null) { - $this->hashedName = sha1($this->getFileName()); - } - - return $this->hashedName; - } - - /** - * @return array - */ - protected function getFileTokens() - { - $key = $this->getHashedFileName(); - - if (!isset(static::$files[$key])) { - static::$files[$key] = token_get_all(file_get_contents($this->getFileName())); - } - - return static::$files[$key]; - } - - /** - * @return array - */ - protected function getTokens() - { - if ($this->tokens === null) { - $tokens = $this->getFileTokens(); - $startLine = $this->getStartLine(); - $endLine = $this->getEndLine(); - $results = array(); - $start = false; - - foreach ($tokens as &$token) { - if (!is_array($token)) { - if ($start) { - $results[] = $token; - } - - continue; - } - - $line = $token[2]; - - if ($line <= $endLine) { - if ($line >= $startLine) { - $start = true; - $results[] = $token; - } - - continue; - } - - break; - } - - $this->tokens = $results; - } - - return $this->tokens; - } - - /** - * @return array - */ - protected function getClasses() - { - $key = $this->getHashedFileName(); - - if (!isset(static::$classes[$key])) { - $this->fetchItems(); - } - - return static::$classes[$key]; - } - - /** - * @return array - */ - protected function getFunctions() - { - $key = $this->getHashedFileName(); - - if (!isset(static::$functions[$key])) { - $this->fetchItems(); - } - - return static::$functions[$key]; - } - - /** - * @return array - */ - protected function getConstants() - { - $key = $this->getHashedFileName(); - - if (!isset(static::$constants[$key])) { - $this->fetchItems(); - } - - return static::$constants[$key]; - } - - /** - * @return array - */ - protected function getStructures() - { - $key = $this->getHashedFileName(); - - if (!isset(static::$structures[$key])) { - $this->fetchItems(); - } - - return static::$structures[$key]; - } - - protected function fetchItems() - { - $key = $this->getHashedFileName(); - - $classes = array(); - $functions = array(); - $constants = array(); - $structures = array(); - $tokens = $this->getFileTokens(); - - $open = 0; - $state = 'start'; - $lastState = ''; - $prefix = ''; - $name = ''; - $alias = ''; - $isFunc = $isConst = false; - - $startLine = $endLine = 0; - $structType = $structName = ''; - $structIgnore = false; - - foreach ($tokens as $token) { - - switch ($state) { - case 'start': - switch ($token[0]) { - case T_CLASS: - case T_INTERFACE: - case T_TRAIT: - $state = 'before_structure'; - $startLine = $token[2]; - $structType = $token[0] == T_CLASS - ? 'class' - : ($token[0] == T_INTERFACE ? 'interface' : 'trait'); - break; - case T_USE: - $state = 'use'; - $prefix = $name = $alias = ''; - $isFunc = $isConst = false; - break; - case T_FUNCTION: - $state = 'structure'; - $structIgnore = true; - break; - case T_NEW: - $state = 'new'; - break; - case T_OBJECT_OPERATOR: - case T_DOUBLE_COLON: - $state = 'invoke'; - break; - } - break; - case 'use': - switch ($token[0]) { - case T_FUNCTION: - $isFunc = true; - break; - case T_CONST: - $isConst = true; - break; - case T_NS_SEPARATOR: - $name .= $token[1]; - break; - case T_STRING: - $name .= $token[1]; - $alias = $token[1]; - break; - case T_AS: - $lastState = 'use'; - $state = 'alias'; - break; - case '{': - $prefix = $name; - $name = $alias = ''; - $state = 'use-group'; - break; - case ',': - case ';': - if ($name === '' || $name[0] !== '\\') { - $name = '\\' . $name; - } - - if ($alias !== '') { - if ($isFunc) { - $functions[strtolower($alias)] = $name; - } elseif ($isConst) { - $constants[$alias] = $name; - } else { - $classes[strtolower($alias)] = $name; - } - } - $name = $alias = ''; - $state = $token === ';' ? 'start' : 'use'; - break; - } - break; - case 'use-group': - switch ($token[0]) { - case T_NS_SEPARATOR: - $name .= $token[1]; - break; - case T_STRING: - $name .= $token[1]; - $alias = $token[1]; - break; - case T_AS: - $lastState = 'use-group'; - $state = 'alias'; - break; - case ',': - case '}': - - if ($prefix === '' || $prefix[0] !== '\\') { - $prefix = '\\' . $prefix; - } - - if ($alias !== '') { - if ($isFunc) { - $functions[strtolower($alias)] = $prefix . $name; - } elseif ($isConst) { - $constants[$alias] = $prefix . $name; - } else { - $classes[strtolower($alias)] = $prefix . $name; - } - } - $name = $alias = ''; - $state = $token === '}' ? 'use' : 'use-group'; - break; - } - break; - case 'alias': - if ($token[0] === T_STRING) { - $alias = $token[1]; - $state = $lastState; - } - break; - case 'new': - switch ($token[0]) { - case T_WHITESPACE: - case T_COMMENT: - case T_DOC_COMMENT: - break 2; - case T_CLASS: - $state = 'structure'; - $structIgnore = true; - break; - default: - $state = 'start'; - } - break; - case 'invoke': - switch ($token[0]) { - case T_WHITESPACE: - case T_COMMENT: - case T_DOC_COMMENT: - break 2; - default: - $state = 'start'; - } - break; - case 'before_structure': - if ($token[0] == T_STRING) { - $structName = $token[1]; - $state = 'structure'; - } - break; - case 'structure': - switch ($token[0]) { - case '{': - case T_CURLY_OPEN: - case T_DOLLAR_OPEN_CURLY_BRACES: - $open++; - break; - case '}': - if (--$open == 0) { - if(!$structIgnore){ - $structures[] = array( - 'type' => $structType, - 'name' => $structName, - 'start' => $startLine, - 'end' => $endLine, - ); - } - $structIgnore = false; - $state = 'start'; - } - break; - default: - if (is_array($token)) { - $endLine = $token[2]; - } - } - break; - } - } - - static::$classes[$key] = $classes; - static::$functions[$key] = $functions; - static::$constants[$key] = $constants; - static::$structures[$key] = $structures; - } -} diff --git a/vendor/opis/closure/src/SecurityException.php b/vendor/opis/closure/src/SecurityException.php deleted file mode 100644 index 6a107eec8..000000000 --- a/vendor/opis/closure/src/SecurityException.php +++ /dev/null @@ -1,18 +0,0 @@ -secret = $secret; - } - - /** - * @inheritdoc - */ - public function sign($closure) - { - return array( - 'closure' => $closure, - 'hash' => base64_encode(hash_hmac('sha256', $closure, $this->secret, true)), - ); - } - - /** - * @inheritdoc - */ - public function verify(array $data) - { - return base64_encode(hash_hmac('sha256', $data['closure'], $this->secret, true)) === $data['hash']; - } -} \ No newline at end of file diff --git a/vendor/opis/closure/src/SelfReference.php b/vendor/opis/closure/src/SelfReference.php deleted file mode 100644 index 3c6ec80dd..000000000 --- a/vendor/opis/closure/src/SelfReference.php +++ /dev/null @@ -1,31 +0,0 @@ -hash = $hash; - } -} \ No newline at end of file diff --git a/vendor/opis/closure/src/SerializableClosure.php b/vendor/opis/closure/src/SerializableClosure.php deleted file mode 100644 index f61c6aeae..000000000 --- a/vendor/opis/closure/src/SerializableClosure.php +++ /dev/null @@ -1,678 +0,0 @@ -closure = $closure; - if (static::$context !== null) { - $this->scope = static::$context->scope; - $this->scope->toserialize++; - } - } - - /** - * Get the Closure object - * - * @return Closure The wrapped closure - */ - public function getClosure() - { - return $this->closure; - } - - /** - * Get the reflector for closure - * - * @return ReflectionClosure - */ - public function getReflector() - { - if ($this->reflector === null) { - $this->reflector = new ReflectionClosure($this->closure, $this->code); - $this->code = null; - } - - return $this->reflector; - } - - /** - * Implementation of magic method __invoke() - */ - public function __invoke() - { - return call_user_func_array($this->closure, func_get_args()); - } - - /** - * Implementation of Serializable::serialize() - * - * @return string The serialized closure - */ - public function serialize() - { - if ($this->scope === null) { - $this->scope = new ClosureScope(); - $this->scope->toserialize++; - } - - $this->scope->serializations++; - - $scope = $object = null; - $reflector = $this->getReflector(); - - if($reflector->isBindingRequired()){ - $object = $reflector->getClosureThis(); - static::wrapClosures($object, $this->scope); - if($scope = $reflector->getClosureScopeClass()){ - $scope = $scope->name; - } - } else { - if($scope = $reflector->getClosureScopeClass()){ - $scope = $scope->name; - } - } - - $this->reference = spl_object_hash($this->closure); - - $this->scope[$this->closure] = $this; - - $use = $this->transformUseVariables($reflector->getUseVariables()); - $code = $reflector->getCode(); - - $this->mapByReference($use); - - $ret = \serialize(array( - 'use' => $use, - 'function' => $code, - 'scope' => $scope, - 'this' => $object, - 'self' => $this->reference, - )); - - if (static::$securityProvider !== null) { - $data = static::$securityProvider->sign($ret); - $ret = '@' . $data['hash'] . '.' . $data['closure']; - } - - if (!--$this->scope->serializations && !--$this->scope->toserialize) { - $this->scope = null; - } - - return $ret; - } - - /** - * Transform the use variables before serialization. - * - * @param array $data The Closure's use variables - * @return array - */ - protected function transformUseVariables($data) - { - return $data; - } - - /** - * Implementation of Serializable::unserialize() - * - * @param string $data Serialized data - * @throws SecurityException - */ - public function unserialize($data) - { - ClosureStream::register(); - - if (static::$securityProvider !== null) { - if ($data[0] !== '@') { - throw new SecurityException("The serialized closure is not signed. ". - "Make sure you use a security provider for both serialization and unserialization."); - } - - if ($data[1] !== '{') { - $separator = strpos($data, '.'); - if ($separator === false) { - throw new SecurityException('Invalid signed closure'); - } - $hash = substr($data, 1, $separator - 1); - $closure = substr($data, $separator + 1); - - $data = ['hash' => $hash, 'closure' => $closure]; - - unset($hash, $closure); - } else { - $data = json_decode(substr($data, 1), true); - } - - if (!is_array($data) || !static::$securityProvider->verify($data)) { - throw new SecurityException("Your serialized closure might have been modified and it's unsafe to be unserialized. " . - "Make sure you use the same security provider, with the same settings, " . - "both for serialization and unserialization."); - } - - $data = $data['closure']; - } elseif ($data[0] === '@') { - if ($data[1] !== '{') { - $separator = strpos($data, '.'); - if ($separator === false) { - throw new SecurityException('Invalid signed closure'); - } - $hash = substr($data, 1, $separator - 1); - $closure = substr($data, $separator + 1); - - $data = ['hash' => $hash, 'closure' => $closure]; - - unset($hash, $closure); - } else { - $data = json_decode(substr($data, 1), true); - } - - if (!is_array($data) || !isset($data['closure']) || !isset($data['hash'])) { - throw new SecurityException('Invalid signed closure'); - } - - $data = $data['closure']; - } - - $this->code = \unserialize($data); - - // unset data - unset($data); - - $this->code['objects'] = array(); - - if ($this->code['use']) { - $this->scope = new ClosureScope(); - $this->code['use'] = $this->resolveUseVariables($this->code['use']); - $this->mapPointers($this->code['use']); - extract($this->code['use'], EXTR_OVERWRITE | EXTR_REFS); - $this->scope = null; - } - - $this->closure = include(ClosureStream::STREAM_PROTO . '://' . $this->code['function']); - - if($this->code['this'] === $this){ - $this->code['this'] = null; - } - - $this->closure = $this->closure->bindTo($this->code['this'], $this->code['scope']); - - if(!empty($this->code['objects'])){ - foreach ($this->code['objects'] as $item){ - $item['property']->setValue($item['instance'], $item['object']->getClosure()); - } - } - - $this->code = $this->code['function']; - } - - /** - * Resolve the use variables after unserialization. - * - * @param array $data The Closure's transformed use variables - * @return array - */ - protected function resolveUseVariables($data) - { - return $data; - } - - /** - * Wraps a closure and sets the serialization context (if any) - * - * @param Closure $closure Closure to be wrapped - * - * @return self The wrapped closure - */ - public static function from(Closure $closure) - { - if (static::$context === null) { - $instance = new static($closure); - } elseif (isset(static::$context->scope[$closure])) { - $instance = static::$context->scope[$closure]; - } else { - $instance = new static($closure); - static::$context->scope[$closure] = $instance; - } - - return $instance; - } - - /** - * Increments the context lock counter or creates a new context if none exist - */ - public static function enterContext() - { - if (static::$context === null) { - static::$context = new ClosureContext(); - } - - static::$context->locks++; - } - - /** - * Decrements the context lock counter and destroy the context when it reaches to 0 - */ - public static function exitContext() - { - if (static::$context !== null && !--static::$context->locks) { - static::$context = null; - } - } - - /** - * @param string $secret - */ - public static function setSecretKey($secret) - { - if(static::$securityProvider === null){ - static::$securityProvider = new SecurityProvider($secret); - } - } - - /** - * @param ISecurityProvider $securityProvider - */ - public static function addSecurityProvider(ISecurityProvider $securityProvider) - { - static::$securityProvider = $securityProvider; - } - - /** - * Remove security provider - */ - public static function removeSecurityProvider() - { - static::$securityProvider = null; - } - - /** - * @return null|ISecurityProvider - */ - public static function getSecurityProvider() - { - return static::$securityProvider; - } - - /** - * Wrap closures - * - * @internal - * @param $data - * @param ClosureScope|SplObjectStorage|null $storage - */ - public static function wrapClosures(&$data, SplObjectStorage $storage = null) - { - if($storage === null){ - $storage = static::$context->scope; - } - - if($data instanceof Closure){ - $data = static::from($data); - } elseif (is_array($data)){ - if(isset($data[self::ARRAY_RECURSIVE_KEY])){ - return; - } - $data[self::ARRAY_RECURSIVE_KEY] = true; - foreach ($data as $key => &$value){ - if($key === self::ARRAY_RECURSIVE_KEY){ - continue; - } - static::wrapClosures($value, $storage); - } - unset($value); - unset($data[self::ARRAY_RECURSIVE_KEY]); - } elseif($data instanceof \stdClass){ - if(isset($storage[$data])){ - $data = $storage[$data]; - return; - } - $data = $storage[$data] = clone($data); - foreach ($data as &$value){ - static::wrapClosures($value, $storage); - } - unset($value); - } elseif (is_object($data) && ! $data instanceof static){ - if(isset($storage[$data])){ - $data = $storage[$data]; - return; - } - $instance = $data; - $reflection = new ReflectionObject($instance); - if(!$reflection->isUserDefined()){ - $storage[$instance] = $data; - return; - } - $storage[$instance] = $data = $reflection->newInstanceWithoutConstructor(); - - do{ - if(!$reflection->isUserDefined()){ - break; - } - foreach ($reflection->getProperties() as $property){ - if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ - continue; - } - $property->setAccessible(true); - if (PHP_VERSION >= 7.4 && !$property->isInitialized($instance)) { - continue; - } - $value = $property->getValue($instance); - if(is_array($value) || is_object($value)){ - static::wrapClosures($value, $storage); - } - $property->setValue($data, $value); - }; - } while($reflection = $reflection->getParentClass()); - } - } - - /** - * Unwrap closures - * - * @internal - * @param $data - * @param SplObjectStorage|null $storage - */ - public static function unwrapClosures(&$data, SplObjectStorage $storage = null) - { - if($storage === null){ - $storage = static::$context->scope; - } - - if($data instanceof static){ - $data = $data->getClosure(); - } elseif (is_array($data)){ - if(isset($data[self::ARRAY_RECURSIVE_KEY])){ - return; - } - $data[self::ARRAY_RECURSIVE_KEY] = true; - foreach ($data as $key => &$value){ - if($key === self::ARRAY_RECURSIVE_KEY){ - continue; - } - static::unwrapClosures($value, $storage); - } - unset($data[self::ARRAY_RECURSIVE_KEY]); - }elseif ($data instanceof \stdClass){ - if(isset($storage[$data])){ - return; - } - $storage[$data] = true; - foreach ($data as &$property){ - static::unwrapClosures($property, $storage); - } - } elseif (is_object($data) && !($data instanceof Closure)){ - if(isset($storage[$data])){ - return; - } - $storage[$data] = true; - $reflection = new ReflectionObject($data); - - do{ - if(!$reflection->isUserDefined()){ - break; - } - foreach ($reflection->getProperties() as $property){ - if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ - continue; - } - $property->setAccessible(true); - if (PHP_VERSION >= 7.4 && !$property->isInitialized($data)) { - continue; - } - $value = $property->getValue($data); - if(is_array($value) || is_object($value)){ - static::unwrapClosures($value, $storage); - $property->setValue($data, $value); - } - }; - } while($reflection = $reflection->getParentClass()); - } - } - - /** - * Creates a new closure from arbitrary code, - * emulating create_function, but without using eval - * - * @param string$args - * @param string $code - * @return Closure - */ - public static function createClosure($args, $code) - { - ClosureStream::register(); - return include(ClosureStream::STREAM_PROTO . '://function(' . $args. '){' . $code . '};'); - } - - /** - * Internal method used to map closure pointers - * @internal - * @param $data - */ - protected function mapPointers(&$data) - { - $scope = $this->scope; - - if ($data instanceof static) { - $data = &$data->closure; - } elseif (is_array($data)) { - if(isset($data[self::ARRAY_RECURSIVE_KEY])){ - return; - } - $data[self::ARRAY_RECURSIVE_KEY] = true; - foreach ($data as $key => &$value){ - if($key === self::ARRAY_RECURSIVE_KEY){ - continue; - } elseif ($value instanceof static) { - $data[$key] = &$value->closure; - } elseif ($value instanceof SelfReference && $value->hash === $this->code['self']){ - $data[$key] = &$this->closure; - } else { - $this->mapPointers($value); - } - } - unset($value); - unset($data[self::ARRAY_RECURSIVE_KEY]); - } elseif ($data instanceof \stdClass) { - if(isset($scope[$data])){ - return; - } - $scope[$data] = true; - foreach ($data as $key => &$value){ - if ($value instanceof SelfReference && $value->hash === $this->code['self']){ - $data->{$key} = &$this->closure; - } elseif(is_array($value) || is_object($value)) { - $this->mapPointers($value); - } - } - unset($value); - } elseif (is_object($data) && !($data instanceof Closure)){ - if(isset($scope[$data])){ - return; - } - $scope[$data] = true; - $reflection = new ReflectionObject($data); - do{ - if(!$reflection->isUserDefined()){ - break; - } - foreach ($reflection->getProperties() as $property){ - if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ - continue; - } - $property->setAccessible(true); - if (PHP_VERSION >= 7.4 && !$property->isInitialized($data)) { - continue; - } - $item = $property->getValue($data); - if ($item instanceof SerializableClosure || ($item instanceof SelfReference && $item->hash === $this->code['self'])) { - $this->code['objects'][] = array( - 'instance' => $data, - 'property' => $property, - 'object' => $item instanceof SelfReference ? $this : $item, - ); - } elseif (is_array($item) || is_object($item)) { - $this->mapPointers($item); - $property->setValue($data, $item); - } - } - } while($reflection = $reflection->getParentClass()); - } - } - - /** - * Internal method used to map closures by reference - * - * @internal - * @param mixed &$data - */ - protected function mapByReference(&$data) - { - if ($data instanceof Closure) { - if($data === $this->closure){ - $data = new SelfReference($this->reference); - return; - } - - if (isset($this->scope[$data])) { - $data = $this->scope[$data]; - return; - } - - $instance = new static($data); - - if (static::$context !== null) { - static::$context->scope->toserialize--; - } else { - $instance->scope = $this->scope; - } - - $data = $this->scope[$data] = $instance; - } elseif (is_array($data)) { - if(isset($data[self::ARRAY_RECURSIVE_KEY])){ - return; - } - $data[self::ARRAY_RECURSIVE_KEY] = true; - foreach ($data as $key => &$value){ - if($key === self::ARRAY_RECURSIVE_KEY){ - continue; - } - $this->mapByReference($value); - } - unset($value); - unset($data[self::ARRAY_RECURSIVE_KEY]); - } elseif ($data instanceof \stdClass) { - if(isset($this->scope[$data])){ - $data = $this->scope[$data]; - return; - } - $instance = $data; - $this->scope[$instance] = $data = clone($data); - - foreach ($data as &$value){ - $this->mapByReference($value); - } - unset($value); - } elseif (is_object($data) && !$data instanceof SerializableClosure){ - if(isset($this->scope[$data])){ - $data = $this->scope[$data]; - return; - } - - $instance = $data; - $reflection = new ReflectionObject($data); - if(!$reflection->isUserDefined()){ - $this->scope[$instance] = $data; - return; - } - $this->scope[$instance] = $data = $reflection->newInstanceWithoutConstructor(); - - do{ - if(!$reflection->isUserDefined()){ - break; - } - foreach ($reflection->getProperties() as $property){ - if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ - continue; - } - $property->setAccessible(true); - if (PHP_VERSION >= 7.4 && !$property->isInitialized($instance)) { - continue; - } - $value = $property->getValue($instance); - if(is_array($value) || is_object($value)){ - $this->mapByReference($value); - } - $property->setValue($data, $value); - } - } while($reflection = $reflection->getParentClass()); - } - } - -} diff --git a/vendor/services.php b/vendor/services.php index 22b1f2429..879bfdf24 100644 --- a/vendor/services.php +++ b/vendor/services.php @@ -1,5 +1,5 @@ 'think\\admin\\Library', diff --git a/vendor/topthink/framework/README.md b/vendor/topthink/framework/README.md index be0bb4e68..6bb78e9b9 100644 --- a/vendor/topthink/framework/README.md +++ b/vendor/topthink/framework/README.md @@ -13,7 +13,7 @@ ThinkPHP 6.0 ThinkPHP6.0底层架构采用PHP7.1改写和进一步优化。 -[官方应用服务市场](https://www.thinkphp.cn/service) | [`ThinkPHP`开发者扶持计划](https://sites.thinkphp.cn/1782366) +[官方应用服务市场](https://market.topthink.com) | [`ThinkPHP`开发者扶持计划](https://sites.thinkphp.cn/1782366) ## 主要新特性 diff --git a/vendor/topthink/framework/composer.json b/vendor/topthink/framework/composer.json index 1405162ee..9afc513a6 100644 --- a/vendor/topthink/framework/composer.json +++ b/vendor/topthink/framework/composer.json @@ -24,7 +24,6 @@ "ext-mbstring": "*", "league/flysystem": "^1.0", "league/flysystem-cached-adapter": "^1.0", - "opis/closure": "^3.1", "psr/log": "~1.0", "psr/container": "~1.0", "psr/simple-cache": "^1.0", diff --git a/vendor/topthink/framework/src/think/App.php b/vendor/topthink/framework/src/think/App.php index 094339501..c23a03c8a 100644 --- a/vendor/topthink/framework/src/think/App.php +++ b/vendor/topthink/framework/src/think/App.php @@ -39,7 +39,7 @@ use think\initializer\RegisterService; */ class App extends Container { - const VERSION = '6.0.3'; + const VERSION = '6.0.4'; /** * 应用调试模式 diff --git a/vendor/topthink/framework/src/think/Config.php b/vendor/topthink/framework/src/think/Config.php index 78933adca..3a1575555 100644 --- a/vendor/topthink/framework/src/think/Config.php +++ b/vendor/topthink/framework/src/think/Config.php @@ -116,6 +116,10 @@ class Config */ public function has(string $name): bool { + if (false === strpos($name, '.') && !isset($this->config[strtolower($name)])) { + return false; + } + return !is_null($this->get($name)); } diff --git a/vendor/topthink/framework/src/think/Console.php b/vendor/topthink/framework/src/think/Console.php index a1398d5d9..389d104d5 100644 --- a/vendor/topthink/framework/src/think/Console.php +++ b/vendor/topthink/framework/src/think/Console.php @@ -57,7 +57,7 @@ class Console protected $catchExceptions = true; protected $autoExit = true; protected $definition; - protected $defaultCommand = 'list'; + protected $defaultCommand = 'list'; protected $defaultCommands = [ 'help' => Help::class, @@ -91,9 +91,7 @@ class Console { $this->app = $app; - if (!$this->app->initialized()) { - $this->app->initialize(); - } + $this->initialize(); $this->definition = $this->getDefaultInputDefinition(); @@ -103,6 +101,63 @@ class Console $this->start(); } + /** + * 初始化 + */ + protected function initialize() + { + if (!$this->app->initialized()) { + $this->app->initialize(); + } + $this->makeRequest(); + } + + /** + * 构造request + */ + protected function makeRequest() + { + $uri = $this->app->config->get('app.url', 'http://localhost'); + + $components = parse_url($uri); + + $server = $_SERVER; + + if (isset($components['path'])) { + $server = array_merge($server, [ + 'SCRIPT_FILENAME' => $components['path'], + 'SCRIPT_NAME' => $components['path'], + ]); + } + + if (isset($components['host'])) { + $server['SERVER_NAME'] = $components['host']; + $server['HTTP_HOST'] = $components['host']; + } + + if (isset($components['scheme'])) { + if ('https' === $components['scheme']) { + $server['HTTPS'] = 'on'; + $server['SERVER_PORT'] = 443; + } else { + unset($server['HTTPS']); + $server['SERVER_PORT'] = 80; + } + } + + if (isset($components['port'])) { + $server['SERVER_PORT'] = $components['port']; + $server['HTTP_HOST'] .= ':' . $components['port']; + } + + $server['REQUEST_URI'] = $uri; + + /** @var Request $request */ + $request = $this->app->make('request'); + + $request->withServer($server); + } + /** * 添加初始化器 * @param Closure $callback @@ -161,7 +216,7 @@ class Console /** * @access public * @param string $command - * @param array $parameters + * @param array $parameters * @param string $driver * @return Output|Buffer */ @@ -226,7 +281,7 @@ class Console /** * 执行指令 * @access public - * @param Input $input + * @param Input $input * @param Output $output * @return int */ @@ -344,7 +399,7 @@ class Console * 添加一个指令 * @access public * @param string|Command $command 指令对象或者指令类名 - * @param string $name 指令名 留空则自动获取 + * @param string $name 指令名 留空则自动获取 * @return Command|void */ public function addCommand($command, string $name = '') @@ -462,7 +517,7 @@ class Console $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]) . '[^:]*'; }, $namespace); - $namespaces = preg_grep('{^' . $expr . '}', $allNamespaces); + $namespaces = preg_grep('{^' . $expr . '}', $allNamespaces); if (empty($namespaces)) { $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace); @@ -560,7 +615,7 @@ class Console /** * 配置基于用户的参数和选项的输入和输出实例。 * @access protected - * @param Input $input 输入实例 + * @param Input $input 输入实例 * @param Output $output 输出实例 */ protected function configureIO(Input $input, Output $output): void @@ -590,8 +645,8 @@ class Console * 执行指令 * @access protected * @param Command $command 指令实例 - * @param Input $input 输入实例 - * @param Output $output 输出实例 + * @param Input $input 输入实例 + * @param Output $output 输出实例 * @return int * @throws \Exception */ @@ -644,8 +699,8 @@ class Console /** * 返回命名空间部分 * @access public - * @param string $name 指令 - * @param int $limit 部分的命名空间的最大数量 + * @param string $name 指令 + * @param int $limit 部分的命名空间的最大数量 * @return string */ public function extractNamespace(string $name, int $limit = 0): string @@ -659,7 +714,7 @@ class Console /** * 查找可替代的建议 * @access private - * @param string $name + * @param string $name * @param array|\Traversable $collection * @return array */ diff --git a/vendor/topthink/framework/src/think/Container.php b/vendor/topthink/framework/src/think/Container.php index 215524f1e..7910bb3d6 100644 --- a/vendor/topthink/framework/src/think/Container.php +++ b/vendor/topthink/framework/src/think/Container.php @@ -152,8 +152,9 @@ class Container implements ContainerInterface, ArrayAccess, IteratorAggregate, C $this->instance($abstract, $concrete); } else { $abstract = $this->getAlias($abstract); - - $this->bind[$abstract] = $concrete; + if ($abstract != $concrete) { + $this->bind[$abstract] = $concrete; + } } return $this; @@ -445,9 +446,9 @@ class Container implements ContainerInterface, ArrayAccess, IteratorAggregate, C $args[] = $this->getObjectParam($class->getName(), $vars); } elseif (1 == $type && !empty($vars)) { $args[] = array_shift($vars); - } elseif (0 == $type && isset($vars[$name])) { + } elseif (0 == $type && array_key_exists($name, $vars)) { $args[] = $vars[$name]; - } elseif (0 == $type && isset($vars[$lowerName])) { + } elseif (0 == $type && array_key_exists($lowerName, $vars)) { $args[] = $vars[$lowerName]; } elseif ($param->isDefaultValueAvailable()) { $args[] = $param->getDefaultValue(); diff --git a/vendor/topthink/framework/src/think/Http.php b/vendor/topthink/framework/src/think/Http.php index 6de30b597..4bc632c4f 100644 --- a/vendor/topthink/framework/src/think/Http.php +++ b/vendor/topthink/framework/src/think/Http.php @@ -42,6 +42,12 @@ class Http */ protected $path; + /** + * 路由路径 + * @var string + */ + protected $routePath; + /** * 是否绑定应用 * @var bool @@ -117,7 +123,6 @@ class Http * 设置路由目录 * @access public * @param string $path 路由定义目录 - * @return string */ public function setRoutePath(string $path): void { @@ -154,6 +159,9 @@ class Http */ public function run(Request $request = null): Response { + //初始化 + $this->initialize(); + //自动创建request对象 $request = $request ?? $this->app->make('request', [], true); $this->app->instance('request', $request); @@ -186,8 +194,6 @@ class Http */ protected function runWithRequest(Request $request) { - $this->initialize(); - // 加载全局中间件 $this->loadMiddleware(); diff --git a/vendor/topthink/framework/src/think/Lang.php b/vendor/topthink/framework/src/think/Lang.php index be27f5e74..d811ea715 100644 --- a/vendor/topthink/framework/src/think/Lang.php +++ b/vendor/topthink/framework/src/think/Lang.php @@ -153,6 +153,18 @@ class Lang if (function_exists('yaml_parse_file')) { $result = yaml_parse_file($file); } + break; + case 'json': + $data = file_get_contents($file); + + if($data !== false) { + $data = json_decode($data, true); + + if(json_last_error() === JSON_ERROR_NONE) { + $result = $data; + } + } + break; } diff --git a/vendor/topthink/framework/src/think/Route.php b/vendor/topthink/framework/src/think/Route.php index e3be55da9..a8b9718de 100644 --- a/vendor/topthink/framework/src/think/Route.php +++ b/vendor/topthink/framework/src/think/Route.php @@ -165,12 +165,12 @@ class Route // 读取路由映射文件 $this->import(include $this->app->getRuntimePath() . 'route.php'); } + + $this->config = array_merge($this->config, $this->app->config->get('route')); } protected function init() { - $this->config = array_merge($this->config, $this->app->config->get('route')); - if (!empty($this->config['middleware'])) { $this->app->middleware->import($this->config['middleware'], 'route'); } @@ -423,7 +423,7 @@ class Route * @param string $name 路由标识 * @param string $domain 域名 * @param string $method 请求类型 - * @return RuleItem[] + * @return array */ public function getName(string $name = null, string $domain = null, string $method = '*'): array { @@ -681,6 +681,18 @@ class Route public function redirect(string $rule, string $route = '', int $status = 301): RuleItem { return $this->rule($rule, function () use ($status, $route) { + $search = $replace = []; + $matches = $this->request->rule()->getVars(); + + foreach ($matches as $key => $value) { + $search[] = '<' . $key . '>'; + $replace[] = $value; + + $search[] = ':' . $key; + $replace[] = $value; + } + + $route = str_replace($search, $replace, $route); return Response::create($route, 'redirect')->code($status); }, '*'); } diff --git a/vendor/topthink/framework/src/think/Validate.php b/vendor/topthink/framework/src/think/Validate.php index 42e64e381..801a69af7 100644 --- a/vendor/topthink/framework/src/think/Validate.php +++ b/vendor/topthink/framework/src/think/Validate.php @@ -605,6 +605,7 @@ class Validate if (isset($this->append[$field])) { // 追加额外的验证规则 $rules = array_unique(array_merge($rules, $this->append[$field]), SORT_REGULAR); + unset($this->append[$field]); } if (empty($rules)) { @@ -663,7 +664,7 @@ class Validate $i++; } - return $result; + return $result ?? true; } /** diff --git a/vendor/topthink/framework/src/think/cache/driver/Redis.php b/vendor/topthink/framework/src/think/cache/driver/Redis.php index 487f66ba3..151b37c61 100644 --- a/vendor/topthink/framework/src/think/cache/driver/Redis.php +++ b/vendor/topthink/framework/src/think/cache/driver/Redis.php @@ -87,7 +87,7 @@ class Redis extends Driver } if (0 != $this->options['select']) { - $this->handler->select($this->options['select']); + $this->handler->select( (int) $this->options['select']); } } diff --git a/vendor/topthink/framework/src/think/console/command/make/stubs/command.stub b/vendor/topthink/framework/src/think/console/command/make/stubs/command.stub index e9121cdd7..3ee2b1cf9 100644 --- a/vendor/topthink/framework/src/think/console/command/make/stubs/command.stub +++ b/vendor/topthink/framework/src/think/console/command/make/stubs/command.stub @@ -15,12 +15,12 @@ class {%className%} extends Command { // 指令配置 $this->setName('{%commandName%}') - ->setDescription('the {%commandName%} command'); + ->setDescription('the {%commandName%} command'); } protected function execute(Input $input, Output $output) { - // 指令输出 - $output->writeln('{%commandName%}'); + // 指令输出 + $output->writeln('{%commandName%}'); } } diff --git a/vendor/topthink/framework/src/think/console/command/make/stubs/listener.stub b/vendor/topthink/framework/src/think/console/command/make/stubs/listener.stub index d55e7c4ed..03724380b 100644 --- a/vendor/topthink/framework/src/think/console/command/make/stubs/listener.stub +++ b/vendor/topthink/framework/src/think/console/command/make/stubs/listener.stub @@ -13,5 +13,5 @@ class {%className%} public function handle($event) { // - } + } } diff --git a/vendor/topthink/framework/src/think/console/command/make/stubs/service.stub b/vendor/topthink/framework/src/think/console/command/make/stubs/service.stub index 6ec93fe84..5d74d15c1 100644 --- a/vendor/topthink/framework/src/think/console/command/make/stubs/service.stub +++ b/vendor/topthink/framework/src/think/console/command/make/stubs/service.stub @@ -3,9 +3,8 @@ declare (strict_types = 1); namespace {%namespace%}; -class {%className%} extends \think\Service +class {%className%} extends \think\Service { - /** * 注册服务 * @@ -16,7 +15,6 @@ class {%className%} extends \think\Service // } - /** * 执行服务 * diff --git a/vendor/topthink/framework/src/think/console/command/make/stubs/validate.stub b/vendor/topthink/framework/src/think/console/command/make/stubs/validate.stub index b59697970..d1fedd8d6 100644 --- a/vendor/topthink/framework/src/think/console/command/make/stubs/validate.stub +++ b/vendor/topthink/framework/src/think/console/command/make/stubs/validate.stub @@ -9,17 +9,17 @@ class {%className%} extends Validate { /** * 定义验证规则 - * 格式:'字段名' => ['规则1','规则2'...] + * 格式:'字段名' => ['规则1','规则2'...] * * @var array - */ - protected $rule = []; - + */ + protected $rule = []; + /** * 定义错误信息 - * 格式:'字段名.规则名' => '错误信息' + * 格式:'字段名.规则名' => '错误信息' * * @var array - */ + */ protected $message = []; } diff --git a/vendor/topthink/framework/src/think/console/command/optimize/Route.php b/vendor/topthink/framework/src/think/console/command/optimize/Route.php index bd4f79c15..56f7f5a9b 100644 --- a/vendor/topthink/framework/src/think/console/command/optimize/Route.php +++ b/vendor/topthink/framework/src/think/console/command/optimize/Route.php @@ -46,7 +46,7 @@ class Route extends Command $this->app->route->lazy(false); // 路由检测 - $path = $this->app->getRootPath() . ($dir ? 'app' . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR : '') . 'route' . DIRECTORY_SEPARATOR ; + $path = $this->app->getRootPath() . ($dir ? 'app' . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR : '') . 'route' . DIRECTORY_SEPARATOR; $files = is_dir($path) ? scandir($path) : []; @@ -58,10 +58,9 @@ class Route extends Command //触发路由载入完成事件 $this->app->event->trigger(RouteLoaded::class); + $rules = $this->app->route->getName(); - $content = 'app->route->getName()) . '\');'; - return $content; + return 'isGet() && false !== $cache) { - $cache = $cache ?: $this->getRequestCache($request); + if (false === $this->config['request_cache_key']) { + // 关闭当前缓存 + $cache = false; + } + + $cache = $cache ?? $this->getRequestCache($request); if ($cache) { if (is_array($cache)) { - [$key, $expire, $tag] = $cache; + [$key, $expire, $tag] = array_pad($cache, 3, null); } else { - $key = str_replace('|', '/', $request->url()); + $key = md5($request->url(true)); $expire = $cache; $tag = null; } + $key = $this->parseCacheKey($request, $key); + if (strtotime($request->server('HTTP_IF_MODIFIED_SINCE', '')) + $expire > $request->server('REQUEST_TIME')) { // 读取缓存 return Response::create()->code(304); @@ -111,6 +118,24 @@ class CheckRequestCache $except = $this->config['request_cache_except']; $tag = $this->config['request_cache_tag']; + foreach ($except as $rule) { + if (0 === stripos($request->url(), $rule)) { + return; + } + } + + return [$key, $expire, $tag]; + } + + /** + * 读取当前地址的请求缓存信息 + * @access protected + * @param Request $request + * @param mixed $key + * @return null|string + */ + protected function parseCacheKey($request, $key) + { if ($key instanceof \Closure) { $key = call_user_func($key, $request); } @@ -120,12 +145,6 @@ class CheckRequestCache return; } - foreach ($except as $rule) { - if (0 === stripos($request->url(), $rule)) { - return; - } - } - if (true === $key) { // 自动缓存功能 $key = '__URL__'; @@ -140,6 +159,7 @@ class CheckRequestCache if (false !== strpos($key, ':')) { $param = $request->param(); + foreach ($param as $item => $val) { if (is_string($val) && false !== strpos($key, ':' . $item)) { $key = str_replace(':' . $item, $val, $key); @@ -158,6 +178,6 @@ class CheckRequestCache $key = $fun($key); } - return [$key, $expire, $tag]; + return $key; } } diff --git a/vendor/topthink/framework/src/think/route/Rule.php b/vendor/topthink/framework/src/think/route/Rule.php index 05213934c..df99fe9de 100644 --- a/vendor/topthink/framework/src/think/route/Rule.php +++ b/vendor/topthink/framework/src/think/route/Rule.php @@ -237,11 +237,17 @@ abstract class Rule */ public function getPattern(string $name = '') { - if ('' === $name) { - return $this->pattern; + $pattern = $this->pattern; + + if ($this->parent) { + $pattern = array_merge($this->parent->getPattern(), $pattern); } - return $this->pattern[$name] ?? null; + if ('' === $name) { + return $pattern; + } + + return $pattern[$name] ?? null; } /** @@ -253,11 +259,26 @@ abstract class Rule */ public function getOption(string $name = '', $default = null) { - if ('' === $name) { - return $this->option; + $option = $this->option; + + if ($this->parent) { + $parentOption = $this->parent->getOption(); + + // 合并分组参数 + foreach ($this->mergeOptions as $item) { + if (isset($parentOption[$item]) && isset($option[$item])) { + $option[$item] = array_merge($parentOption[$item], $option[$item]); + } + } + + $option = array_merge($parentOption, $option); } - return $this->option[$name] ?? $default; + if ('' === $name) { + return $option; + } + + return $option[$name] ?? $default; } /** @@ -551,26 +572,6 @@ abstract class Rule return $this; } - /** - * 合并分组参数 - * @access public - * @return array - */ - public function mergeGroupOptions(): array - { - $parentOption = $this->parent->getOption(); - // 合并分组参数 - foreach ($this->mergeOptions as $item) { - if (isset($parentOption[$item]) && isset($this->option[$item])) { - $this->option[$item] = array_merge($parentOption[$item], $this->option[$item]); - } - } - - $this->option = array_merge($parentOption, $this->option); - - return $this->option; - } - /** * 解析匹配到的规则路由 * @access public @@ -590,24 +591,31 @@ abstract class Rule } // 替换路由地址中的变量 - if (is_string($route) && !empty($matches)) { - $search = $replace = []; + $extraParams = true; + $search = $replace = []; + $depr = $this->router->config('pathinfo_depr'); + foreach ($matches as $key => $value) { + $search[] = '<' . $key . '>'; + $replace[] = $value; - foreach ($matches as $key => $value) { - $search[] = '<' . $key . '>'; - $replace[] = $value; + $search[] = ':' . $key; + $replace[] = $value; - $search[] = ':' . $key; - $replace[] = $value; + if (strpos($value, $depr)) { + $extraParams = false; } + } + if (is_string($route)) { $route = str_replace($search, $replace, $route); } // 解析额外参数 - $count = substr_count($rule, '/'); - $url = array_slice(explode('|', $url), $count + 1); - $this->parseUrlParams(implode('|', $url), $matches); + if ($extraParams) { + $count = substr_count($rule, '/'); + $url = array_slice(explode('|', $url), $count + 1); + $this->parseUrlParams(implode('|', $url), $matches); + } $this->vars = $matches; @@ -630,7 +638,7 @@ abstract class Rule } elseif ($route instanceof Closure) { // 执行闭包 $result = new CallbackDispatch($request, $this, $route, $this->vars); - } elseif (false !== strpos($route, '@') || false !== strpos($route, '::')) { + } elseif (false !== strpos($route, '@') || false !== strpos($route, '::') || false !== strpos($route, '\\')) { // 路由到类的方法 $route = str_replace('::', '@', $route); $result = $this->dispatchMethod($request, $route); diff --git a/vendor/topthink/framework/src/think/route/RuleGroup.php b/vendor/topthink/framework/src/think/route/RuleGroup.php index 3d5e9bc82..94bf2b982 100644 --- a/vendor/topthink/framework/src/think/route/RuleGroup.php +++ b/vendor/topthink/framework/src/think/route/RuleGroup.php @@ -147,19 +147,13 @@ class RuleGroup extends Rule // 获取当前路由规则 $method = strtolower($request->method()); $rules = $this->getRules($method); + $option = $this->getOption(); - if ($this->parent) { - // 合并分组参数 - $this->mergeGroupOptions(); - // 合并分组变量规则 - $this->pattern = array_merge($this->parent->getPattern(), $this->pattern); + if (isset($option['complete_match'])) { + $completeMatch = $option['complete_match']; } - if (isset($this->option['complete_match'])) { - $completeMatch = $this->option['complete_match']; - } - - if (!empty($this->option['merge_rule_regex'])) { + if (!empty($option['merge_rule_regex'])) { // 合并路由正则规则进行路由匹配检查 $result = $this->checkMergeRuleRegex($request, $rules, $url, $completeMatch); @@ -179,7 +173,7 @@ class RuleGroup extends Rule if ($this->miss && in_array($this->miss->getMethod(), ['*', $method])) { // 未匹配所有路由的路由规则处理 - $result = $this->parseRule($request, '', $this->miss->getRoute(), $url, $this->miss->mergeGroupOptions()); + $result = $this->parseRule($request, '', $this->miss->getRoute(), $url, $this->miss->getOption()); } else { $result = false; } @@ -495,7 +489,7 @@ class RuleGroup extends Rule } return array_filter($this->rules, function ($item) use ($method) { - return $method == $item[0] || $item[0] == '*'; + return $method == $item[0] || '*' == $item[0]; }); } diff --git a/vendor/topthink/framework/src/think/route/RuleItem.php b/vendor/topthink/framework/src/think/route/RuleItem.php index f7f72ba1f..3ca4885eb 100644 --- a/vendor/topthink/framework/src/think/route/RuleItem.php +++ b/vendor/topthink/framework/src/think/route/RuleItem.php @@ -191,12 +191,12 @@ class RuleItem extends Rule } // 合并分组参数 - $option = $this->mergeGroupOptions(); - - $url = $this->urlSuffixCheck($request, $url, $option); + $option = $this->getOption(); + $pattern = $this->getPattern(); + $url = $this->urlSuffixCheck($request, $url, $option); if (is_null($match)) { - $match = $this->match($url, $option, $completeMatch); + $match = $this->match($url, $option, $pattern, $completeMatch); } if (false !== $match) { @@ -248,17 +248,17 @@ class RuleItem extends Rule * @access private * @param string $url URL地址 * @param array $option 路由参数 - * @param bool $completeMatch 路由是否完全匹配 + * @param array $pattern 变量规则 + * @param bool $completeMatch 是否完全匹配 * @return array|false */ - private function match(string $url, array $option, bool $completeMatch) + private function match(string $url, array $option, array $pattern, bool $completeMatch) { if (isset($option['complete_match'])) { $completeMatch = $option['complete_match']; } - $depr = $this->router->config('pathinfo_depr'); - $pattern = array_merge($this->parent->getPattern(), $this->pattern); + $depr = $this->router->config('pathinfo_depr'); // 检查完整规则定义 if (isset($pattern['__url__']) && !preg_match(0 === strpos($pattern['__url__'], '/') ? $pattern['__url__'] : '/^' . $pattern['__url__'] . ($completeMatch ? '$' : '') . '/', str_replace('|', $depr, $url))) { diff --git a/vendor/topthink/framework/src/think/route/RuleName.php b/vendor/topthink/framework/src/think/route/RuleName.php index 9b1088aed..5ddc7a7b6 100644 --- a/vendor/topthink/framework/src/think/route/RuleName.php +++ b/vendor/topthink/framework/src/think/route/RuleName.php @@ -46,10 +46,11 @@ class RuleName public function setName(string $name, RuleItem $ruleItem, bool $first = false): void { $name = strtolower($name); + $item = $this->getRuleItemInfo($ruleItem); if ($first && isset($this->item[$name])) { - array_unshift($this->item[$name], $ruleItem); + array_unshift($this->item[$name], $item); } else { - $this->item[$name][] = $ruleItem; + $this->item[$name][] = $item; } } @@ -179,8 +180,8 @@ class RuleName $result = $this->item[$name]; } else { foreach ($this->item[$name] as $item) { - $itemDomain = $item->getDomain(); - $itemMethod = $item->getMethod(); + $itemDomain = $item['domain']; + $itemMethod = $item['method']; if (($itemDomain == $domain || '-' == $itemDomain) && ('*' == $itemMethod || '*' == $method || $method == $itemMethod)) { $result[] = $item; @@ -192,4 +193,19 @@ class RuleName return $result; } + /** + * 获取路由信息 + * @access protected + * @param RuleItem $item 路由规则 + * @return array + */ + protected function getRuleItemInfo(RuleItem $item): array + { + return [ + 'rule' => $item->getRule(), + 'domain' => $item->getDomain(), + 'method' => $item->getMethod(), + 'suffix' => $item->getSuffix(), + ]; + } } diff --git a/vendor/topthink/framework/src/think/route/Url.php b/vendor/topthink/framework/src/think/route/Url.php index d0d808b25..270439edb 100644 --- a/vendor/topthink/framework/src/think/route/Url.php +++ b/vendor/topthink/framework/src/think/route/Url.php @@ -302,10 +302,10 @@ class Url $port = $request->port(); foreach ($rule as $item) { - $url = $item->getRule(); + $url = $item['rule']; $pattern = $this->parseVar($url); - $domain = $item->getDomain(); - $suffix = $item->getSuffix(); + $domain = $item['domain']; + $suffix = $item['suffix']; if ('-' == $domain) { $domain = is_string($allowDomain) ? $allowDomain : $request->host(true); diff --git a/vendor/topthink/framework/src/think/session/driver/File.php b/vendor/topthink/framework/src/think/session/driver/File.php index 991f2cc93..258458a6a 100644 --- a/vendor/topthink/framework/src/think/session/driver/File.php +++ b/vendor/topthink/framework/src/think/session/driver/File.php @@ -39,7 +39,7 @@ class File implements SessionHandlerInterface $this->config = array_merge($this->config, $config); if (empty($this->config['path'])) { - $this->config['path'] = $app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . 'session' . DIRECTORY_SEPARATOR; + $this->config['path'] = $app->getRuntimePath() . 'session' . DIRECTORY_SEPARATOR; } elseif (substr($this->config['path'], -1) != DIRECTORY_SEPARATOR) { $this->config['path'] .= DIRECTORY_SEPARATOR; } diff --git a/vendor/topthink/framework/tests/ContainerTest.php b/vendor/topthink/framework/tests/ContainerTest.php index 72ff1d071..e27deb088 100644 --- a/vendor/topthink/framework/tests/ContainerTest.php +++ b/vendor/topthink/framework/tests/ContainerTest.php @@ -149,6 +149,7 @@ class ContainerTest extends TestCase $container->bind('name2', $object); + $container->bind('name3', Taylor::class); $container->bind('name3', Taylor::class); $container->name4 = $object; diff --git a/vendor/topthink/framework/tests/HttpTest.php b/vendor/topthink/framework/tests/HttpTest.php index 8b6f28fd6..c3e0abd33 100644 --- a/vendor/topthink/framework/tests/HttpTest.php +++ b/vendor/topthink/framework/tests/HttpTest.php @@ -123,6 +123,7 @@ class HttpTest extends TestCase $response = m::mock(Response::class); $this->app->shouldReceive('instance')->once()->with('request', $request); + $this->app->shouldReceive('initialize')->once(); $exception = new Exception(); diff --git a/vendor/topthink/think-orm/src/db/PDOConnection.php b/vendor/topthink/think-orm/src/db/PDOConnection.php index 540f13536..e8a1dbf49 100644 --- a/vendor/topthink/think-orm/src/db/PDOConnection.php +++ b/vendor/topthink/think-orm/src/db/PDOConnection.php @@ -203,7 +203,7 @@ abstract class PDOConnection extends Connection * @param array $config 连接信息 * @return string */ - abstract protected function parseDsn(array $config); + abstract protected function parseDsn(array $config): string; /** * 取得数据表的字段信息 @@ -211,7 +211,7 @@ abstract class PDOConnection extends Connection * @param string $tableName 数据表名称 * @return array */ - abstract public function getFields(string $tableName); + abstract public function getFields(string $tableName): array; /** * 取得数据库的表信息 @@ -219,7 +219,7 @@ abstract class PDOConnection extends Connection * @param string $dbName 数据库名称 * @return array */ - abstract public function getTables(string $dbName); + abstract public function getTables(string $dbName = ''): array; /** * 对返数据表字段信息进行大小写转换出来 @@ -728,16 +728,13 @@ abstract class PDOConnection extends Connection */ public function getPDOStatement(string $sql, array $bind = [], bool $master = false, bool $procedure = false): PDOStatement { - $this->initConnect($this->readMaster ?: $master); - - // 记录SQL语句 - $this->queryStr = $sql; - - $this->bind = $bind; - - $this->db->updateQueryTimes(); - try { + $this->initConnect($this->readMaster ?: $master); + // 记录SQL语句 + $this->queryStr = $sql; + $this->bind = $bind; + + $this->db->updateQueryTimes(); $this->queryStartTime = microtime(true); // 预处理 @@ -1394,11 +1391,11 @@ abstract class PDOConnection extends Connection */ public function startTrans(): void { - $this->initConnect(true); - - ++$this->transTimes; - try { + $this->initConnect(true); + + ++$this->transTimes; + if (1 == $this->transTimes) { $this->linkID->beginTransaction(); } elseif ($this->transTimes > 1 && $this->supportSavepoint()) { @@ -1412,8 +1409,9 @@ abstract class PDOConnection extends Connection --$this->transTimes; ++$this->reConnectTimes; $this->close()->startTrans(); + } else { + throw $e; } - throw $e; } } diff --git a/vendor/topthink/think-orm/src/db/concern/WhereQuery.php b/vendor/topthink/think-orm/src/db/concern/WhereQuery.php index 62dc98366..a95c69758 100644 --- a/vendor/topthink/think-orm/src/db/concern/WhereQuery.php +++ b/vendor/topthink/think-orm/src/db/concern/WhereQuery.php @@ -378,7 +378,7 @@ trait WhereQuery } elseif (is_string($field)) { if (preg_match('/[,=\<\'\"\(\s]/', $field)) { return $this->whereRaw($field, is_array($op) ? $op : [], $logic); - } elseif (is_string($op) && strtolower($op) == 'exp') { + } elseif (is_string($op) && strtolower($op) == 'exp' && !is_null($condition)) { $bind = isset($param[2]) && is_array($param[2]) ? $param[2] : []; return $this->whereExp($field, $condition, $bind, $logic); } @@ -514,17 +514,9 @@ trait WhereQuery } if ($condition) { - if ($query instanceof Closure) { - $query($this, $condition); - } elseif (is_array($query)) { - $this->where($query); - } + $this->where($query); } elseif ($otherwise) { - if ($otherwise instanceof Closure) { - $otherwise($this, $condition); - } elseif (is_array($otherwise)) { - $this->where($otherwise); - } + $this->where($otherwise); } return $this; diff --git a/vendor/topthink/think-orm/src/db/exception/DbException.php b/vendor/topthink/think-orm/src/db/exception/DbException.php index d5bfc3f04..7d1deaadf 100644 --- a/vendor/topthink/think-orm/src/db/exception/DbException.php +++ b/vendor/topthink/think-orm/src/db/exception/DbException.php @@ -17,65 +17,94 @@ use Exception; /** * Database相关异常处理类 */ -class DbException extends Exception -{ - /** - * DbException constructor. - * @access public - * @param string $message - * @param array $config - * @param string $sql - * @param int $code - */ - public function __construct(string $message, array $config = [], string $sql = '', int $code = 10500) +if (class_exists('think\Exception')) { + class DbException extends \think\Exception { - $this->message = $message; - $this->code = $code; + /** + * DbException constructor. + * @access public + * @param string $message + * @param array $config + * @param string $sql + * @param int $code + */ + public function __construct(string $message, array $config = [], string $sql = '', int $code = 10500) + { + $this->message = $message; + $this->code = $code; - $this->setData('Database Status', [ - 'Error Code' => $code, - 'Error Message' => $message, - 'Error SQL' => $sql, - ]); + $this->setData('Database Status', [ + 'Error Code' => $code, + 'Error Message' => $message, + 'Error SQL' => $sql, + ]); - unset($config['username'], $config['password']); - $this->setData('Database Config', $config); + unset($config['username'], $config['password']); + $this->setData('Database Config', $config); + } } +} else { - /** - * 保存异常页面显示的额外Debug数据 - * @var array - */ - protected $data = []; - - /** - * 设置异常额外的Debug数据 - * 数据将会显示为下面的格式 - * - * Exception Data - * -------------------------------------------------- - * Label 1 - * key1 value1 - * key2 value2 - * Label 2 - * key1 value1 - * key2 value2 - * - * @param string $label 数据分类,用于异常页面显示 - * @param array $data 需要显示的数据,必须为关联数组 - */ - final protected function setData($label, array $data) + class DbException extends Exception { - $this->data[$label] = $data; - } + /** + * DbException constructor. + * @access public + * @param string $message + * @param array $config + * @param string $sql + * @param int $code + */ + public function __construct(string $message, array $config = [], string $sql = '', int $code = 10500) + { + $this->message = $message; + $this->code = $code; - /** - * 获取异常额外Debug数据 - * 主要用于输出到异常页面便于调试 - * @return array 由setData设置的Debug数据 - */ - final public function getData() - { - return $this->data; + $this->setData('Database Status', [ + 'Error Code' => $code, + 'Error Message' => $message, + 'Error SQL' => $sql, + ]); + + unset($config['username'], $config['password']); + $this->setData('Database Config', $config); + } + + /** + * 保存异常页面显示的额外Debug数据 + * @var array + */ + protected $data = []; + + /** + * 设置异常额外的Debug数据 + * 数据将会显示为下面的格式 + * + * Exception Data + * -------------------------------------------------- + * Label 1 + * key1 value1 + * key2 value2 + * Label 2 + * key1 value1 + * key2 value2 + * + * @param string $label 数据分类,用于异常页面显示 + * @param array $data 需要显示的数据,必须为关联数组 + */ + final protected function setData($label, array $data) + { + $this->data[$label] = $data; + } + + /** + * 获取异常额外Debug数据 + * 主要用于输出到异常页面便于调试 + * @return array 由setData设置的Debug数据 + */ + final public function getData() + { + return $this->data; + } } } diff --git a/vendor/topthink/think-orm/src/model/Relation.php b/vendor/topthink/think-orm/src/model/Relation.php index d9d02e33c..e823bd90b 100644 --- a/vendor/topthink/think-orm/src/model/Relation.php +++ b/vendor/topthink/think-orm/src/model/Relation.php @@ -99,6 +99,26 @@ abstract class Relation return $this->query; } + /** + * 获取关联表外键 + * @access public + * @return string + */ + public function getForeignKey() + { + return $this->foreignKey; + } + + /** + * 获取关联表主键 + * @access public + * @return string + */ + public function getLocalKey() + { + return $this->localKey; + } + /** * 获取当前的关联模型类的实例 * @access public diff --git a/vendor/topthink/think-orm/src/model/concern/Attribute.php b/vendor/topthink/think-orm/src/model/concern/Attribute.php index 9e4367b8f..6358bf8b8 100644 --- a/vendor/topthink/think-orm/src/model/concern/Attribute.php +++ b/vendor/topthink/think-orm/src/model/concern/Attribute.php @@ -185,7 +185,11 @@ trait Attribute */ protected function getRealFieldName(string $name): string { - return $this->strict ? $name : Str::snake($name); + if ($this->convertNameToCamel || !$this->strict) { + return Str::snake($name); + } + + return $name; } /** @@ -302,7 +306,7 @@ trait Attribute // 只读字段不允许更新 foreach ($this->readonly as $key => $field) { - if (isset($data[$field])) { + if (array_key_exists($field, $data)) { unset($data[$field]); } } diff --git a/vendor/topthink/think-orm/src/model/concern/Conversion.php b/vendor/topthink/think-orm/src/model/concern/Conversion.php index e12d0affb..f81850cb2 100644 --- a/vendor/topthink/think-orm/src/model/concern/Conversion.php +++ b/vendor/topthink/think-orm/src/model/concern/Conversion.php @@ -48,6 +48,24 @@ trait Conversion */ protected $resultSetType; + /** + * 数据命名是否自动转为驼峰 + * @var bool + */ + protected $convertNameToCamel; + + /** + * 转换数据为驼峰命名(用于输出) + * @access public + * @param bool $toCamel 是否自动驼峰命名 + * @return $this + */ + public function convertNameToCamel(bool $toCamel = true) + { + $this->convertNameToCamel = $toCamel; + return $this; + } + /** * 设置需要附加的输出属性 * @access public @@ -181,6 +199,16 @@ trait Conversion $this->appendAttrToArray($item, $key, $name); } + if ($this->convertNameToCamel) { + foreach ($item as $key => $val) { + $name = Str::camel($key); + if ($name !== $key) { + $item[$name] = $val; + unset($item[$key]); + } + } + } + return $item; } diff --git a/vendor/topthink/think-orm/src/model/relation/BelongsToMany.php b/vendor/topthink/think-orm/src/model/relation/BelongsToMany.php index a3c8aa478..6b64d9530 100644 --- a/vendor/topthink/think-orm/src/model/relation/BelongsToMany.php +++ b/vendor/topthink/think-orm/src/model/relation/BelongsToMany.php @@ -440,20 +440,23 @@ class BelongsToMany extends Relation protected function belongsToManyQuery(string $foreignKey, string $localKey, array $condition = []): Query { // 关联查询封装 - $tableName = $this->query->getTable(); - $table = $this->pivot->db()->getTable(); - $fields = $this->getQueryFields($tableName); + if (empty($this->baseQuery)) { + $tableName = $this->query->getTable(); + $table = $this->pivot->db()->getTable(); + $fields = $this->getQueryFields($tableName); + + if ($this->withLimit) { + $this->query->limit($this->withLimit); + } + + $this->query + ->field($fields) + ->tableField(true, $table, 'pivot', 'pivot__') + ->join([$table => 'pivot'], 'pivot.' . $foreignKey . '=' . $tableName . '.' . $this->query->getPk()) + ->where($condition); - if ($this->withLimit) { - $this->query->limit($this->withLimit); } - $this->query - ->field($fields) - ->tableField(true, $table, 'pivot', 'pivot__') - ->join([$table => 'pivot'], 'pivot.' . $foreignKey . '=' . $tableName . '.' . $this->query->getPk()) - ->where($condition); - return $this->query; } @@ -666,7 +669,11 @@ class BelongsToMany extends Relation $localKey = $this->localKey; // 关联查询 - $condition = ['pivot.' . $localKey, '=', $this->parent->getKey()]; + if (null === $this->parent->getKey()) { + $condition = ['pivot.' . $localKey, 'exp', new Raw('=' . $this->parent->getTable() . '.' . $this->parent->getPk())]; + } else { + $condition = ['pivot.' . $localKey, '=', $this->parent->getKey()]; + } $this->belongsToManyQuery($foreignKey, $localKey, [$condition]); diff --git a/vendor/topthink/think-orm/src/model/relation/HasOne.php b/vendor/topthink/think-orm/src/model/relation/HasOne.php index d0dc21d63..7fcd20a03 100644 --- a/vendor/topthink/think-orm/src/model/relation/HasOne.php +++ b/vendor/topthink/think-orm/src/model/relation/HasOne.php @@ -181,7 +181,7 @@ class HasOne extends OneToOne $fields = $this->getRelationQueryFields($fields, $model); $softDelete = $this->query->getOptions('soft_delete'); - $query = $query ?: $this->parent->db()->alias($model); + $query = $query ? $query->alias($model) : $this->parent->db()->alias($model); return $query->field($fields) ->join([$table => $relation], $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey, $joinType ?: $this->joinType) diff --git a/vendor/topthink/think-orm/src/model/relation/OneToOne.php b/vendor/topthink/think-orm/src/model/relation/OneToOne.php index efb2359c7..65bbfdae8 100644 --- a/vendor/topthink/think-orm/src/model/relation/OneToOne.php +++ b/vendor/topthink/think-orm/src/model/relation/OneToOne.php @@ -307,10 +307,6 @@ abstract class OneToOne extends Relation $this->query->field($this->withField); } - if ($this->query->getOptions('order')) { - $this->query->group($key); - } - $list = $this->query ->where($where) ->with($subRelation) diff --git a/vendor/zoujingli/think-library/src/Library.php b/vendor/zoujingli/think-library/src/Library.php index a7d1468f8..9d92f7ca7 100644 --- a/vendor/zoujingli/think-library/src/Library.php +++ b/vendor/zoujingli/think-library/src/Library.php @@ -41,7 +41,7 @@ class Library extends Service /** * 扩展库版本号 */ - const VERSION = '6.0.15'; + const VERSION = '6.0.16'; /** * 启动服务 diff --git a/vendor/zoujingli/think-library/src/storage/AliossStorage.php b/vendor/zoujingli/think-library/src/storage/AliossStorage.php index 6802fab5b..076f0bab3 100644 --- a/vendor/zoujingli/think-library/src/storage/AliossStorage.php +++ b/vendor/zoujingli/think-library/src/storage/AliossStorage.php @@ -76,14 +76,14 @@ class AliossStorage extends Storage /** * 获取当前实例对象 - * @param null $name + * @param null|string $name * @return static * @throws \think\admin\Exception * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ - public static function instance($name = null) + public static function instance(?string $name = null) { return parent::instance('alioss'); } diff --git a/vendor/zoujingli/think-library/src/storage/LocalStorage.php b/vendor/zoujingli/think-library/src/storage/LocalStorage.php index b748b8a69..17451c7e7 100644 --- a/vendor/zoujingli/think-library/src/storage/LocalStorage.php +++ b/vendor/zoujingli/think-library/src/storage/LocalStorage.php @@ -48,14 +48,14 @@ class LocalStorage extends Storage /** * 获取当前实例对象 - * @param null $name + * @param null|string $name * @return static * @throws \think\admin\Exception * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ - public static function instance($name = null): LocalStorage + public static function instance(?string $name = null): LocalStorage { return parent::instance('local'); } diff --git a/vendor/zoujingli/think-library/src/storage/QiniuStorage.php b/vendor/zoujingli/think-library/src/storage/QiniuStorage.php index 8ac1c2cfa..2da326858 100644 --- a/vendor/zoujingli/think-library/src/storage/QiniuStorage.php +++ b/vendor/zoujingli/think-library/src/storage/QiniuStorage.php @@ -55,14 +55,14 @@ class QiniuStorage extends Storage /** * 获取当前实例对象 - * @param null $name + * @param null|string $name * @return static * @throws \think\admin\Exception * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ - public static function instance($name = null) + public static function instance(?string $name = null) { return parent::instance('qiniu'); }