From 47d436c637e642203b58be48024859e471adff03 Mon Sep 17 00:00:00 2001 From: liyukun <1099438829@qq.com> Date: Fri, 31 Dec 2021 01:32:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=87=E7=BA=A7vendor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vendor/composer/autoload_files.php | 2 +- vendor/composer/autoload_psr4.php | 3 +- vendor/composer/autoload_static.php | 13 +- vendor/composer/installed.json | 120 ++++++++++--- vendor/composer/installed.php | 37 ++-- vendor/services.php | 2 +- .../symfony/http-foundation/HeaderUtils.php | 2 - vendor/symfony/http-foundation/ServerBag.php | 2 +- .../Storage/Handler/PdoSessionHandler.php | 4 +- .../var-dumper/Caster/ReflectionCaster.php | 20 ++- vendor/topthink/framework/README.md | 2 +- vendor/topthink/framework/composer.json | 4 +- vendor/topthink/framework/src/helper.php | 2 +- vendor/topthink/framework/src/think/App.php | 31 +--- .../framework/src/think/Container.php | 11 +- .../topthink/framework/src/think/Cookie.php | 6 +- vendor/topthink/framework/src/think/Env.php | 6 +- vendor/topthink/framework/src/think/File.php | 2 +- vendor/topthink/framework/src/think/Lang.php | 54 +++++- .../topthink/framework/src/think/Request.php | 7 +- .../topthink/framework/src/think/Response.php | 21 ++- .../src/think/console/command/Make.php | 2 +- .../src/think/console/command/RouteList.php | 7 +- .../framework/src/think/filesystem/Driver.php | 11 ++ .../src/think/filesystem/driver/Local.php | 8 + .../framework/src/think/log/driver/File.php | 2 + .../src/think/middleware/LoadLangPack.php | 79 +++++++-- .../framework/src/think/route/Dispatch.php | 7 + .../framework/src/think/route/Url.php | 6 +- .../src/think/route/dispatch/Controller.php | 47 +++-- vendor/topthink/framework/tests/EnvTest.php | 2 - vendor/topthink/framework/tests/RouteTest.php | 7 +- vendor/topthink/think-orm/src/Model.php | 43 ++++- vendor/topthink/think-orm/src/Paginator.php | 10 +- .../topthink/think-orm/src/db/BaseQuery.php | 17 +- .../think-orm/src/db/PDOConnection.php | 10 +- .../think-orm/src/db/builder/Sqlite.php | 12 ++ .../src/db/concern/ModelRelationQuery.php | 161 +++++++----------- .../src/db/concern/ResultOperation.php | 73 +++----- .../think-orm/src/model/Collection.php | 2 +- .../think-orm/src/model/concern/Attribute.php | 28 ++- .../src/model/concern/Conversion.php | 1 + .../src/model/concern/SoftDelete.php | 31 +++- .../src/model/relation/BelongsToMany.php | 98 ++--------- 44 files changed, 611 insertions(+), 404 deletions(-) diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index 0ed4359..fedbb2f 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -12,6 +12,6 @@ return array( '35fab96057f1bf5e7aba31a8a6d5fdde' => $vendorDir . '/topthink/think-orm/stubs/load_stubs.php', '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', - '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', '1cfd2761b63b0a29ed23657ea394cb2d' => $vendorDir . '/topthink/think-captcha/src/helper.php', + '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', ); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 59e3577..d0e7a96 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -9,7 +9,7 @@ return array( 'think\\view\\driver\\' => array($vendorDir . '/topthink/think-view/src'), 'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'), 'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/src'), - 'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src'), + 'think\\' => array($vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-template/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/framework/src/think'), 'learn\\' => array($baseDir . '/learn'), 'app\\' => array($baseDir . '/app'), 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), @@ -20,6 +20,7 @@ return array( 'Spatie\\Macroable\\' => array($vendorDir . '/spatie/macroable/src'), 'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), + 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'), 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), 'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'), diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 689f4d0..e778392 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -13,8 +13,8 @@ class ComposerStaticInit179ad4390eaa61356c3a52b9b610e467 '35fab96057f1bf5e7aba31a8a6d5fdde' => __DIR__ . '/..' . '/topthink/think-orm/stubs/load_stubs.php', '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', - '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', '1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php', + '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', ); public static $prefixLengthsPsr4 = array ( @@ -46,6 +46,7 @@ class ComposerStaticInit179ad4390eaa61356c3a52b9b610e467 array ( 'Psr\\SimpleCache\\' => 16, 'Psr\\Log\\' => 8, + 'Psr\\Http\\Message\\' => 17, 'Psr\\Container\\' => 14, 'Psr\\Cache\\' => 10, 'PHPMailer\\PHPMailer\\' => 20, @@ -83,10 +84,10 @@ class ComposerStaticInit179ad4390eaa61356c3a52b9b610e467 ), 'think\\' => array ( - 0 => __DIR__ . '/..' . '/topthink/framework/src/think', - 1 => __DIR__ . '/..' . '/topthink/think-helper/src', + 0 => __DIR__ . '/..' . '/topthink/think-helper/src', + 1 => __DIR__ . '/..' . '/topthink/think-template/src', 2 => __DIR__ . '/..' . '/topthink/think-orm/src', - 3 => __DIR__ . '/..' . '/topthink/think-template/src', + 3 => __DIR__ . '/..' . '/topthink/framework/src/think', ), 'learn\\' => array ( @@ -128,6 +129,10 @@ class ComposerStaticInit179ad4390eaa61356c3a52b9b610e467 array ( 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', ), + 'Psr\\Http\\Message\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/http-message/src', + ), 'Psr\\Container\\' => array ( 0 => __DIR__ . '/..' . '/psr/container/src', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 6bdc51a..a73931d 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -666,6 +666,68 @@ }, "install-path": "../psr/container" }, + { + "name": "psr/http-message", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2016-08-06T14:39:51+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, + "install-path": "../psr/http-message" + }, { "name": "psr/log", "version": "1.1.4", @@ -922,17 +984,17 @@ }, { "name": "symfony/http-foundation", - "version": "v5.4.1", - "version_normalized": "5.4.1.0", + "version": "v5.4.2", + "version_normalized": "5.4.2.0", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "5dad3780023a707f4c24beac7d57aead85c1ce3c" + "reference": "ce952af52877eaf3eab5d0c08cc0ea865ed37313" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/5dad3780023a707f4c24beac7d57aead85c1ce3c", - "reference": "5dad3780023a707f4c24beac7d57aead85c1ce3c", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ce952af52877eaf3eab5d0c08cc0ea865ed37313", + "reference": "ce952af52877eaf3eab5d0c08cc0ea865ed37313", "shasum": "", "mirrors": [ { @@ -956,7 +1018,7 @@ "suggest": { "symfony/mime": "To use the file extension guesser" }, - "time": "2021-12-09T12:46:57+00:00", + "time": "2021-12-28T17:15:56+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -984,7 +1046,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.4.1" + "source": "https://github.com/symfony/http-foundation/tree/v5.4.2" }, "funding": [ { @@ -1270,17 +1332,17 @@ }, { "name": "symfony/var-dumper", - "version": "v4.4.34", - "version_normalized": "4.4.34.0", + "version": "v4.4.36", + "version_normalized": "4.4.36.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "2d0c056b2faaa3d785bdbd5adecc593a5be9c16e" + "reference": "02685c62fcbc4262235cc72a54fbd45ab719ce3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/2d0c056b2faaa3d785bdbd5adecc593a5be9c16e", - "reference": "2d0c056b2faaa3d785bdbd5adecc593a5be9c16e", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/02685c62fcbc4262235cc72a54fbd45ab719ce3c", + "reference": "02685c62fcbc4262235cc72a54fbd45ab719ce3c", "shasum": "", "mirrors": [ { @@ -1310,7 +1372,7 @@ "ext-intl": "To show region name in time zone dump", "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" }, - "time": "2021-11-12T10:50:54+00:00", + "time": "2021-12-29T09:28:53+00:00", "bin": [ "Resources/bin/var-dump-server" ], @@ -1348,7 +1410,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v4.4.34" + "source": "https://github.com/symfony/var-dumper/tree/v4.4.36" }, "funding": [ { @@ -1368,17 +1430,17 @@ }, { "name": "topthink/framework", - "version": "v6.0.9", - "version_normalized": "6.0.9.0", + "version": "v6.0.10", + "version_normalized": "6.0.10.0", "source": { "type": "git", "url": "https://github.com/top-think/framework.git", - "reference": "0b5fb453f0e533de3af3a1ab6a202510b61be617" + "reference": "109ade68d6ad3b10af5c8d9d8f53161a513eec18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/framework/zipball/0b5fb453f0e533de3af3a1ab6a202510b61be617", - "reference": "0b5fb453f0e533de3af3a1ab6a202510b61be617", + "url": "https://api.github.com/repos/top-think/framework/zipball/109ade68d6ad3b10af5c8d9d8f53161a513eec18", + "reference": "109ade68d6ad3b10af5c8d9d8f53161a513eec18", "shasum": "", "mirrors": [ { @@ -1394,17 +1456,19 @@ "league/flysystem-cached-adapter": "^1.0", "php": ">=7.2.5", "psr/container": "~1.0", + "psr/http-message": "^1.0", "psr/log": "~1.0", "psr/simple-cache": "^1.0", "topthink/think-helper": "^3.1.1", "topthink/think-orm": "^2.0" }, "require-dev": { + "guzzlehttp/psr7": "^2.1.0", "mikey179/vfsstream": "^1.6", "mockery/mockery": "^1.2", "phpunit/phpunit": "^7.0" }, - "time": "2021-07-22T03:24:49+00:00", + "time": "2021-12-30T13:54:49+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1436,7 +1500,7 @@ ], "support": { "issues": "https://github.com/top-think/framework/issues", - "source": "https://github.com/top-think/framework/tree/v6.0.9" + "source": "https://github.com/top-think/framework/tree/v6.0.10" }, "install-path": "../topthink/framework" }, @@ -1613,17 +1677,17 @@ }, { "name": "topthink/think-orm", - "version": "v2.0.45", - "version_normalized": "2.0.45.0", + "version": "v2.0.46", + "version_normalized": "2.0.46.0", "source": { "type": "git", "url": "https://github.com/top-think/think-orm.git", - "reference": "3dcf9af447b048103093840833e8c74ab849152f" + "reference": "51ec287abdb99521dbbc66526b114f2e32b8fff4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/think-orm/zipball/3dcf9af447b048103093840833e8c74ab849152f", - "reference": "3dcf9af447b048103093840833e8c74ab849152f", + "url": "https://api.github.com/repos/top-think/think-orm/zipball/51ec287abdb99521dbbc66526b114f2e32b8fff4", + "reference": "51ec287abdb99521dbbc66526b114f2e32b8fff4", "shasum": "", "mirrors": [ { @@ -1643,7 +1707,7 @@ "require-dev": { "phpunit/phpunit": "^7|^8|^9.5" }, - "time": "2021-11-30T14:31:05+00:00", + "time": "2021-12-29T05:48:27+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1671,7 +1735,7 @@ ], "support": { "issues": "https://github.com/top-think/think-orm/issues", - "source": "https://github.com/top-think/think-orm/tree/v2.0.45" + "source": "https://github.com/top-think/think-orm/tree/v2.0.46" }, "install-path": "../topthink/think-orm" }, diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 149e61c..a6c8d6e 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -5,7 +5,7 @@ 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => 'cb1402d64f9ca93ea47960ba194212d469fd5d98', + 'reference' => 'b719a4b772e06fd2165da8eb317ef17bc73126ed', 'name' => 'topthink/think', 'dev' => true, ), @@ -91,6 +91,15 @@ 'reference' => '8622567409010282b7aeebe4bb841fe98b58dcaf', 'dev_requirement' => false, ), + 'psr/http-message' => array( + 'pretty_version' => '1.0.1', + 'version' => '1.0.1.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-message', + 'aliases' => array(), + 'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363', + 'dev_requirement' => false, + ), 'psr/log' => array( 'pretty_version' => '1.1.4', 'version' => '1.1.4.0', @@ -128,12 +137,12 @@ 'dev_requirement' => false, ), 'symfony/http-foundation' => array( - 'pretty_version' => 'v5.4.1', - 'version' => '5.4.1.0', + 'pretty_version' => 'v5.4.2', + 'version' => '5.4.2.0', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/http-foundation', 'aliases' => array(), - 'reference' => '5dad3780023a707f4c24beac7d57aead85c1ce3c', + 'reference' => 'ce952af52877eaf3eab5d0c08cc0ea865ed37313', 'dev_requirement' => false, ), 'symfony/polyfill-mbstring' => array( @@ -164,21 +173,21 @@ 'dev_requirement' => false, ), 'symfony/var-dumper' => array( - 'pretty_version' => 'v4.4.34', - 'version' => '4.4.34.0', + 'pretty_version' => 'v4.4.36', + 'version' => '4.4.36.0', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/var-dumper', 'aliases' => array(), - 'reference' => '2d0c056b2faaa3d785bdbd5adecc593a5be9c16e', + 'reference' => '02685c62fcbc4262235cc72a54fbd45ab719ce3c', 'dev_requirement' => true, ), 'topthink/framework' => array( - 'pretty_version' => 'v6.0.9', - 'version' => '6.0.9.0', + 'pretty_version' => 'v6.0.10', + 'version' => '6.0.10.0', 'type' => 'library', 'install_path' => __DIR__ . '/../topthink/framework', 'aliases' => array(), - 'reference' => '0b5fb453f0e533de3af3a1ab6a202510b61be617', + 'reference' => '109ade68d6ad3b10af5c8d9d8f53161a513eec18', 'dev_requirement' => false, ), 'topthink/think' => array( @@ -187,7 +196,7 @@ 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => 'cb1402d64f9ca93ea47960ba194212d469fd5d98', + 'reference' => 'b719a4b772e06fd2165da8eb317ef17bc73126ed', 'dev_requirement' => false, ), 'topthink/think-captcha' => array( @@ -218,12 +227,12 @@ 'dev_requirement' => false, ), 'topthink/think-orm' => array( - 'pretty_version' => 'v2.0.45', - 'version' => '2.0.45.0', + 'pretty_version' => 'v2.0.46', + 'version' => '2.0.46.0', 'type' => 'library', 'install_path' => __DIR__ . '/../topthink/think-orm', 'aliases' => array(), - 'reference' => '3dcf9af447b048103093840833e8c74ab849152f', + 'reference' => '51ec287abdb99521dbbc66526b114f2e32b8fff4', 'dev_requirement' => false, ), 'topthink/think-template' => array( diff --git a/vendor/services.php b/vendor/services.php index 5dcb9f0..b5a384b 100644 --- a/vendor/services.php +++ b/vendor/services.php @@ -1,5 +1,5 @@ 'think\\captcha\\CaptchaService', diff --git a/vendor/symfony/http-foundation/HeaderUtils.php b/vendor/symfony/http-foundation/HeaderUtils.php index 8f1b8bf..1d56be0 100644 --- a/vendor/symfony/http-foundation/HeaderUtils.php +++ b/vendor/symfony/http-foundation/HeaderUtils.php @@ -154,8 +154,6 @@ class HeaderUtils * is semantically equivalent to $filename. If the filename is already ASCII, * it can be omitted, or just copied from $filename * - * @return string - * * @throws \InvalidArgumentException * * @see RFC 6266 diff --git a/vendor/symfony/http-foundation/ServerBag.php b/vendor/symfony/http-foundation/ServerBag.php index 7af111c..25688d5 100644 --- a/vendor/symfony/http-foundation/ServerBag.php +++ b/vendor/symfony/http-foundation/ServerBag.php @@ -89,7 +89,7 @@ class ServerBag extends ParameterBag // PHP_AUTH_USER/PHP_AUTH_PW if (isset($headers['PHP_AUTH_USER'])) { - $headers['AUTHORIZATION'] = 'Basic '.base64_encode($headers['PHP_AUTH_USER'].':'.$headers['PHP_AUTH_PW']); + $headers['AUTHORIZATION'] = 'Basic '.base64_encode($headers['PHP_AUTH_USER'].':'.($headers['PHP_AUTH_PW'] ?? '')); } elseif (isset($headers['PHP_AUTH_DIGEST'])) { $headers['AUTHORIZATION'] = $headers['PHP_AUTH_DIGEST']; } diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php index 0b9e1c6..067bfcb 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php +++ b/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php @@ -663,7 +663,7 @@ class PdoSessionHandler extends AbstractSessionHandler $selectStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); $insertStmt = null; - do { + while (true) { $selectStmt->execute(); $sessionRows = $selectStmt->fetchAll(\PDO::FETCH_NUM); @@ -712,7 +712,7 @@ class PdoSessionHandler extends AbstractSessionHandler } return ''; - } while (true); + } } /** diff --git a/vendor/symfony/var-dumper/Caster/ReflectionCaster.php b/vendor/symfony/var-dumper/Caster/ReflectionCaster.php index 819a618..2a74b25 100644 --- a/vendor/symfony/var-dumper/Caster/ReflectionCaster.php +++ b/vendor/symfony/var-dumper/Caster/ReflectionCaster.php @@ -134,7 +134,7 @@ class ReflectionCaster array_unshift($trace, [ 'function' => 'yield', 'file' => $function->getExecutingFile(), - 'line' => $function->getExecutingLine() - 1, + 'line' => $function->getExecutingLine() - (int) (\PHP_VERSION_ID < 80100), ]); $trace[] = $frame; $a[$prefix.'trace'] = new TraceStub($trace, false, 0, -1, -1); @@ -263,15 +263,17 @@ class ReflectionCaster unset($a[$prefix.'allowsNull']); } - try { - $a[$prefix.'default'] = $v = $c->getDefaultValue(); - if ($c->isDefaultValueConstant()) { - $a[$prefix.'default'] = new ConstStub($c->getDefaultValueConstantName(), $v); + if ($c->isOptional()) { + try { + $a[$prefix.'default'] = $v = $c->getDefaultValue(); + if ($c->isDefaultValueConstant()) { + $a[$prefix.'default'] = new ConstStub($c->getDefaultValueConstantName(), $v); + } + if (null === $v) { + unset($a[$prefix.'allowsNull']); + } + } catch (\ReflectionException $e) { } - if (null === $v) { - unset($a[$prefix.'allowsNull']); - } - } catch (\ReflectionException $e) { } return $a; diff --git a/vendor/topthink/framework/README.md b/vendor/topthink/framework/README.md index 0ea03c9..aa16486 100644 --- a/vendor/topthink/framework/README.md +++ b/vendor/topthink/framework/README.md @@ -35,7 +35,7 @@ ThinkPHP6.0底层架构采用PHP7.1改写和进一步优化。 * 统一和精简大量用法 -> ThinkPHP6.0的运行环境要求PHP7.1+,兼容PHP8.0。 +> ThinkPHP6.0的运行环境要求PHP7.2+,兼容PHP8.1 ## 安装 diff --git a/vendor/topthink/framework/composer.json b/vendor/topthink/framework/composer.json index 4be2ae0..90793d3 100644 --- a/vendor/topthink/framework/composer.json +++ b/vendor/topthink/framework/composer.json @@ -27,13 +27,15 @@ "psr/log": "~1.0", "psr/container": "~1.0", "psr/simple-cache": "^1.0", + "psr/http-message": "^1.0", "topthink/think-orm": "^2.0", "topthink/think-helper": "^3.1.1" }, "require-dev": { "mikey179/vfsstream": "^1.6", "mockery/mockery": "^1.2", - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^7.0", + "guzzlehttp/psr7": "^2.1.0" }, "autoload": { "files": [], diff --git a/vendor/topthink/framework/src/helper.php b/vendor/topthink/framework/src/helper.php index 650edcb..e436e14 100644 --- a/vendor/topthink/framework/src/helper.php +++ b/vendor/topthink/framework/src/helper.php @@ -149,7 +149,7 @@ if (!function_exists('cookie')) { { if (is_null($value)) { // 删除 - Cookie::delete($name); + Cookie::delete($name, $option ?: []); } elseif ('' === $value) { // 获取 return 0 === strpos($name, '?') ? Cookie::has(substr($name, 1)) : Cookie::get($name); diff --git a/vendor/topthink/framework/src/think/App.php b/vendor/topthink/framework/src/think/App.php index 056a341..101bb6d 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.9'; + const VERSION = '6.0.10LTS'; /** * 应用调试模式 @@ -168,7 +168,7 @@ class App extends Container */ public function __construct(string $rootPath = '') { - $this->thinkPath = dirname(__DIR__) . DIRECTORY_SEPARATOR; + $this->thinkPath = realpath(dirname(__DIR__)) . DIRECTORY_SEPARATOR; $this->rootPath = $rootPath ? rtrim($rootPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $this->getDefaultRootPath(); $this->appPath = $this->rootPath . 'app' . DIRECTORY_SEPARATOR; $this->runtimePath = $this->rootPath . 'runtime' . DIRECTORY_SEPARATOR; @@ -450,13 +450,8 @@ class App extends Container // 加载全局初始化文件 $this->load(); - // 加载框架默认语言包 - $langSet = $this->lang->defaultLangSet(); - - $this->lang->load($this->thinkPath . 'lang' . DIRECTORY_SEPARATOR . $langSet . '.php'); - // 加载应用默认语言包 - $this->loadLangPack($langSet); + $this->loadLangPack(); // 监听AppInit $this->event->trigger(AppInit::class); @@ -482,25 +477,13 @@ class App extends Container /** * 加载语言包 - * @param string $langset 语言 * @return void */ - public function loadLangPack($langset) + public function loadLangPack() { - if (empty($langset)) { - return; - } - - // 加载系统语言包 - $files = glob($this->appPath . 'lang' . DIRECTORY_SEPARATOR . $langset . '.*'); - $this->lang->load($files); - - // 加载扩展(自定义)语言包 - $list = $this->config->get('lang.extend_list', []); - - if (isset($list[$langset])) { - $this->lang->load($list[$langset]); - } + // 加载默认语言包 + $langSet = $this->lang->defaultLangSet(); + $this->lang->switchLangSet($langSet); } /** diff --git a/vendor/topthink/framework/src/think/Container.php b/vendor/topthink/framework/src/think/Container.php index 74026bb..e3a4341 100644 --- a/vendor/topthink/framework/src/think/Container.php +++ b/vendor/topthink/framework/src/think/Container.php @@ -27,6 +27,7 @@ use ReflectionMethod; use think\exception\ClassNotFoundException; use think\exception\FuncNotFoundException; use think\helper\Str; +use Traversable; /** * 容器管理类 支持PSR-11 @@ -520,34 +521,38 @@ class Container implements ContainerInterface, ArrayAccess, IteratorAggregate, C $this->delete($name); } - public function offsetExists($key) + #[\ReturnTypeWillChange] + public function offsetExists($key): bool { return $this->exists($key); } + #[\ReturnTypeWillChange] public function offsetGet($key) { return $this->make($key); } + #[\ReturnTypeWillChange] public function offsetSet($key, $value) { $this->bind($key, $value); } + #[\ReturnTypeWillChange] public function offsetUnset($key) { $this->delete($key); } //Countable - public function count() + public function count(): int { return count($this->instances); } //IteratorAggregate - public function getIterator() + public function getIterator(): Traversable { return new ArrayIterator($this->instances); } diff --git a/vendor/topthink/framework/src/think/Cookie.php b/vendor/topthink/framework/src/think/Cookie.php index ebbfd64..04774a6 100644 --- a/vendor/topthink/framework/src/think/Cookie.php +++ b/vendor/topthink/framework/src/think/Cookie.php @@ -158,11 +158,13 @@ class Cookie * Cookie删除 * @access public * @param string $name cookie名称 + * @param array $options cookie参数 * @return void */ - public function delete(string $name): void + public function delete(string $name, array $options = []): void { - $this->setCookie($name, '', time() - 3600, $this->config); + $config = array_merge($this->config, array_change_key_case($options)); + $this->setCookie($name, '', time() - 3600, $config); } /** diff --git a/vendor/topthink/framework/src/think/Env.php b/vendor/topthink/framework/src/think/Env.php index 4c26b33..21fd250 100644 --- a/vendor/topthink/framework/src/think/Env.php +++ b/vendor/topthink/framework/src/think/Env.php @@ -39,7 +39,7 @@ class Env implements ArrayAccess */ public function load(string $file): void { - $env = parse_ini_file($file, true) ?: []; + $env = parse_ini_file($file, true, INI_SCANNER_RAW) ?: []; $this->set($env); } @@ -159,21 +159,25 @@ class Env implements ArrayAccess } // ArrayAccess + #[\ReturnTypeWillChange] public function offsetSet($name, $value): void { $this->set($name, $value); } + #[\ReturnTypeWillChange] public function offsetExists($name): bool { return $this->__isset($name); } + #[\ReturnTypeWillChange] public function offsetUnset($name) { throw new Exception('not support: unset'); } + #[\ReturnTypeWillChange] public function offsetGet($name) { return $this->get($name); diff --git a/vendor/topthink/framework/src/think/File.php b/vendor/topthink/framework/src/think/File.php index f7c37bd..087e808 100644 --- a/vendor/topthink/framework/src/think/File.php +++ b/vendor/topthink/framework/src/think/File.php @@ -176,7 +176,7 @@ class File extends SplFileInfo $this->hashName = call_user_func($rule); break; default: - $this->hashName = date('Ymd') . DIRECTORY_SEPARATOR . md5((string) microtime(true)); + $this->hashName = date('Ymd') . DIRECTORY_SEPARATOR . md5(microtime(true) . $this->getPathname()); break; } } diff --git a/vendor/topthink/framework/src/think/Lang.php b/vendor/topthink/framework/src/think/Lang.php index 0b79b76..0226f81 100644 --- a/vendor/topthink/framework/src/think/Lang.php +++ b/vendor/topthink/framework/src/think/Lang.php @@ -18,6 +18,8 @@ namespace think; */ class Lang { + protected $app; + /** * 配置参数 * @var array @@ -62,15 +64,26 @@ class Lang * @access public * @param array $config */ - public function __construct(array $config = []) + public function __construct(App $app, array $config = []) { $this->config = array_merge($this->config, array_change_key_case($config)); $this->range = $this->config['default_lang']; + $this->app = $app; } - public static function __make(Config $config) + public static function __make(App $app, Config $config) { - return new static($config->get('lang')); + return new static($app, $config->get('lang')); + } + + /** + * 获取当前语言配置 + * @access public + * @return array + */ + public function getConfig(): array + { + return $this->config; } /** @@ -104,6 +117,35 @@ class Lang return $this->config['default_lang']; } + /** + * 切换语言 + * @access public + * @param string $langset 语言 + * @return void + */ + public function switchLangSet(string $langset) + { + if (empty($langset)) { + return; + } + + // 加载系统语言包 + $this->load([ + $this->app->getThinkPath() . 'lang' . DIRECTORY_SEPARATOR . $langset . '.php', + ]); + + // 加载系统语言包 + $files = glob($this->app->getAppPath() . 'lang' . DIRECTORY_SEPARATOR . $langset . '.*'); + $this->load($files); + + // 加载扩展(自定义)语言包 + $list = $this->app->config->get('lang.extend_list', []); + + if (isset($list[$langset])) { + $this->load($list[$langset]); + } + } + /** * 加载语言定义(不区分大小写) * @access public @@ -202,6 +244,10 @@ class Lang { $range = $range ?: $this->range; + if (!isset($this->lang[$range])) { + $this->switchLangSet($range); + } + // 空参数返回所有定义 if (is_null($name)) { return $this->lang[$range] ?? []; @@ -241,6 +287,7 @@ class Lang /** * 自动侦测设置获取语言选择 + * @deprecated * @access public * @param Request $request * @return string @@ -280,6 +327,7 @@ class Lang /** * 保存当前语言到Cookie + * @deprecated * @access public * @param Cookie $cookie Cookie对象 * @return void diff --git a/vendor/topthink/framework/src/think/Request.php b/vendor/topthink/framework/src/think/Request.php index 1c15f63..fe9938d 100644 --- a/vendor/topthink/framework/src/think/Request.php +++ b/vendor/topthink/framework/src/think/Request.php @@ -13,6 +13,7 @@ declare (strict_types = 1); namespace think; use ArrayAccess; +use think\facade\Lang; use think\file\UploadedFile; use think\route\Rule; @@ -1227,7 +1228,7 @@ class Request implements ArrayAccess 7 => 'file write error', ]; - $msg = $fileUploadErrors[$error]; + $msg = Lang::get($fileUploadErrors[$error]); throw new Exception($msg, $error); } @@ -2150,19 +2151,23 @@ class Request implements ArrayAccess } // ArrayAccess + #[\ReturnTypeWillChange] public function offsetExists($name): bool { return $this->has($name); } + #[\ReturnTypeWillChange] public function offsetGet($name) { return $this->param($name); } + #[\ReturnTypeWillChange] public function offsetSet($name, $value) {} + #[\ReturnTypeWillChange] public function offsetUnset($name) {} diff --git a/vendor/topthink/framework/src/think/Response.php b/vendor/topthink/framework/src/think/Response.php index a8a61ff..49f26dc 100644 --- a/vendor/topthink/framework/src/think/Response.php +++ b/vendor/topthink/framework/src/think/Response.php @@ -130,16 +130,19 @@ abstract class Response // 处理输出数据 $data = $this->getContent(); - if (!headers_sent() && !empty($this->header)) { - // 发送状态码 - http_response_code($this->code); - // 发送头部信息 - foreach ($this->header as $name => $val) { - header($name . (!is_null($val) ? ':' . $val : '')); + if (!headers_sent()) { + if (!empty($this->header)) { + // 发送状态码 + http_response_code($this->code); + // 发送头部信息 + foreach ($this->header as $name => $val) { + header($name . (!is_null($val) ? ':' . $val : '')); + } + } + + if ($this->cookie) { + $this->cookie->save(); } - } - if ($this->cookie) { - $this->cookie->save(); } $this->sendData($data); diff --git a/vendor/topthink/framework/src/think/console/command/Make.php b/vendor/topthink/framework/src/think/console/command/Make.php index 662b337..a74e9e8 100644 --- a/vendor/topthink/framework/src/think/console/command/Make.php +++ b/vendor/topthink/framework/src/think/console/command/Make.php @@ -67,7 +67,7 @@ abstract class Make extends Command protected function getPathName(string $name): string { - $name = str_replace('app\\', '', $name); + $name = substr($name, 4); return $this->app->getBasePath() . ltrim(str_replace('\\', '/', $name), '/') . '.php'; } diff --git a/vendor/topthink/framework/src/think/console/command/RouteList.php b/vendor/topthink/framework/src/think/console/command/RouteList.php index ed579b8..e9d4c5d 100644 --- a/vendor/topthink/framework/src/think/console/command/RouteList.php +++ b/vendor/topthink/framework/src/think/console/command/RouteList.php @@ -91,14 +91,13 @@ class RouteList extends Command foreach ($routeList as $item) { $item['route'] = $item['route'] instanceof \Closure ? '' : $item['route']; + $row = [$item['rule'], $item['route'], $item['method'], $item['name']]; if ($this->input->hasOption('more')) { - $item = [$item['rule'], $item['route'], $item['method'], $item['name'], $item['domain'], json_encode($item['option']), json_encode($item['pattern'])]; - } else { - $item = [$item['rule'], $item['route'], $item['method'], $item['name']]; + array_push($row, $item['domain'], json_encode($item['option']), json_encode($item['pattern'])); } - $rows[] = $item; + $rows[] = $row; } if ($this->input->getOption('sort')) { diff --git a/vendor/topthink/framework/src/think/filesystem/Driver.php b/vendor/topthink/framework/src/think/filesystem/Driver.php index 6712959..0e61cf4 100644 --- a/vendor/topthink/framework/src/think/filesystem/Driver.php +++ b/vendor/topthink/framework/src/think/filesystem/Driver.php @@ -17,6 +17,7 @@ use League\Flysystem\Adapter\AbstractAdapter; use League\Flysystem\Cached\CachedAdapter; use League\Flysystem\Cached\Storage\Memory as MemoryStore; use League\Flysystem\Filesystem; +use RuntimeException; use think\Cache; use think\File; @@ -91,6 +92,16 @@ abstract class Driver return $path; } + protected function concatPathToUrl($url, $path) + { + return rtrim($url, '/') . '/' . ltrim($path, '/'); + } + + public function url(string $path): string + { + throw new RuntimeException('This driver does not support retrieving URLs.'); + } + /** * 保存文件 * @param string $path 路径 diff --git a/vendor/topthink/framework/src/think/filesystem/driver/Local.php b/vendor/topthink/framework/src/think/filesystem/driver/Local.php index c10ccc3..31172d0 100644 --- a/vendor/topthink/framework/src/think/filesystem/driver/Local.php +++ b/vendor/topthink/framework/src/think/filesystem/driver/Local.php @@ -41,4 +41,12 @@ class Local extends Driver $permissions ); } + + public function url(string $path): string + { + if (isset($this->config['url'])) { + return $this->concatPathToUrl($this->config['url'], $path); + } + return parent::url($path); + } } diff --git a/vendor/topthink/framework/src/think/log/driver/File.php b/vendor/topthink/framework/src/think/log/driver/File.php index e5682fc..1f726b0 100644 --- a/vendor/topthink/framework/src/think/log/driver/File.php +++ b/vendor/topthink/framework/src/think/log/driver/File.php @@ -139,7 +139,9 @@ class File implements LogHandlerInterface try { if (count($files) > $this->config['max_files']) { + set_error_handler(function ($errno, $errstr, $errfile, $errline) {}); unlink($files[0]); + restore_error_handler(); } } catch (\Exception $e) { // diff --git a/vendor/topthink/framework/src/think/middleware/LoadLangPack.php b/vendor/topthink/framework/src/think/middleware/LoadLangPack.php index 478e29c..d6bf6a4 100644 --- a/vendor/topthink/framework/src/think/middleware/LoadLangPack.php +++ b/vendor/topthink/framework/src/think/middleware/LoadLangPack.php @@ -14,6 +14,8 @@ namespace think\middleware; use Closure; use think\App; +use think\Config; +use think\Cookie; use think\Lang; use think\Request; use think\Response; @@ -24,13 +26,14 @@ use think\Response; class LoadLangPack { protected $app; - protected $lang; + protected $config; - public function __construct(App $app, Lang $lang) + public function __construct(App $app, Lang $lang, Config $config) { - $this->app = $app; - $this->lang = $lang; + $this->app = $app; + $this->lang = $lang; + $this->config = $lang->getConfig(); } /** @@ -43,19 +46,71 @@ class LoadLangPack public function handle($request, Closure $next) { // 自动侦测当前语言 - $langset = $this->lang->detect($request); + $langset = $this->detect($request); if ($this->lang->defaultLangSet() != $langset) { - // 加载系统语言包 - $this->lang->load([ - $this->app->getThinkPath() . 'lang' . DIRECTORY_SEPARATOR . $langset . '.php', - ]); - - $this->app->LoadLangPack($langset); + $this->lang->switchLangSet($langset); } - $this->lang->saveToCookie($this->app->cookie); + $this->saveToCookie($this->app->cookie, $langset); return $next($request); } + + /** + * 自动侦测设置获取语言选择 + * @access protected + * @param Request $request + * @return string + */ + protected function detect(Request $request): string + { + // 自动侦测设置获取语言选择 + $langSet = ''; + + if ($request->get($this->config['detect_var'])) { + // url中设置了语言变量 + $langSet = strtolower($request->get($this->config['detect_var'])); + } elseif ($request->header($this->config['header_var'])) { + // Header中设置了语言变量 + $langSet = strtolower($request->header($this->config['header_var'])); + } elseif ($request->cookie($this->config['cookie_var'])) { + // Cookie中设置了语言变量 + $langSet = strtolower($request->cookie($this->config['cookie_var'])); + } elseif ($request->server('HTTP_ACCEPT_LANGUAGE')) { + // 自动侦测浏览器语言 + $match = preg_match('/^([a-z\d\-]+)/i', $request->server('HTTP_ACCEPT_LANGUAGE'), $matches); + if ($match) { + $langSet = strtolower($matches[1]); + if (isset($this->config['accept_language'][$langSet])) { + $langSet = $this->config['accept_language'][$langSet]; + } + } + } + + if (empty($this->config['allow_lang_list']) || in_array($langSet, $this->config['allow_lang_list'])) { + // 合法的语言 + $range = $langSet; + $this->lang->setLangSet($range); + } else { + $range = $this->lang->getLangSet(); + } + + return $range; + } + + /** + * 保存当前语言到Cookie + * @access protected + * @param Cookie $cookie Cookie对象 + * @param string $langSet 语言 + * @return void + */ + protected function saveToCookie(Cookie $cookie, string $langSet) + { + if ($this->config['use_cookie']) { + $cookie->set($this->config['cookie_var'], $langSet); + } + } + } diff --git a/vendor/topthink/framework/src/think/route/Dispatch.php b/vendor/topthink/framework/src/think/route/Dispatch.php index e77e299..0599dc1 100644 --- a/vendor/topthink/framework/src/think/route/Dispatch.php +++ b/vendor/topthink/framework/src/think/route/Dispatch.php @@ -12,6 +12,7 @@ declare (strict_types = 1); namespace think\route; +use Psr\Http\Message\ResponseInterface; use think\App; use think\Container; use think\Request; @@ -94,6 +95,12 @@ abstract class Dispatch { if ($data instanceof Response) { $response = $data; + } elseif ($data instanceof ResponseInterface) { + $response = Response::create($data->getBody()->getContents(), 'html', $data->getStatusCode()); + + foreach ($data->getHeaders() as $header => $values) { + $response->header([$header => implode(", ", $values)]); + } } elseif (!is_null($data)) { // 默认自动识别响应输出类型 $type = $this->request->isJson() ? 'json' : 'html'; diff --git a/vendor/topthink/framework/src/think/route/Url.php b/vendor/topthink/framework/src/think/route/Url.php index 8dd410c..b3f8b9f 100644 --- a/vendor/topthink/framework/src/think/route/Url.php +++ b/vendor/topthink/framework/src/think/route/Url.php @@ -320,7 +320,7 @@ class Url } if (empty($pattern)) { - return [rtrim($url, '?/-'), $domain, $suffix]; + return [rtrim($url, '?-'), $domain, $suffix]; } $type = $this->route->config('url_common_param'); @@ -331,11 +331,11 @@ class Url $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key, '<' . $key . '>'], $type ? (string) $vars[$key] : urlencode((string) $vars[$key]), $url); $keys[] = $key; $url = str_replace(['/?', '-?'], ['/', '-'], $url); - $result = [rtrim($url, '?/-'), $domain, $suffix]; + $result = [rtrim($url, '?-'), $domain, $suffix]; } elseif (2 == $val) { $url = str_replace(['/[:' . $key . ']', '[:' . $key . ']', '<' . $key . '?>'], '', $url); $url = str_replace(['/?', '-?'], ['/', '-'], $url); - $result = [rtrim($url, '?/-'), $domain, $suffix]; + $result = [rtrim($url, '?-'), $domain, $suffix]; } else { $result = null; $keys = []; diff --git a/vendor/topthink/framework/src/think/route/dispatch/Controller.php b/vendor/topthink/framework/src/think/route/dispatch/Controller.php index 611101b..f18512c 100644 --- a/vendor/topthink/framework/src/think/route/dispatch/Controller.php +++ b/vendor/topthink/framework/src/think/route/dispatch/Controller.php @@ -113,6 +113,13 @@ class Controller extends Dispatch }); } + protected function parseActions($actions) + { + return array_map(function ($item) { + return strtolower($item); + }, is_string($actions) ? explode(",", $actions) : $actions); + } + /** * 使用反射机制注册控制器中间件 * @access public @@ -128,30 +135,34 @@ class Controller extends Dispatch $reflectionProperty->setAccessible(true); $middlewares = $reflectionProperty->getValue($controller); + $action = $this->request->action(true); foreach ($middlewares as $key => $val) { if (!is_int($key)) { - if (isset($val['only']) && !in_array($this->request->action(true), array_map(function ($item) { - return strtolower($item); - }, is_string($val['only']) ? explode(",", $val['only']) : $val['only']))) { - continue; - } elseif (isset($val['except']) && in_array($this->request->action(true), array_map(function ($item) { - return strtolower($item); - }, is_string($val['except']) ? explode(',', $val['except']) : $val['except']))) { - continue; - } else { - $val = $key; + $middleware = $key; + $options = $val; + } elseif (isset($val['middleware'])) { + $middleware = $val['middleware']; + $options = $val['options'] ?? []; + } else { + $middleware = $val; + $options = []; + } + + if (isset($options['only']) && !in_array($action, $this->parseActions($options['only']))) { + continue; + } elseif (isset($options['except']) && in_array($action, $this->parseActions($options['except']))) { + continue; + } + + if (is_string($middleware) && strpos($middleware, ':')) { + $middleware = explode(':', $middleware); + if (count($middleware) > 1) { + $middleware = [$middleware[0], array_slice($middleware, 1)]; } } - if (is_string($val) && strpos($val, ':')) { - $val = explode(':', $val); - if (count($val) > 1) { - $val = [$val[0], array_slice($val, 1)]; - } - } - - $this->app->middleware->controller($val); + $this->app->middleware->controller($middleware); } } } diff --git a/vendor/topthink/framework/tests/EnvTest.php b/vendor/topthink/framework/tests/EnvTest.php index cf2e65f..9b3b615 100644 --- a/vendor/topthink/framework/tests/EnvTest.php +++ b/vendor/topthink/framework/tests/EnvTest.php @@ -21,8 +21,6 @@ class EnvTest extends TestCase $this->assertEquals('value1', $env->get('key1')); $this->assertEquals('value2', $env->get('key2')); - - $this->assertSame(['KEY1' => 'value1', 'KEY2' => 'value2'], $env->get()); } public function testServerEnv() diff --git a/vendor/topthink/framework/tests/RouteTest.php b/vendor/topthink/framework/tests/RouteTest.php index e992d0f..6a7f8ee 100644 --- a/vendor/topthink/framework/tests/RouteTest.php +++ b/vendor/topthink/framework/tests/RouteTest.php @@ -194,6 +194,10 @@ class RouteTest extends TestCase $this->createMiddleware()->mockery_getName() . ":params1:params2", $this->createMiddleware(0)->mockery_getName() => ['except' => 'bar'], $this->createMiddleware()->mockery_getName() => ['only' => 'bar'], + [ + 'middleware' => [$this->createMiddleware()->mockery_getName(), [new \stdClass()]], + 'options' => ['only' => 'bar'], + ], ]; $this->app->shouldReceive('parseClass')->with('controller', 'Foo')->andReturn($controller->mockery_getName()); @@ -211,7 +215,8 @@ class RouteTest extends TestCase $controller = m::mock(FooClass::class); $controller->shouldReceive('index')->andReturn('bar'); - $this->app->shouldReceive('parseClass')->once()->with('controller', 'Foo')->andReturn($controller->mockery_getName()); + $this->app->shouldReceive('parseClass')->once()->with('controller', 'Foo') + ->andReturn($controller->mockery_getName()); $this->app->shouldReceive('make')->with($controller->mockery_getName(), [], true)->andReturn($controller); $request = $this->makeRequest('foo'); diff --git a/vendor/topthink/think-orm/src/Model.php b/vendor/topthink/think-orm/src/Model.php index 00016d0..9802821 100644 --- a/vendor/topthink/think-orm/src/Model.php +++ b/vendor/topthink/think-orm/src/Model.php @@ -243,6 +243,29 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab } } + $this->filter(function ($result, $options) { + // 关联查询 + if (!empty($options['relation'])) { + $result->relationQuery($options['relation'], $options['with_relation_attr']); + } + + // 预载入查询 + if (!empty($options['with'])) { + $result->eagerlyResult($result, $options['with'], $options['with_relation_attr'], false, $options['with_cache'] ?? false); + } + + // JOIN预载入查询 + if (!empty($options['with_join'])) { + $result->eagerlyResult($result, $options['with_join'], $options['with_relation_attr'], true, $options['with_cache'] ?? false); + } + + // 关联统计 + if (!empty($options['with_count'])) { + foreach ($options['with_count'] as $val) { + $result->relationCount($this, (array) $val[0], $val[1], $val[2], false); + } + } + }); // 执行初始化操作 $this->initialize(); } @@ -260,11 +283,12 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab /** * 创建新的模型实例 * @access public - * @param array $data 数据 - * @param mixed $where 更新条件 + * @param array $data 数据 + * @param mixed $where 更新条件 + * @param array $options 参数 * @return Model */ - public function newInstance(array $data = [], $where = null): Model + public function newInstance(array $data = [], $where = null, array $options = []): Model { $model = new static($data); @@ -284,6 +308,11 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab $model->setUpdateWhere($where); + // 查询数据处理 + foreach ($this->filter as $filter) { + call_user_func_array($filter, [$model, $options]); + } + $model->trigger('AfterRead'); return $model; @@ -970,21 +999,25 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab } // ArrayAccess + #[\ReturnTypeWillChange] public function offsetSet($name, $value) { $this->setAttr($name, $value); } + #[\ReturnTypeWillChange] public function offsetExists($name): bool { return $this->__isset($name); } + #[\ReturnTypeWillChange] public function offsetUnset($name) { $this->__unset($name); } + #[\ReturnTypeWillChange] public function offsetGet($name) { return $this->getAttr($name); @@ -1037,10 +1070,6 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab return call_user_func_array(static::$macro[static::class][$method]->bindTo($this, static::class), $args); } - if ('withattr' == strtolower($method)) { - return call_user_func_array([$this, 'withAttribute'], $args); - } - return call_user_func_array([$this->db(), $method], $args); } diff --git a/vendor/topthink/think-orm/src/Paginator.php b/vendor/topthink/think-orm/src/Paginator.php index d8d43d7..2f755ef 100644 --- a/vendor/topthink/think-orm/src/Paginator.php +++ b/vendor/topthink/think-orm/src/Paginator.php @@ -410,7 +410,8 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J * @return Traversable An instance of an object implementing Iterator or * Traversable */ - public function getIterator() + #[\ReturnTypeWillChange] + public function getIterator(): Traversable { return new ArrayIterator($this->items->all()); } @@ -421,7 +422,8 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J * @param mixed $offset * @return bool */ - public function offsetExists($offset) + #[\ReturnTypeWillChange] + public function offsetExists($offset): bool { return $this->items->offsetExists($offset); } @@ -432,6 +434,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J * @param mixed $offset * @return mixed */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->items->offsetGet($offset); @@ -443,6 +446,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J * @param mixed $offset * @param mixed $value */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $this->items->offsetSet($offset, $value); @@ -455,6 +459,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J * @return void * @since 5.0.0 */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $this->items->offsetUnset($offset); @@ -498,6 +503,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J /** * Specify data which should be serialized to JSON */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->toArray(); diff --git a/vendor/topthink/think-orm/src/db/BaseQuery.php b/vendor/topthink/think-orm/src/db/BaseQuery.php index a0acdbe..63b8d22 100644 --- a/vendor/topthink/think-orm/src/db/BaseQuery.php +++ b/vendor/topthink/think-orm/src/db/BaseQuery.php @@ -106,6 +106,12 @@ abstract class BaseQuery $name = Str::snake(substr($method, 5)); array_unshift($args, $name); return call_user_func_array([$this, 'where'], $args); + } elseif ($this->model && in_array($method, ['hidden', 'visible', 'append'])) { + // 调用模型类方法 + $this->model->filter(function ($model, $options) use ($method, $args) { + call_user_func_array([$model, $method], $args); + }); + return $this; } elseif ($this->model && method_exists($this->model, 'scope' . $method)) { // 动态调用命名范围 $method = 'scope' . $method; @@ -137,7 +143,7 @@ abstract class BaseQuery $query->name($this->name); } - if (isset($this->options['json'])) { + if (!empty($this->options['json'])) { $query->json($this->options['json'], $this->options['json_assoc']); } @@ -278,7 +284,9 @@ abstract class BaseQuery public function column($field, string $key = ''): array { $result = $this->connection->column($this, $field, $key); - $this->resultSet($result, false); + if (count($result) != count($result, 1)) { + $this->resultSet($result, false); + } return $result; } @@ -867,6 +875,7 @@ abstract class BaseQuery { $this->options['json'] = $json; $this->options['json_assoc'] = $assoc; + return $this; } @@ -1124,7 +1133,7 @@ abstract class BaseQuery * 查找单条记录 * @access public * @param mixed $data 查询数据 - * @return array|Model|null|static + * @return array|Model|null|static|mixed * @throws Exception * @throws ModelNotFoundException * @throws DataNotFoundException @@ -1178,7 +1187,7 @@ abstract class BaseQuery $this->parseView($options); } - foreach (['data', 'order', 'join', 'union'] as $name) { + foreach (['data', 'order', 'join', 'union', 'filter', 'json'] as $name) { if (!isset($options[$name])) { $options[$name] = []; } diff --git a/vendor/topthink/think-orm/src/db/PDOConnection.php b/vendor/topthink/think-orm/src/db/PDOConnection.php index 1a3d4a2..40ac99e 100644 --- a/vendor/topthink/think-orm/src/db/PDOConnection.php +++ b/vendor/topthink/think-orm/src/db/PDOConnection.php @@ -279,7 +279,7 @@ abstract class PDOConnection extends Connection */ protected function getFieldType(string $type): string { - if (0 === strpos($type, 'set') || 0 === strpos($type, 'enum')) { + if (0 === stripos($type, 'set') || 0 === stripos($type, 'enum')) { $result = 'string'; } elseif (preg_match('/(double|float|decimal|real|numeric)/is', $type)) { $result = 'float'; @@ -287,11 +287,11 @@ abstract class PDOConnection extends Connection $result = 'int'; } elseif (preg_match('/bool/is', $type)) { $result = 'bool'; - } elseif (0 === strpos($type, 'timestamp')) { + } elseif (0 === stripos($type, 'timestamp')) { $result = 'timestamp'; - } elseif (0 === strpos($type, 'datetime')) { + } elseif (0 === stripos($type, 'datetime')) { $result = 'datetime'; - } elseif (0 === strpos($type, 'date')) { + } elseif (0 === stripos($type, 'date')) { $result = 'date'; } else { $result = 'string'; @@ -1273,7 +1273,7 @@ abstract class PDOConnection extends Connection $type = is_array($val) ? $val[1] : PDO::PARAM_STR; if (self::PARAM_FLOAT == $type || PDO::PARAM_STR == $type) { - $value = '\'' . addslashes($value) . '\''; + $value = '\'' . addcslashes($value, "'") . '\''; } elseif (PDO::PARAM_INT == $type && '' === $value) { $value = '0'; } diff --git a/vendor/topthink/think-orm/src/db/builder/Sqlite.php b/vendor/topthink/think-orm/src/db/builder/Sqlite.php index 40cab7f..78a307d 100644 --- a/vendor/topthink/think-orm/src/db/builder/Sqlite.php +++ b/vendor/topthink/think-orm/src/db/builder/Sqlite.php @@ -94,4 +94,16 @@ class Sqlite extends Builder return $key; } + + /** + * 设置锁机制 + * @access protected + * @param Query $query 查询对象 + * @param bool|string $lock + * @return string + */ + protected function parseLock(Query $query, $lock = false): string + { + return ''; + } } diff --git a/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php b/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php index ffb72de..ffec2fb 100644 --- a/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php +++ b/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php @@ -51,42 +51,6 @@ trait ModelRelationQuery return $this->model; } - /** - * 设置需要隐藏的输出属性 - * @access public - * @param array $hidden 需要隐藏的字段名 - * @return $this - */ - public function hidden(array $hidden) - { - $this->options['hidden'] = $hidden; - return $this; - } - - /** - * 设置需要输出的属性 - * @access public - * @param array $visible 需要输出的属性 - * @return $this - */ - public function visible(array $visible) - { - $this->options['visible'] = $visible; - return $this; - } - - /** - * 设置需要追加输出的属性 - * @access public - * @param array $append 需要追加的属性 - * @return $this - */ - public function append(array $append) - { - $this->options['append'] = $append; - return $this; - } - /** * 添加查询范围 * @access public @@ -187,7 +151,9 @@ trait ModelRelationQuery $this->options['with_attr'][$name] = $callback; } - return $this; + return $this->filter(function ($result) { + return $this->getResultAttr($result, $this->options['with_attr']); + }, 'with_attr'); } /** @@ -418,23 +384,10 @@ trait ModelRelationQuery return $this->model->toCollection(); } - // 检查动态获取器 - if (!empty($this->options['with_attr'])) { - foreach ($this->options['with_attr'] as $name => $val) { - if (strpos($name, '.')) { - [$relation, $field] = explode('.', $name); - - $withRelationAttr[$relation][$field] = $val; - unset($this->options['with_attr'][$name]); - } - } - } - - $withRelationAttr = $withRelationAttr ?? []; - + $withRelationAttr = $this->getWithRelationAttr(); foreach ($resultSet as $key => &$result) { // 数据转换为模型对象 - $this->resultToModel($result, $this->options, true, $withRelationAttr); + $this->resultToModel($result, $this->options, true); } if (!empty($this->options['with'])) { @@ -451,74 +404,74 @@ trait ModelRelationQuery return $this->model->toCollection($resultSet); } + /** + * 检查动态获取器 + * @access protected + * @return array + */ + protected function getWithRelationAttr(): array + { + if (isset($this->options['with_relation_attr'])) { + return $this->options['with_relation_attr']; + } + + $withRelationAttr = []; + if (!empty($this->options['with_attr'])) { + foreach ($this->options['with_attr'] as $name => $val) { + if (strpos($name, '.')) { + [$relation, $field] = explode('.', $name); + + $withRelationAttr[$relation][$field] = $val; + unset($this->options['with_attr'][$name]); + } + } + } + + $this->options['with_relation_attr'] = $withRelationAttr; + return $withRelationAttr; + } + /** * 查询数据转换为模型对象 * @access protected * @param array $result 查询数据 * @param array $options 查询参数 * @param bool $resultSet 是否为数据集查询 - * @param array $withRelationAttr 关联字段获取器 * @return void */ - protected function resultToModel(array &$result, array $options = [], bool $resultSet = false, array $withRelationAttr = []): void + protected function resultToModel(array &$result, array $options = [], bool $resultSet = false): void { - // 动态获取器 - if (!empty($options['with_attr']) && empty($withRelationAttr)) { - foreach ($options['with_attr'] as $name => $val) { - if (strpos($name, '.')) { - [$relation, $field] = explode('.', $name); - - $withRelationAttr[$relation][$field] = $val; - unset($options['with_attr'][$name]); - } - } - } + $options['with_relation_attr'] = $this->getWithRelationAttr(); // JSON 数据处理 if (!empty($options['json'])) { - $this->jsonResult($result, $options['json'], $options['json_assoc'], $withRelationAttr); + $this->jsonResult($result, $options['json'], $options['json_assoc'], $options['with_relation_attr']); } - $result = $this->model - ->newInstance($result, $resultSet ? null : $this->getModelUpdateCondition($options)); - - // 动态获取器 - if (!empty($options['with_attr'])) { - $result->withAttribute($options['with_attr']); + foreach ($this->options['filter'] as $filter) { + $result = call_user_func($filter, $result); } - // 输出属性控制 - if (!empty($options['visible'])) { - $result->visible($options['visible']); - } elseif (!empty($options['hidden'])) { - $result->hidden($options['hidden']); - } - - if (!empty($options['append'])) { - $result->append($options['append']); - } - - // 关联查询 - if (!empty($options['relation'])) { - $result->relationQuery($options['relation'], $withRelationAttr); - } - - // 预载入查询 - if (!$resultSet && !empty($options['with'])) { - $result->eagerlyResult($result, $options['with'], $withRelationAttr, false, $options['with_cache'] ?? false); - } - - // JOIN预载入查询 - if (!$resultSet && !empty($options['with_join'])) { - $result->eagerlyResult($result, $options['with_join'], $withRelationAttr, true, $options['with_cache'] ?? false); - } - - // 关联统计 - if (!empty($options['with_count'])) { - foreach ($options['with_count'] as $val) { - $result->relationCount($this, (array) $val[0], $val[1], $val[2], false); - } - } + $result = $this->model->newInstance($result, $resultSet ? null : $this->getModelUpdateCondition($options), $options); } + /** + * 查询软删除数据 + * @access public + * @return Query + */ + public function withTrashed() + { + return $this->model ? $this->model->queryWithTrashed() : $this; + } + + /** + * 只查询软删除数据 + * @access public + * @return Query + */ + public function onlyTrashed() + { + return $this->model ? $this->model->queryOnlyTrashed() : $this; + } } diff --git a/vendor/topthink/think-orm/src/db/concern/ResultOperation.php b/vendor/topthink/think-orm/src/db/concern/ResultOperation.php index 77409d1..d8b5a4c 100644 --- a/vendor/topthink/think-orm/src/db/concern/ResultOperation.php +++ b/vendor/topthink/think-orm/src/db/concern/ResultOperation.php @@ -26,6 +26,23 @@ use think\Model; */ trait ResultOperation { + /** + * 设置数据处理 + * @access public + * @param callable $filter 数据处理Callable + * @param string $index 索引(唯一) + * @return $this + */ + public function filter(callable $filter, string $index = null) + { + if ($index) { + $this->options['filter'][$index] = $filter; + } else { + $this->options['filter'][] = $filter; + } + return $this; + } + /** * 是否允许返回空数据(或空模型) * @access public @@ -62,11 +79,9 @@ trait ResultOperation $this->jsonResult($result, $this->options['json'], true); } - if (!empty($this->options['with_attr'])) { - $this->getResultAttr($result, $this->options['with_attr']); + foreach ($this->options['filter'] as $filter) { + $result = call_user_func($filter, $result); } - - $this->filterResult($result); } /** @@ -78,22 +93,8 @@ trait ResultOperation */ protected function resultSet(array &$resultSet, bool $toCollection = true): void { - if (!empty($this->options['json'])) { - foreach ($resultSet as &$result) { - $this->jsonResult($result, $this->options['json'], true); - } - } - - if (!empty($this->options['with_attr'])) { - foreach ($resultSet as &$result) { - $this->getResultAttr($result, $this->options['with_attr']); - } - } - - if (!empty($this->options['visible']) || !empty($this->options['hidden'])) { - foreach ($resultSet as &$result) { - $this->filterResult($result); - } + foreach ($resultSet as &$result) { + $this->result($result); } // 返回Collection对象 @@ -102,36 +103,14 @@ trait ResultOperation } } - /** - * 处理数据的可见和隐藏 - * @access protected - * @param array $result 查询数据 - * @return void - */ - protected function filterResult(&$result): void - { - $array = []; - if (!empty($this->options['visible'])) { - foreach ($this->options['visible'] as $key) { - $array[] = $key; - } - $result = array_intersect_key($result, array_flip($array)); - } elseif (!empty($this->options['hidden'])) { - foreach ($this->options['hidden'] as $key) { - $array[] = $key; - } - $result = array_diff_key($result, array_flip($array)); - } - } - /** * 使用获取器处理数据 * @access protected * @param array $result 查询数据 * @param array $withAttr 字段获取器 - * @return void + * @return array */ - protected function getResultAttr(array &$result, array $withAttr = []): void + protected function getResultAttr(array $result, array $withAttr = []): array { foreach ($withAttr as $name => $closure) { $name = Str::snake($name); @@ -147,6 +126,8 @@ trait ResultOperation $result[$name] = $closure($result[$name] ?? null, $result); } } + + return $result; } /** @@ -170,7 +151,7 @@ trait ResultOperation * 查找单条记录 不存在返回空数据(或者空模型) * @access public * @param mixed $data 数据 - * @return array|Model|static + * @return array|Model|static|mixed */ public function findOrEmpty($data = null) { @@ -242,7 +223,7 @@ trait ResultOperation * 查找单条记录 如果不存在则抛出异常 * @access public * @param array|string|Query|Closure $data 数据 - * @return array|Model|static + * @return array|Model|static|mixed * @throws ModelNotFoundException * @throws DataNotFoundException */ diff --git a/vendor/topthink/think-orm/src/model/Collection.php b/vendor/topthink/think-orm/src/model/Collection.php index f017e32..c8ff385 100644 --- a/vendor/topthink/think-orm/src/model/Collection.php +++ b/vendor/topthink/think-orm/src/model/Collection.php @@ -157,7 +157,7 @@ class Collection extends BaseCollection public function withAttr($name, $callback = null) { $this->each(function (Model $model) use ($name, $callback) { - $model->withAttribute($name, $callback); + $model->withAttr($name, $callback); }); return $this; diff --git a/vendor/topthink/think-orm/src/model/concern/Attribute.php b/vendor/topthink/think-orm/src/model/concern/Attribute.php index 34cb59a..a48c74e 100644 --- a/vendor/topthink/think-orm/src/model/concern/Attribute.php +++ b/vendor/topthink/think-orm/src/model/concern/Attribute.php @@ -106,6 +106,12 @@ trait Attribute */ private $withAttr = []; + /** + * 数据处理 + * @var array + */ + private $filter = []; + /** * 获取模型对象的主键 * @access public @@ -177,6 +183,24 @@ trait Attribute return $this; } + /** + * 设置模型数据处理 + * @access public + * @param callable $filter 数据处理Callable + * @param string $index 索引(唯一) + * @return $this + */ + public function filter(callable $filter, string $index = null) + { + if ($index) { + $this->filter[$index] = $filter; + } else { + $this->filter[] = $filter; + } + + return $this; + } + /** * 获取实际的字段名 * @access protected @@ -633,11 +657,11 @@ trait Attribute * @param callable $callback 闭包获取器 * @return $this */ - public function withAttribute($name, callable $callback = null) + public function withAttr($name, callable $callback = null) { if (is_array($name)) { foreach ($name as $key => $val) { - $this->withAttribute($key, $val); + $this->withAttr($key, $val); } } else { $name = $this->getRealFieldName($name); diff --git a/vendor/topthink/think-orm/src/model/concern/Conversion.php b/vendor/topthink/think-orm/src/model/concern/Conversion.php index 35d96d0..22d6256 100644 --- a/vendor/topthink/think-orm/src/model/concern/Conversion.php +++ b/vendor/topthink/think-orm/src/model/concern/Conversion.php @@ -330,6 +330,7 @@ trait Conversion } // JsonSerializable + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->toArray(); diff --git a/vendor/topthink/think-orm/src/model/concern/SoftDelete.php b/vendor/topthink/think-orm/src/model/concern/SoftDelete.php index 8d76bb0..117f1ef 100644 --- a/vendor/topthink/think-orm/src/model/concern/SoftDelete.php +++ b/vendor/topthink/think-orm/src/model/concern/SoftDelete.php @@ -55,6 +55,16 @@ trait SoftDelete return $model->withTrashedData(true)->db(); } + /** + * 查询软删除数据 + * @access public + * @return Query + */ + public function queryWithTrashed(): Query + { + return $this->withTrashedData(true)->db(); + } + /** * 是否包含软删除数据 * @access protected @@ -86,6 +96,23 @@ trait SoftDelete return $model->db(); } + /** + * 只查询软删除数据 + * @access public + * @return Query + */ + public function queryOnlyTrashed(): Query + { + $field = $this->getDeleteTimeField(true); + + if ($field) { + return $this->db() + ->useSoftDelete($field, $this->getWithTrashedExp()); + } + + return $this->db(); + } + /** * 获取软删除数据的查询条件 * @access protected @@ -152,12 +179,12 @@ trait SoftDelete public static function destroy($data, bool $force = false): bool { // 传入空值(包括空字符串和空数组)的时候不会做任何的数据删除操作,但传入0则是有效的 - if(empty($data) && $data !== 0){ + if (empty($data) && 0 !== $data) { return false; } // 仅当强制删除时包含软删除数据 $model = (new static()); - if($force){ + if ($force) { $model->withTrashedData(true); } $query = $model->db(false); diff --git a/vendor/topthink/think-orm/src/model/relation/BelongsToMany.php b/vendor/topthink/think-orm/src/model/relation/BelongsToMany.php index 5f177c1..75eab1e 100644 --- a/vendor/topthink/think-orm/src/model/relation/BelongsToMany.php +++ b/vendor/topthink/think-orm/src/model/relation/BelongsToMany.php @@ -19,7 +19,6 @@ use think\db\Raw; use think\Model; use think\model\Pivot; use think\model\Relation; -use think\Paginator; /** * 多对多关联类 @@ -120,31 +119,6 @@ class BelongsToMany extends Relation } } - /** - * 合成中间表模型 - * @access protected - * @param array|Collection|Paginator $models - */ - protected function hydratePivot(iterable $models) - { - foreach ($models as $model) { - $pivot = []; - - foreach ($model->getData() as $key => $val) { - if (strpos($key, '__')) { - [$name, $attr] = explode('__', $key, 2); - - if ('pivot' == $name) { - $pivot[$attr] = $val; - unset($model->$key); - } - } - } - - $model->setRelation($this->pivotDataName, $this->newPivot($pivot)); - } - } - /** * 延迟获取关联数据 * @access public @@ -158,62 +132,9 @@ class BelongsToMany extends Relation $closure($this->getClosureType($closure)); } - $result = $this->relation($subRelation) + return $this->relation($subRelation) ->select() ->setParent(clone $this->parent); - - $this->hydratePivot($result); - - return $result; - } - - /** - * 重载select方法 - * @access public - * @param mixed $data - * @return Collection - */ - public function select($data = null): Collection - { - $this->baseQuery(); - $result = $this->query->select($data); - $this->hydratePivot($result); - - return $result; - } - - /** - * 重载paginate方法 - * @access public - * @param int|array $listRows - * @param int|bool $simple - * @return Paginator - */ - public function paginate($listRows = null, $simple = false): Paginator - { - $this->baseQuery(); - $result = $this->query->paginate($listRows, $simple); - $this->hydratePivot($result); - - return $result; - } - - /** - * 重载find方法 - * @access public - * @param mixed $data - * @return Model - */ - public function find($data = null) - { - $this->baseQuery(); - $result = $this->query->find($data); - - if ($result && !$result->isEmpty()) { - $this->hydratePivot([$result]); - } - - return $result; } /** @@ -673,6 +594,23 @@ class BelongsToMany extends Relation $foreignKey = $this->foreignKey; $localKey = $this->localKey; + $this->query->getModel()->filter(function ($result, $options) { + $pivot = []; + + foreach ($result->getData() as $key => $val) { + if (strpos($key, '__')) { + [$name, $attr] = explode('__', $key, 2); + + if ('pivot' == $name) { + $pivot[$attr] = $val; + unset($result->$key); + } + } + } + + $result->setRelation($this->pivotDataName, $this->newPivot($pivot)); + }); + // 关联查询 if (null === $this->parent->getKey()) { $condition = ['pivot.' . $localKey, 'exp', new Raw('=' . $this->parent->getTable() . '.' . $this->parent->getPk())];