mirror of https://github.com/1099438829/apeblog
升级vendor
This commit is contained in:
parent
b719a4b772
commit
47d436c637
|
|
@ -12,6 +12,6 @@ return array(
|
||||||
'35fab96057f1bf5e7aba31a8a6d5fdde' => $vendorDir . '/topthink/think-orm/stubs/load_stubs.php',
|
'35fab96057f1bf5e7aba31a8a6d5fdde' => $vendorDir . '/topthink/think-orm/stubs/load_stubs.php',
|
||||||
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
|
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
|
||||||
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.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',
|
'1cfd2761b63b0a29ed23657ea394cb2d' => $vendorDir . '/topthink/think-captcha/src/helper.php',
|
||||||
|
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ return array(
|
||||||
'think\\view\\driver\\' => array($vendorDir . '/topthink/think-view/src'),
|
'think\\view\\driver\\' => array($vendorDir . '/topthink/think-view/src'),
|
||||||
'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'),
|
'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'),
|
||||||
'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/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'),
|
'learn\\' => array($baseDir . '/learn'),
|
||||||
'app\\' => array($baseDir . '/app'),
|
'app\\' => array($baseDir . '/app'),
|
||||||
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
|
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
|
||||||
|
|
@ -20,6 +20,7 @@ return array(
|
||||||
'Spatie\\Macroable\\' => array($vendorDir . '/spatie/macroable/src'),
|
'Spatie\\Macroable\\' => array($vendorDir . '/spatie/macroable/src'),
|
||||||
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
|
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
|
||||||
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
|
'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\\Container\\' => array($vendorDir . '/psr/container/src'),
|
||||||
'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
|
'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
|
||||||
'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'),
|
'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'),
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ class ComposerStaticInit179ad4390eaa61356c3a52b9b610e467
|
||||||
'35fab96057f1bf5e7aba31a8a6d5fdde' => __DIR__ . '/..' . '/topthink/think-orm/stubs/load_stubs.php',
|
'35fab96057f1bf5e7aba31a8a6d5fdde' => __DIR__ . '/..' . '/topthink/think-orm/stubs/load_stubs.php',
|
||||||
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
|
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
|
||||||
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.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',
|
'1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php',
|
||||||
|
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||||
);
|
);
|
||||||
|
|
||||||
public static $prefixLengthsPsr4 = array (
|
public static $prefixLengthsPsr4 = array (
|
||||||
|
|
@ -46,6 +46,7 @@ class ComposerStaticInit179ad4390eaa61356c3a52b9b610e467
|
||||||
array (
|
array (
|
||||||
'Psr\\SimpleCache\\' => 16,
|
'Psr\\SimpleCache\\' => 16,
|
||||||
'Psr\\Log\\' => 8,
|
'Psr\\Log\\' => 8,
|
||||||
|
'Psr\\Http\\Message\\' => 17,
|
||||||
'Psr\\Container\\' => 14,
|
'Psr\\Container\\' => 14,
|
||||||
'Psr\\Cache\\' => 10,
|
'Psr\\Cache\\' => 10,
|
||||||
'PHPMailer\\PHPMailer\\' => 20,
|
'PHPMailer\\PHPMailer\\' => 20,
|
||||||
|
|
@ -83,10 +84,10 @@ class ComposerStaticInit179ad4390eaa61356c3a52b9b610e467
|
||||||
),
|
),
|
||||||
'think\\' =>
|
'think\\' =>
|
||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/..' . '/topthink/framework/src/think',
|
0 => __DIR__ . '/..' . '/topthink/think-helper/src',
|
||||||
1 => __DIR__ . '/..' . '/topthink/think-helper/src',
|
1 => __DIR__ . '/..' . '/topthink/think-template/src',
|
||||||
2 => __DIR__ . '/..' . '/topthink/think-orm/src',
|
2 => __DIR__ . '/..' . '/topthink/think-orm/src',
|
||||||
3 => __DIR__ . '/..' . '/topthink/think-template/src',
|
3 => __DIR__ . '/..' . '/topthink/framework/src/think',
|
||||||
),
|
),
|
||||||
'learn\\' =>
|
'learn\\' =>
|
||||||
array (
|
array (
|
||||||
|
|
@ -128,6 +129,10 @@ class ComposerStaticInit179ad4390eaa61356c3a52b9b610e467
|
||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
|
0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
|
||||||
),
|
),
|
||||||
|
'Psr\\Http\\Message\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/psr/http-message/src',
|
||||||
|
),
|
||||||
'Psr\\Container\\' =>
|
'Psr\\Container\\' =>
|
||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/..' . '/psr/container/src',
|
0 => __DIR__ . '/..' . '/psr/container/src',
|
||||||
|
|
|
||||||
|
|
@ -666,6 +666,68 @@
|
||||||
},
|
},
|
||||||
"install-path": "../psr/container"
|
"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",
|
"name": "psr/log",
|
||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
|
|
@ -922,17 +984,17 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/http-foundation",
|
"name": "symfony/http-foundation",
|
||||||
"version": "v5.4.1",
|
"version": "v5.4.2",
|
||||||
"version_normalized": "5.4.1.0",
|
"version_normalized": "5.4.2.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/http-foundation.git",
|
"url": "https://github.com/symfony/http-foundation.git",
|
||||||
"reference": "5dad3780023a707f4c24beac7d57aead85c1ce3c"
|
"reference": "ce952af52877eaf3eab5d0c08cc0ea865ed37313"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/5dad3780023a707f4c24beac7d57aead85c1ce3c",
|
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/ce952af52877eaf3eab5d0c08cc0ea865ed37313",
|
||||||
"reference": "5dad3780023a707f4c24beac7d57aead85c1ce3c",
|
"reference": "ce952af52877eaf3eab5d0c08cc0ea865ed37313",
|
||||||
"shasum": "",
|
"shasum": "",
|
||||||
"mirrors": [
|
"mirrors": [
|
||||||
{
|
{
|
||||||
|
|
@ -956,7 +1018,7 @@
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"symfony/mime": "To use the file extension guesser"
|
"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",
|
"type": "library",
|
||||||
"installation-source": "dist",
|
"installation-source": "dist",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
|
@ -984,7 +1046,7 @@
|
||||||
"description": "Defines an object-oriented layer for the HTTP specification",
|
"description": "Defines an object-oriented layer for the HTTP specification",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/http-foundation/tree/v5.4.1"
|
"source": "https://github.com/symfony/http-foundation/tree/v5.4.2"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
|
@ -1270,17 +1332,17 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/var-dumper",
|
"name": "symfony/var-dumper",
|
||||||
"version": "v4.4.34",
|
"version": "v4.4.36",
|
||||||
"version_normalized": "4.4.34.0",
|
"version_normalized": "4.4.36.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/var-dumper.git",
|
"url": "https://github.com/symfony/var-dumper.git",
|
||||||
"reference": "2d0c056b2faaa3d785bdbd5adecc593a5be9c16e"
|
"reference": "02685c62fcbc4262235cc72a54fbd45ab719ce3c"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/2d0c056b2faaa3d785bdbd5adecc593a5be9c16e",
|
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/02685c62fcbc4262235cc72a54fbd45ab719ce3c",
|
||||||
"reference": "2d0c056b2faaa3d785bdbd5adecc593a5be9c16e",
|
"reference": "02685c62fcbc4262235cc72a54fbd45ab719ce3c",
|
||||||
"shasum": "",
|
"shasum": "",
|
||||||
"mirrors": [
|
"mirrors": [
|
||||||
{
|
{
|
||||||
|
|
@ -1310,7 +1372,7 @@
|
||||||
"ext-intl": "To show region name in time zone dump",
|
"ext-intl": "To show region name in time zone dump",
|
||||||
"symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
|
"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": [
|
"bin": [
|
||||||
"Resources/bin/var-dump-server"
|
"Resources/bin/var-dump-server"
|
||||||
],
|
],
|
||||||
|
|
@ -1348,7 +1410,7 @@
|
||||||
"dump"
|
"dump"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/var-dumper/tree/v4.4.34"
|
"source": "https://github.com/symfony/var-dumper/tree/v4.4.36"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
|
@ -1368,17 +1430,17 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "topthink/framework",
|
"name": "topthink/framework",
|
||||||
"version": "v6.0.9",
|
"version": "v6.0.10",
|
||||||
"version_normalized": "6.0.9.0",
|
"version_normalized": "6.0.10.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/top-think/framework.git",
|
"url": "https://github.com/top-think/framework.git",
|
||||||
"reference": "0b5fb453f0e533de3af3a1ab6a202510b61be617"
|
"reference": "109ade68d6ad3b10af5c8d9d8f53161a513eec18"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/top-think/framework/zipball/0b5fb453f0e533de3af3a1ab6a202510b61be617",
|
"url": "https://api.github.com/repos/top-think/framework/zipball/109ade68d6ad3b10af5c8d9d8f53161a513eec18",
|
||||||
"reference": "0b5fb453f0e533de3af3a1ab6a202510b61be617",
|
"reference": "109ade68d6ad3b10af5c8d9d8f53161a513eec18",
|
||||||
"shasum": "",
|
"shasum": "",
|
||||||
"mirrors": [
|
"mirrors": [
|
||||||
{
|
{
|
||||||
|
|
@ -1394,17 +1456,19 @@
|
||||||
"league/flysystem-cached-adapter": "^1.0",
|
"league/flysystem-cached-adapter": "^1.0",
|
||||||
"php": ">=7.2.5",
|
"php": ">=7.2.5",
|
||||||
"psr/container": "~1.0",
|
"psr/container": "~1.0",
|
||||||
|
"psr/http-message": "^1.0",
|
||||||
"psr/log": "~1.0",
|
"psr/log": "~1.0",
|
||||||
"psr/simple-cache": "^1.0",
|
"psr/simple-cache": "^1.0",
|
||||||
"topthink/think-helper": "^3.1.1",
|
"topthink/think-helper": "^3.1.1",
|
||||||
"topthink/think-orm": "^2.0"
|
"topthink/think-orm": "^2.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
"guzzlehttp/psr7": "^2.1.0",
|
||||||
"mikey179/vfsstream": "^1.6",
|
"mikey179/vfsstream": "^1.6",
|
||||||
"mockery/mockery": "^1.2",
|
"mockery/mockery": "^1.2",
|
||||||
"phpunit/phpunit": "^7.0"
|
"phpunit/phpunit": "^7.0"
|
||||||
},
|
},
|
||||||
"time": "2021-07-22T03:24:49+00:00",
|
"time": "2021-12-30T13:54:49+00:00",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"installation-source": "dist",
|
"installation-source": "dist",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
|
@ -1436,7 +1500,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/top-think/framework/issues",
|
"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"
|
"install-path": "../topthink/framework"
|
||||||
},
|
},
|
||||||
|
|
@ -1613,17 +1677,17 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "topthink/think-orm",
|
"name": "topthink/think-orm",
|
||||||
"version": "v2.0.45",
|
"version": "v2.0.46",
|
||||||
"version_normalized": "2.0.45.0",
|
"version_normalized": "2.0.46.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/top-think/think-orm.git",
|
"url": "https://github.com/top-think/think-orm.git",
|
||||||
"reference": "3dcf9af447b048103093840833e8c74ab849152f"
|
"reference": "51ec287abdb99521dbbc66526b114f2e32b8fff4"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/3dcf9af447b048103093840833e8c74ab849152f",
|
"url": "https://api.github.com/repos/top-think/think-orm/zipball/51ec287abdb99521dbbc66526b114f2e32b8fff4",
|
||||||
"reference": "3dcf9af447b048103093840833e8c74ab849152f",
|
"reference": "51ec287abdb99521dbbc66526b114f2e32b8fff4",
|
||||||
"shasum": "",
|
"shasum": "",
|
||||||
"mirrors": [
|
"mirrors": [
|
||||||
{
|
{
|
||||||
|
|
@ -1643,7 +1707,7 @@
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^7|^8|^9.5"
|
"phpunit/phpunit": "^7|^8|^9.5"
|
||||||
},
|
},
|
||||||
"time": "2021-11-30T14:31:05+00:00",
|
"time": "2021-12-29T05:48:27+00:00",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"installation-source": "dist",
|
"installation-source": "dist",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
|
@ -1671,7 +1735,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/top-think/think-orm/issues",
|
"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"
|
"install-path": "../topthink/think-orm"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
'type' => 'project',
|
'type' => 'project',
|
||||||
'install_path' => __DIR__ . '/../../',
|
'install_path' => __DIR__ . '/../../',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'reference' => 'cb1402d64f9ca93ea47960ba194212d469fd5d98',
|
'reference' => 'b719a4b772e06fd2165da8eb317ef17bc73126ed',
|
||||||
'name' => 'topthink/think',
|
'name' => 'topthink/think',
|
||||||
'dev' => true,
|
'dev' => true,
|
||||||
),
|
),
|
||||||
|
|
@ -91,6 +91,15 @@
|
||||||
'reference' => '8622567409010282b7aeebe4bb841fe98b58dcaf',
|
'reference' => '8622567409010282b7aeebe4bb841fe98b58dcaf',
|
||||||
'dev_requirement' => false,
|
'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(
|
'psr/log' => array(
|
||||||
'pretty_version' => '1.1.4',
|
'pretty_version' => '1.1.4',
|
||||||
'version' => '1.1.4.0',
|
'version' => '1.1.4.0',
|
||||||
|
|
@ -128,12 +137,12 @@
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/http-foundation' => array(
|
'symfony/http-foundation' => array(
|
||||||
'pretty_version' => 'v5.4.1',
|
'pretty_version' => 'v5.4.2',
|
||||||
'version' => '5.4.1.0',
|
'version' => '5.4.2.0',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/http-foundation',
|
'install_path' => __DIR__ . '/../symfony/http-foundation',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'reference' => '5dad3780023a707f4c24beac7d57aead85c1ce3c',
|
'reference' => 'ce952af52877eaf3eab5d0c08cc0ea865ed37313',
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/polyfill-mbstring' => array(
|
'symfony/polyfill-mbstring' => array(
|
||||||
|
|
@ -164,21 +173,21 @@
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/var-dumper' => array(
|
'symfony/var-dumper' => array(
|
||||||
'pretty_version' => 'v4.4.34',
|
'pretty_version' => 'v4.4.36',
|
||||||
'version' => '4.4.34.0',
|
'version' => '4.4.36.0',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/var-dumper',
|
'install_path' => __DIR__ . '/../symfony/var-dumper',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'reference' => '2d0c056b2faaa3d785bdbd5adecc593a5be9c16e',
|
'reference' => '02685c62fcbc4262235cc72a54fbd45ab719ce3c',
|
||||||
'dev_requirement' => true,
|
'dev_requirement' => true,
|
||||||
),
|
),
|
||||||
'topthink/framework' => array(
|
'topthink/framework' => array(
|
||||||
'pretty_version' => 'v6.0.9',
|
'pretty_version' => 'v6.0.10',
|
||||||
'version' => '6.0.9.0',
|
'version' => '6.0.10.0',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../topthink/framework',
|
'install_path' => __DIR__ . '/../topthink/framework',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'reference' => '0b5fb453f0e533de3af3a1ab6a202510b61be617',
|
'reference' => '109ade68d6ad3b10af5c8d9d8f53161a513eec18',
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'topthink/think' => array(
|
'topthink/think' => array(
|
||||||
|
|
@ -187,7 +196,7 @@
|
||||||
'type' => 'project',
|
'type' => 'project',
|
||||||
'install_path' => __DIR__ . '/../../',
|
'install_path' => __DIR__ . '/../../',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'reference' => 'cb1402d64f9ca93ea47960ba194212d469fd5d98',
|
'reference' => 'b719a4b772e06fd2165da8eb317ef17bc73126ed',
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'topthink/think-captcha' => array(
|
'topthink/think-captcha' => array(
|
||||||
|
|
@ -218,12 +227,12 @@
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'topthink/think-orm' => array(
|
'topthink/think-orm' => array(
|
||||||
'pretty_version' => 'v2.0.45',
|
'pretty_version' => 'v2.0.46',
|
||||||
'version' => '2.0.45.0',
|
'version' => '2.0.46.0',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../topthink/think-orm',
|
'install_path' => __DIR__ . '/../topthink/think-orm',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'reference' => '3dcf9af447b048103093840833e8c74ab849152f',
|
'reference' => '51ec287abdb99521dbbc66526b114f2e32b8fff4',
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'topthink/think-template' => array(
|
'topthink/think-template' => array(
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
// This file is automatically generated at:2021-12-26 21:35:37
|
// This file is automatically generated at:2021-12-31 01:32:01
|
||||||
declare (strict_types = 1);
|
declare (strict_types = 1);
|
||||||
return array (
|
return array (
|
||||||
0 => 'think\\captcha\\CaptchaService',
|
0 => 'think\\captcha\\CaptchaService',
|
||||||
|
|
|
||||||
|
|
@ -154,8 +154,6 @@ class HeaderUtils
|
||||||
* is semantically equivalent to $filename. If the filename is already ASCII,
|
* is semantically equivalent to $filename. If the filename is already ASCII,
|
||||||
* it can be omitted, or just copied from $filename
|
* it can be omitted, or just copied from $filename
|
||||||
*
|
*
|
||||||
* @return string
|
|
||||||
*
|
|
||||||
* @throws \InvalidArgumentException
|
* @throws \InvalidArgumentException
|
||||||
*
|
*
|
||||||
* @see RFC 6266
|
* @see RFC 6266
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ class ServerBag extends ParameterBag
|
||||||
|
|
||||||
// PHP_AUTH_USER/PHP_AUTH_PW
|
// PHP_AUTH_USER/PHP_AUTH_PW
|
||||||
if (isset($headers['PHP_AUTH_USER'])) {
|
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'])) {
|
} elseif (isset($headers['PHP_AUTH_DIGEST'])) {
|
||||||
$headers['AUTHORIZATION'] = $headers['PHP_AUTH_DIGEST'];
|
$headers['AUTHORIZATION'] = $headers['PHP_AUTH_DIGEST'];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -663,7 +663,7 @@ class PdoSessionHandler extends AbstractSessionHandler
|
||||||
$selectStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
|
$selectStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
|
||||||
$insertStmt = null;
|
$insertStmt = null;
|
||||||
|
|
||||||
do {
|
while (true) {
|
||||||
$selectStmt->execute();
|
$selectStmt->execute();
|
||||||
$sessionRows = $selectStmt->fetchAll(\PDO::FETCH_NUM);
|
$sessionRows = $selectStmt->fetchAll(\PDO::FETCH_NUM);
|
||||||
|
|
||||||
|
|
@ -712,7 +712,7 @@ class PdoSessionHandler extends AbstractSessionHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
} while (true);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ class ReflectionCaster
|
||||||
array_unshift($trace, [
|
array_unshift($trace, [
|
||||||
'function' => 'yield',
|
'function' => 'yield',
|
||||||
'file' => $function->getExecutingFile(),
|
'file' => $function->getExecutingFile(),
|
||||||
'line' => $function->getExecutingLine() - 1,
|
'line' => $function->getExecutingLine() - (int) (\PHP_VERSION_ID < 80100),
|
||||||
]);
|
]);
|
||||||
$trace[] = $frame;
|
$trace[] = $frame;
|
||||||
$a[$prefix.'trace'] = new TraceStub($trace, false, 0, -1, -1);
|
$a[$prefix.'trace'] = new TraceStub($trace, false, 0, -1, -1);
|
||||||
|
|
@ -263,6 +263,7 @@ class ReflectionCaster
|
||||||
unset($a[$prefix.'allowsNull']);
|
unset($a[$prefix.'allowsNull']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($c->isOptional()) {
|
||||||
try {
|
try {
|
||||||
$a[$prefix.'default'] = $v = $c->getDefaultValue();
|
$a[$prefix.'default'] = $v = $c->getDefaultValue();
|
||||||
if ($c->isDefaultValueConstant()) {
|
if ($c->isDefaultValueConstant()) {
|
||||||
|
|
@ -273,6 +274,7 @@ class ReflectionCaster
|
||||||
}
|
}
|
||||||
} catch (\ReflectionException $e) {
|
} catch (\ReflectionException $e) {
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $a;
|
return $a;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ ThinkPHP6.0底层架构采用PHP7.1改写和进一步优化。
|
||||||
* 统一和精简大量用法
|
* 统一和精简大量用法
|
||||||
|
|
||||||
|
|
||||||
> ThinkPHP6.0的运行环境要求PHP7.1+,兼容PHP8.0。
|
> ThinkPHP6.0的运行环境要求PHP7.2+,兼容PHP8.1
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,13 +27,15 @@
|
||||||
"psr/log": "~1.0",
|
"psr/log": "~1.0",
|
||||||
"psr/container": "~1.0",
|
"psr/container": "~1.0",
|
||||||
"psr/simple-cache": "^1.0",
|
"psr/simple-cache": "^1.0",
|
||||||
|
"psr/http-message": "^1.0",
|
||||||
"topthink/think-orm": "^2.0",
|
"topthink/think-orm": "^2.0",
|
||||||
"topthink/think-helper": "^3.1.1"
|
"topthink/think-helper": "^3.1.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"mikey179/vfsstream": "^1.6",
|
"mikey179/vfsstream": "^1.6",
|
||||||
"mockery/mockery": "^1.2",
|
"mockery/mockery": "^1.2",
|
||||||
"phpunit/phpunit": "^7.0"
|
"phpunit/phpunit": "^7.0",
|
||||||
|
"guzzlehttp/psr7": "^2.1.0"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"files": [],
|
"files": [],
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ if (!function_exists('cookie')) {
|
||||||
{
|
{
|
||||||
if (is_null($value)) {
|
if (is_null($value)) {
|
||||||
// 删除
|
// 删除
|
||||||
Cookie::delete($name);
|
Cookie::delete($name, $option ?: []);
|
||||||
} elseif ('' === $value) {
|
} elseif ('' === $value) {
|
||||||
// 获取
|
// 获取
|
||||||
return 0 === strpos($name, '?') ? Cookie::has(substr($name, 1)) : Cookie::get($name);
|
return 0 === strpos($name, '?') ? Cookie::has(substr($name, 1)) : Cookie::get($name);
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ use think\initializer\RegisterService;
|
||||||
*/
|
*/
|
||||||
class App extends Container
|
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 = '')
|
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->rootPath = $rootPath ? rtrim($rootPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $this->getDefaultRootPath();
|
||||||
$this->appPath = $this->rootPath . 'app' . DIRECTORY_SEPARATOR;
|
$this->appPath = $this->rootPath . 'app' . DIRECTORY_SEPARATOR;
|
||||||
$this->runtimePath = $this->rootPath . 'runtime' . DIRECTORY_SEPARATOR;
|
$this->runtimePath = $this->rootPath . 'runtime' . DIRECTORY_SEPARATOR;
|
||||||
|
|
@ -450,13 +450,8 @@ class App extends Container
|
||||||
// 加载全局初始化文件
|
// 加载全局初始化文件
|
||||||
$this->load();
|
$this->load();
|
||||||
|
|
||||||
// 加载框架默认语言包
|
|
||||||
$langSet = $this->lang->defaultLangSet();
|
|
||||||
|
|
||||||
$this->lang->load($this->thinkPath . 'lang' . DIRECTORY_SEPARATOR . $langSet . '.php');
|
|
||||||
|
|
||||||
// 加载应用默认语言包
|
// 加载应用默认语言包
|
||||||
$this->loadLangPack($langSet);
|
$this->loadLangPack();
|
||||||
|
|
||||||
// 监听AppInit
|
// 监听AppInit
|
||||||
$this->event->trigger(AppInit::class);
|
$this->event->trigger(AppInit::class);
|
||||||
|
|
@ -482,25 +477,13 @@ class App extends Container
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载语言包
|
* 加载语言包
|
||||||
* @param string $langset 语言
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function loadLangPack($langset)
|
public function loadLangPack()
|
||||||
{
|
{
|
||||||
if (empty($langset)) {
|
// 加载默认语言包
|
||||||
return;
|
$langSet = $this->lang->defaultLangSet();
|
||||||
}
|
$this->lang->switchLangSet($langSet);
|
||||||
|
|
||||||
// 加载系统语言包
|
|
||||||
$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]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ use ReflectionMethod;
|
||||||
use think\exception\ClassNotFoundException;
|
use think\exception\ClassNotFoundException;
|
||||||
use think\exception\FuncNotFoundException;
|
use think\exception\FuncNotFoundException;
|
||||||
use think\helper\Str;
|
use think\helper\Str;
|
||||||
|
use Traversable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 容器管理类 支持PSR-11
|
* 容器管理类 支持PSR-11
|
||||||
|
|
@ -520,34 +521,38 @@ class Container implements ContainerInterface, ArrayAccess, IteratorAggregate, C
|
||||||
$this->delete($name);
|
$this->delete($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function offsetExists($key)
|
#[\ReturnTypeWillChange]
|
||||||
|
public function offsetExists($key): bool
|
||||||
{
|
{
|
||||||
return $this->exists($key);
|
return $this->exists($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetGet($key)
|
public function offsetGet($key)
|
||||||
{
|
{
|
||||||
return $this->make($key);
|
return $this->make($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetSet($key, $value)
|
public function offsetSet($key, $value)
|
||||||
{
|
{
|
||||||
$this->bind($key, $value);
|
$this->bind($key, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetUnset($key)
|
public function offsetUnset($key)
|
||||||
{
|
{
|
||||||
$this->delete($key);
|
$this->delete($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Countable
|
//Countable
|
||||||
public function count()
|
public function count(): int
|
||||||
{
|
{
|
||||||
return count($this->instances);
|
return count($this->instances);
|
||||||
}
|
}
|
||||||
|
|
||||||
//IteratorAggregate
|
//IteratorAggregate
|
||||||
public function getIterator()
|
public function getIterator(): Traversable
|
||||||
{
|
{
|
||||||
return new ArrayIterator($this->instances);
|
return new ArrayIterator($this->instances);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -158,11 +158,13 @@ class Cookie
|
||||||
* Cookie删除
|
* Cookie删除
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $name cookie名称
|
* @param string $name cookie名称
|
||||||
|
* @param array $options cookie参数
|
||||||
* @return void
|
* @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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ class Env implements ArrayAccess
|
||||||
*/
|
*/
|
||||||
public function load(string $file): void
|
public function load(string $file): void
|
||||||
{
|
{
|
||||||
$env = parse_ini_file($file, true) ?: [];
|
$env = parse_ini_file($file, true, INI_SCANNER_RAW) ?: [];
|
||||||
$this->set($env);
|
$this->set($env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,21 +159,25 @@ class Env implements ArrayAccess
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArrayAccess
|
// ArrayAccess
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetSet($name, $value): void
|
public function offsetSet($name, $value): void
|
||||||
{
|
{
|
||||||
$this->set($name, $value);
|
$this->set($name, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetExists($name): bool
|
public function offsetExists($name): bool
|
||||||
{
|
{
|
||||||
return $this->__isset($name);
|
return $this->__isset($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetUnset($name)
|
public function offsetUnset($name)
|
||||||
{
|
{
|
||||||
throw new Exception('not support: unset');
|
throw new Exception('not support: unset');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetGet($name)
|
public function offsetGet($name)
|
||||||
{
|
{
|
||||||
return $this->get($name);
|
return $this->get($name);
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ class File extends SplFileInfo
|
||||||
$this->hashName = call_user_func($rule);
|
$this->hashName = call_user_func($rule);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$this->hashName = date('Ymd') . DIRECTORY_SEPARATOR . md5((string) microtime(true));
|
$this->hashName = date('Ymd') . DIRECTORY_SEPARATOR . md5(microtime(true) . $this->getPathname());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ namespace think;
|
||||||
*/
|
*/
|
||||||
class Lang
|
class Lang
|
||||||
{
|
{
|
||||||
|
protected $app;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配置参数
|
* 配置参数
|
||||||
* @var array
|
* @var array
|
||||||
|
|
@ -62,15 +64,26 @@ class Lang
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $config
|
* @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->config = array_merge($this->config, array_change_key_case($config));
|
||||||
$this->range = $this->config['default_lang'];
|
$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'];
|
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
|
* @access public
|
||||||
|
|
@ -202,6 +244,10 @@ class Lang
|
||||||
{
|
{
|
||||||
$range = $range ?: $this->range;
|
$range = $range ?: $this->range;
|
||||||
|
|
||||||
|
if (!isset($this->lang[$range])) {
|
||||||
|
$this->switchLangSet($range);
|
||||||
|
}
|
||||||
|
|
||||||
// 空参数返回所有定义
|
// 空参数返回所有定义
|
||||||
if (is_null($name)) {
|
if (is_null($name)) {
|
||||||
return $this->lang[$range] ?? [];
|
return $this->lang[$range] ?? [];
|
||||||
|
|
@ -241,6 +287,7 @@ class Lang
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自动侦测设置获取语言选择
|
* 自动侦测设置获取语言选择
|
||||||
|
* @deprecated
|
||||||
* @access public
|
* @access public
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return string
|
* @return string
|
||||||
|
|
@ -280,6 +327,7 @@ class Lang
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存当前语言到Cookie
|
* 保存当前语言到Cookie
|
||||||
|
* @deprecated
|
||||||
* @access public
|
* @access public
|
||||||
* @param Cookie $cookie Cookie对象
|
* @param Cookie $cookie Cookie对象
|
||||||
* @return void
|
* @return void
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ declare (strict_types = 1);
|
||||||
namespace think;
|
namespace think;
|
||||||
|
|
||||||
use ArrayAccess;
|
use ArrayAccess;
|
||||||
|
use think\facade\Lang;
|
||||||
use think\file\UploadedFile;
|
use think\file\UploadedFile;
|
||||||
use think\route\Rule;
|
use think\route\Rule;
|
||||||
|
|
||||||
|
|
@ -1227,7 +1228,7 @@ class Request implements ArrayAccess
|
||||||
7 => 'file write error',
|
7 => 'file write error',
|
||||||
];
|
];
|
||||||
|
|
||||||
$msg = $fileUploadErrors[$error];
|
$msg = Lang::get($fileUploadErrors[$error]);
|
||||||
throw new Exception($msg, $error);
|
throw new Exception($msg, $error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2150,19 +2151,23 @@ class Request implements ArrayAccess
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArrayAccess
|
// ArrayAccess
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetExists($name): bool
|
public function offsetExists($name): bool
|
||||||
{
|
{
|
||||||
return $this->has($name);
|
return $this->has($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetGet($name)
|
public function offsetGet($name)
|
||||||
{
|
{
|
||||||
return $this->param($name);
|
return $this->param($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetSet($name, $value)
|
public function offsetSet($name, $value)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetUnset($name)
|
public function offsetUnset($name)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,8 @@ abstract class Response
|
||||||
// 处理输出数据
|
// 处理输出数据
|
||||||
$data = $this->getContent();
|
$data = $this->getContent();
|
||||||
|
|
||||||
if (!headers_sent() && !empty($this->header)) {
|
if (!headers_sent()) {
|
||||||
|
if (!empty($this->header)) {
|
||||||
// 发送状态码
|
// 发送状态码
|
||||||
http_response_code($this->code);
|
http_response_code($this->code);
|
||||||
// 发送头部信息
|
// 发送头部信息
|
||||||
|
|
@ -138,9 +139,11 @@ abstract class Response
|
||||||
header($name . (!is_null($val) ? ':' . $val : ''));
|
header($name . (!is_null($val) ? ':' . $val : ''));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->cookie) {
|
if ($this->cookie) {
|
||||||
$this->cookie->save();
|
$this->cookie->save();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->sendData($data);
|
$this->sendData($data);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ abstract class Make extends Command
|
||||||
|
|
||||||
protected function getPathName(string $name): string
|
protected function getPathName(string $name): string
|
||||||
{
|
{
|
||||||
$name = str_replace('app\\', '', $name);
|
$name = substr($name, 4);
|
||||||
|
|
||||||
return $this->app->getBasePath() . ltrim(str_replace('\\', '/', $name), '/') . '.php';
|
return $this->app->getBasePath() . ltrim(str_replace('\\', '/', $name), '/') . '.php';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,14 +91,13 @@ class RouteList extends Command
|
||||||
|
|
||||||
foreach ($routeList as $item) {
|
foreach ($routeList as $item) {
|
||||||
$item['route'] = $item['route'] instanceof \Closure ? '<Closure>' : $item['route'];
|
$item['route'] = $item['route'] instanceof \Closure ? '<Closure>' : $item['route'];
|
||||||
|
$row = [$item['rule'], $item['route'], $item['method'], $item['name']];
|
||||||
|
|
||||||
if ($this->input->hasOption('more')) {
|
if ($this->input->hasOption('more')) {
|
||||||
$item = [$item['rule'], $item['route'], $item['method'], $item['name'], $item['domain'], json_encode($item['option']), json_encode($item['pattern'])];
|
array_push($row, $item['domain'], json_encode($item['option']), json_encode($item['pattern']));
|
||||||
} else {
|
|
||||||
$item = [$item['rule'], $item['route'], $item['method'], $item['name']];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$rows[] = $item;
|
$rows[] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->input->getOption('sort')) {
|
if ($this->input->getOption('sort')) {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ use League\Flysystem\Adapter\AbstractAdapter;
|
||||||
use League\Flysystem\Cached\CachedAdapter;
|
use League\Flysystem\Cached\CachedAdapter;
|
||||||
use League\Flysystem\Cached\Storage\Memory as MemoryStore;
|
use League\Flysystem\Cached\Storage\Memory as MemoryStore;
|
||||||
use League\Flysystem\Filesystem;
|
use League\Flysystem\Filesystem;
|
||||||
|
use RuntimeException;
|
||||||
use think\Cache;
|
use think\Cache;
|
||||||
use think\File;
|
use think\File;
|
||||||
|
|
||||||
|
|
@ -91,6 +92,16 @@ abstract class Driver
|
||||||
return $path;
|
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 路径
|
* @param string $path 路径
|
||||||
|
|
|
||||||
|
|
@ -41,4 +41,12 @@ class Local extends Driver
|
||||||
$permissions
|
$permissions
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function url(string $path): string
|
||||||
|
{
|
||||||
|
if (isset($this->config['url'])) {
|
||||||
|
return $this->concatPathToUrl($this->config['url'], $path);
|
||||||
|
}
|
||||||
|
return parent::url($path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,9 @@ class File implements LogHandlerInterface
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (count($files) > $this->config['max_files']) {
|
if (count($files) > $this->config['max_files']) {
|
||||||
|
set_error_handler(function ($errno, $errstr, $errfile, $errline) {});
|
||||||
unlink($files[0]);
|
unlink($files[0]);
|
||||||
|
restore_error_handler();
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ namespace think\middleware;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use think\App;
|
use think\App;
|
||||||
|
use think\Config;
|
||||||
|
use think\Cookie;
|
||||||
use think\Lang;
|
use think\Lang;
|
||||||
use think\Request;
|
use think\Request;
|
||||||
use think\Response;
|
use think\Response;
|
||||||
|
|
@ -24,13 +26,14 @@ use think\Response;
|
||||||
class LoadLangPack
|
class LoadLangPack
|
||||||
{
|
{
|
||||||
protected $app;
|
protected $app;
|
||||||
|
|
||||||
protected $lang;
|
protected $lang;
|
||||||
|
protected $config;
|
||||||
|
|
||||||
public function __construct(App $app, Lang $lang)
|
public function __construct(App $app, Lang $lang, Config $config)
|
||||||
{
|
{
|
||||||
$this->app = $app;
|
$this->app = $app;
|
||||||
$this->lang = $lang;
|
$this->lang = $lang;
|
||||||
|
$this->config = $lang->getConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -43,19 +46,71 @@ class LoadLangPack
|
||||||
public function handle($request, Closure $next)
|
public function handle($request, Closure $next)
|
||||||
{
|
{
|
||||||
// 自动侦测当前语言
|
// 自动侦测当前语言
|
||||||
$langset = $this->lang->detect($request);
|
$langset = $this->detect($request);
|
||||||
|
|
||||||
if ($this->lang->defaultLangSet() != $langset) {
|
if ($this->lang->defaultLangSet() != $langset) {
|
||||||
// 加载系统语言包
|
$this->lang->switchLangSet($langset);
|
||||||
$this->lang->load([
|
|
||||||
$this->app->getThinkPath() . 'lang' . DIRECTORY_SEPARATOR . $langset . '.php',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->app->LoadLangPack($langset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->lang->saveToCookie($this->app->cookie);
|
$this->saveToCookie($this->app->cookie, $langset);
|
||||||
|
|
||||||
return $next($request);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ declare (strict_types = 1);
|
||||||
|
|
||||||
namespace think\route;
|
namespace think\route;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use think\App;
|
use think\App;
|
||||||
use think\Container;
|
use think\Container;
|
||||||
use think\Request;
|
use think\Request;
|
||||||
|
|
@ -94,6 +95,12 @@ abstract class Dispatch
|
||||||
{
|
{
|
||||||
if ($data instanceof Response) {
|
if ($data instanceof Response) {
|
||||||
$response = $data;
|
$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)) {
|
} elseif (!is_null($data)) {
|
||||||
// 默认自动识别响应输出类型
|
// 默认自动识别响应输出类型
|
||||||
$type = $this->request->isJson() ? 'json' : 'html';
|
$type = $this->request->isJson() ? 'json' : 'html';
|
||||||
|
|
|
||||||
|
|
@ -320,7 +320,7 @@ class Url
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($pattern)) {
|
if (empty($pattern)) {
|
||||||
return [rtrim($url, '?/-'), $domain, $suffix];
|
return [rtrim($url, '?-'), $domain, $suffix];
|
||||||
}
|
}
|
||||||
|
|
||||||
$type = $this->route->config('url_common_param');
|
$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);
|
$url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key, '<' . $key . '>'], $type ? (string) $vars[$key] : urlencode((string) $vars[$key]), $url);
|
||||||
$keys[] = $key;
|
$keys[] = $key;
|
||||||
$url = str_replace(['/?', '-?'], ['/', '-'], $url);
|
$url = str_replace(['/?', '-?'], ['/', '-'], $url);
|
||||||
$result = [rtrim($url, '?/-'), $domain, $suffix];
|
$result = [rtrim($url, '?-'), $domain, $suffix];
|
||||||
} elseif (2 == $val) {
|
} elseif (2 == $val) {
|
||||||
$url = str_replace(['/[:' . $key . ']', '[:' . $key . ']', '<' . $key . '?>'], '', $url);
|
$url = str_replace(['/[:' . $key . ']', '[:' . $key . ']', '<' . $key . '?>'], '', $url);
|
||||||
$url = str_replace(['/?', '-?'], ['/', '-'], $url);
|
$url = str_replace(['/?', '-?'], ['/', '-'], $url);
|
||||||
$result = [rtrim($url, '?/-'), $domain, $suffix];
|
$result = [rtrim($url, '?-'), $domain, $suffix];
|
||||||
} else {
|
} else {
|
||||||
$result = null;
|
$result = null;
|
||||||
$keys = [];
|
$keys = [];
|
||||||
|
|
|
||||||
|
|
@ -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
|
* @access public
|
||||||
|
|
@ -128,30 +135,34 @@ class Controller extends Dispatch
|
||||||
$reflectionProperty->setAccessible(true);
|
$reflectionProperty->setAccessible(true);
|
||||||
|
|
||||||
$middlewares = $reflectionProperty->getValue($controller);
|
$middlewares = $reflectionProperty->getValue($controller);
|
||||||
|
$action = $this->request->action(true);
|
||||||
|
|
||||||
foreach ($middlewares as $key => $val) {
|
foreach ($middlewares as $key => $val) {
|
||||||
if (!is_int($key)) {
|
if (!is_int($key)) {
|
||||||
if (isset($val['only']) && !in_array($this->request->action(true), array_map(function ($item) {
|
$middleware = $key;
|
||||||
return strtolower($item);
|
$options = $val;
|
||||||
}, is_string($val['only']) ? explode(",", $val['only']) : $val['only']))) {
|
} elseif (isset($val['middleware'])) {
|
||||||
continue;
|
$middleware = $val['middleware'];
|
||||||
} elseif (isset($val['except']) && in_array($this->request->action(true), array_map(function ($item) {
|
$options = $val['options'] ?? [];
|
||||||
return strtolower($item);
|
|
||||||
}, is_string($val['except']) ? explode(',', $val['except']) : $val['except']))) {
|
|
||||||
continue;
|
|
||||||
} else {
|
} else {
|
||||||
$val = $key;
|
$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, ':')) {
|
$this->app->middleware->controller($middleware);
|
||||||
$val = explode(':', $val);
|
|
||||||
if (count($val) > 1) {
|
|
||||||
$val = [$val[0], array_slice($val, 1)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->app->middleware->controller($val);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,6 @@ class EnvTest extends TestCase
|
||||||
|
|
||||||
$this->assertEquals('value1', $env->get('key1'));
|
$this->assertEquals('value1', $env->get('key1'));
|
||||||
$this->assertEquals('value2', $env->get('key2'));
|
$this->assertEquals('value2', $env->get('key2'));
|
||||||
|
|
||||||
$this->assertSame(['KEY1' => 'value1', 'KEY2' => 'value2'], $env->get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testServerEnv()
|
public function testServerEnv()
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,10 @@ class RouteTest extends TestCase
|
||||||
$this->createMiddleware()->mockery_getName() . ":params1:params2",
|
$this->createMiddleware()->mockery_getName() . ":params1:params2",
|
||||||
$this->createMiddleware(0)->mockery_getName() => ['except' => 'bar'],
|
$this->createMiddleware(0)->mockery_getName() => ['except' => 'bar'],
|
||||||
$this->createMiddleware()->mockery_getName() => ['only' => '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());
|
$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 = m::mock(FooClass::class);
|
||||||
$controller->shouldReceive('index')->andReturn('bar');
|
$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);
|
$this->app->shouldReceive('make')->with($controller->mockery_getName(), [], true)->andReturn($controller);
|
||||||
|
|
||||||
$request = $this->makeRequest('foo');
|
$request = $this->makeRequest('foo');
|
||||||
|
|
|
||||||
|
|
@ -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();
|
$this->initialize();
|
||||||
}
|
}
|
||||||
|
|
@ -262,9 +285,10 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $data 数据
|
* @param array $data 数据
|
||||||
* @param mixed $where 更新条件
|
* @param mixed $where 更新条件
|
||||||
|
* @param array $options 参数
|
||||||
* @return Model
|
* @return Model
|
||||||
*/
|
*/
|
||||||
public function newInstance(array $data = [], $where = null): Model
|
public function newInstance(array $data = [], $where = null, array $options = []): Model
|
||||||
{
|
{
|
||||||
$model = new static($data);
|
$model = new static($data);
|
||||||
|
|
||||||
|
|
@ -284,6 +308,11 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
|
||||||
|
|
||||||
$model->setUpdateWhere($where);
|
$model->setUpdateWhere($where);
|
||||||
|
|
||||||
|
// 查询数据处理
|
||||||
|
foreach ($this->filter as $filter) {
|
||||||
|
call_user_func_array($filter, [$model, $options]);
|
||||||
|
}
|
||||||
|
|
||||||
$model->trigger('AfterRead');
|
$model->trigger('AfterRead');
|
||||||
|
|
||||||
return $model;
|
return $model;
|
||||||
|
|
@ -970,21 +999,25 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArrayAccess
|
// ArrayAccess
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetSet($name, $value)
|
public function offsetSet($name, $value)
|
||||||
{
|
{
|
||||||
$this->setAttr($name, $value);
|
$this->setAttr($name, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetExists($name): bool
|
public function offsetExists($name): bool
|
||||||
{
|
{
|
||||||
return $this->__isset($name);
|
return $this->__isset($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetUnset($name)
|
public function offsetUnset($name)
|
||||||
{
|
{
|
||||||
$this->__unset($name);
|
$this->__unset($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetGet($name)
|
public function offsetGet($name)
|
||||||
{
|
{
|
||||||
return $this->getAttr($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);
|
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);
|
return call_user_func_array([$this->db(), $method], $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,8 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
|
||||||
* @return Traversable An instance of an object implementing <b>Iterator</b> or
|
* @return Traversable An instance of an object implementing <b>Iterator</b> or
|
||||||
* <b>Traversable</b>
|
* <b>Traversable</b>
|
||||||
*/
|
*/
|
||||||
public function getIterator()
|
#[\ReturnTypeWillChange]
|
||||||
|
public function getIterator(): Traversable
|
||||||
{
|
{
|
||||||
return new ArrayIterator($this->items->all());
|
return new ArrayIterator($this->items->all());
|
||||||
}
|
}
|
||||||
|
|
@ -421,7 +422,8 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
|
||||||
* @param mixed $offset
|
* @param mixed $offset
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function offsetExists($offset)
|
#[\ReturnTypeWillChange]
|
||||||
|
public function offsetExists($offset): bool
|
||||||
{
|
{
|
||||||
return $this->items->offsetExists($offset);
|
return $this->items->offsetExists($offset);
|
||||||
}
|
}
|
||||||
|
|
@ -432,6 +434,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
|
||||||
* @param mixed $offset
|
* @param mixed $offset
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetGet($offset)
|
public function offsetGet($offset)
|
||||||
{
|
{
|
||||||
return $this->items->offsetGet($offset);
|
return $this->items->offsetGet($offset);
|
||||||
|
|
@ -443,6 +446,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
|
||||||
* @param mixed $offset
|
* @param mixed $offset
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
*/
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetSet($offset, $value)
|
public function offsetSet($offset, $value)
|
||||||
{
|
{
|
||||||
$this->items->offsetSet($offset, $value);
|
$this->items->offsetSet($offset, $value);
|
||||||
|
|
@ -455,6 +459,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
|
||||||
* @return void
|
* @return void
|
||||||
* @since 5.0.0
|
* @since 5.0.0
|
||||||
*/
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetUnset($offset)
|
public function offsetUnset($offset)
|
||||||
{
|
{
|
||||||
$this->items->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
|
* Specify data which should be serialized to JSON
|
||||||
*/
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function jsonSerialize()
|
public function jsonSerialize()
|
||||||
{
|
{
|
||||||
return $this->toArray();
|
return $this->toArray();
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,12 @@ abstract class BaseQuery
|
||||||
$name = Str::snake(substr($method, 5));
|
$name = Str::snake(substr($method, 5));
|
||||||
array_unshift($args, $name);
|
array_unshift($args, $name);
|
||||||
return call_user_func_array([$this, 'where'], $args);
|
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)) {
|
} elseif ($this->model && method_exists($this->model, 'scope' . $method)) {
|
||||||
// 动态调用命名范围
|
// 动态调用命名范围
|
||||||
$method = 'scope' . $method;
|
$method = 'scope' . $method;
|
||||||
|
|
@ -137,7 +143,7 @@ abstract class BaseQuery
|
||||||
$query->name($this->name);
|
$query->name($this->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($this->options['json'])) {
|
if (!empty($this->options['json'])) {
|
||||||
$query->json($this->options['json'], $this->options['json_assoc']);
|
$query->json($this->options['json'], $this->options['json_assoc']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -278,7 +284,9 @@ abstract class BaseQuery
|
||||||
public function column($field, string $key = ''): array
|
public function column($field, string $key = ''): array
|
||||||
{
|
{
|
||||||
$result = $this->connection->column($this, $field, $key);
|
$result = $this->connection->column($this, $field, $key);
|
||||||
|
if (count($result) != count($result, 1)) {
|
||||||
$this->resultSet($result, false);
|
$this->resultSet($result, false);
|
||||||
|
}
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -867,6 +875,7 @@ abstract class BaseQuery
|
||||||
{
|
{
|
||||||
$this->options['json'] = $json;
|
$this->options['json'] = $json;
|
||||||
$this->options['json_assoc'] = $assoc;
|
$this->options['json_assoc'] = $assoc;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1124,7 +1133,7 @@ abstract class BaseQuery
|
||||||
* 查找单条记录
|
* 查找单条记录
|
||||||
* @access public
|
* @access public
|
||||||
* @param mixed $data 查询数据
|
* @param mixed $data 查询数据
|
||||||
* @return array|Model|null|static
|
* @return array|Model|null|static|mixed
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @throws ModelNotFoundException
|
* @throws ModelNotFoundException
|
||||||
* @throws DataNotFoundException
|
* @throws DataNotFoundException
|
||||||
|
|
@ -1178,7 +1187,7 @@ abstract class BaseQuery
|
||||||
$this->parseView($options);
|
$this->parseView($options);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (['data', 'order', 'join', 'union'] as $name) {
|
foreach (['data', 'order', 'join', 'union', 'filter', 'json'] as $name) {
|
||||||
if (!isset($options[$name])) {
|
if (!isset($options[$name])) {
|
||||||
$options[$name] = [];
|
$options[$name] = [];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -279,7 +279,7 @@ abstract class PDOConnection extends Connection
|
||||||
*/
|
*/
|
||||||
protected function getFieldType(string $type): string
|
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';
|
$result = 'string';
|
||||||
} elseif (preg_match('/(double|float|decimal|real|numeric)/is', $type)) {
|
} elseif (preg_match('/(double|float|decimal|real|numeric)/is', $type)) {
|
||||||
$result = 'float';
|
$result = 'float';
|
||||||
|
|
@ -287,11 +287,11 @@ abstract class PDOConnection extends Connection
|
||||||
$result = 'int';
|
$result = 'int';
|
||||||
} elseif (preg_match('/bool/is', $type)) {
|
} elseif (preg_match('/bool/is', $type)) {
|
||||||
$result = 'bool';
|
$result = 'bool';
|
||||||
} elseif (0 === strpos($type, 'timestamp')) {
|
} elseif (0 === stripos($type, 'timestamp')) {
|
||||||
$result = 'timestamp';
|
$result = 'timestamp';
|
||||||
} elseif (0 === strpos($type, 'datetime')) {
|
} elseif (0 === stripos($type, 'datetime')) {
|
||||||
$result = 'datetime';
|
$result = 'datetime';
|
||||||
} elseif (0 === strpos($type, 'date')) {
|
} elseif (0 === stripos($type, 'date')) {
|
||||||
$result = 'date';
|
$result = 'date';
|
||||||
} else {
|
} else {
|
||||||
$result = 'string';
|
$result = 'string';
|
||||||
|
|
@ -1273,7 +1273,7 @@ abstract class PDOConnection extends Connection
|
||||||
$type = is_array($val) ? $val[1] : PDO::PARAM_STR;
|
$type = is_array($val) ? $val[1] : PDO::PARAM_STR;
|
||||||
|
|
||||||
if (self::PARAM_FLOAT == $type || PDO::PARAM_STR == $type) {
|
if (self::PARAM_FLOAT == $type || PDO::PARAM_STR == $type) {
|
||||||
$value = '\'' . addslashes($value) . '\'';
|
$value = '\'' . addcslashes($value, "'") . '\'';
|
||||||
} elseif (PDO::PARAM_INT == $type && '' === $value) {
|
} elseif (PDO::PARAM_INT == $type && '' === $value) {
|
||||||
$value = '0';
|
$value = '0';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -94,4 +94,16 @@ class Sqlite extends Builder
|
||||||
|
|
||||||
return $key;
|
return $key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置锁机制
|
||||||
|
* @access protected
|
||||||
|
* @param Query $query 查询对象
|
||||||
|
* @param bool|string $lock
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function parseLock(Query $query, $lock = false): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,42 +51,6 @@ trait ModelRelationQuery
|
||||||
return $this->model;
|
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
|
* @access public
|
||||||
|
|
@ -187,7 +151,9 @@ trait ModelRelationQuery
|
||||||
$this->options['with_attr'][$name] = $callback;
|
$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();
|
return $this->model->toCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查动态获取器
|
$withRelationAttr = $this->getWithRelationAttr();
|
||||||
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 ?? [];
|
|
||||||
|
|
||||||
foreach ($resultSet as $key => &$result) {
|
foreach ($resultSet as $key => &$result) {
|
||||||
// 数据转换为模型对象
|
// 数据转换为模型对象
|
||||||
$this->resultToModel($result, $this->options, true, $withRelationAttr);
|
$this->resultToModel($result, $this->options, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($this->options['with'])) {
|
if (!empty($this->options['with'])) {
|
||||||
|
|
@ -451,74 +404,74 @@ trait ModelRelationQuery
|
||||||
return $this->model->toCollection($resultSet);
|
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
|
* @access protected
|
||||||
* @param array $result 查询数据
|
* @param array $result 查询数据
|
||||||
* @param array $options 查询参数
|
* @param array $options 查询参数
|
||||||
* @param bool $resultSet 是否为数据集查询
|
* @param bool $resultSet 是否为数据集查询
|
||||||
* @param array $withRelationAttr 关联字段获取器
|
|
||||||
* @return void
|
* @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
|
||||||
{
|
{
|
||||||
// 动态获取器
|
$options['with_relation_attr'] = $this->getWithRelationAttr();
|
||||||
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]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// JSON 数据处理
|
// JSON 数据处理
|
||||||
if (!empty($options['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
|
foreach ($this->options['filter'] as $filter) {
|
||||||
->newInstance($result, $resultSet ? null : $this->getModelUpdateCondition($options));
|
$result = call_user_func($filter, $result);
|
||||||
|
|
||||||
// 动态获取器
|
|
||||||
if (!empty($options['with_attr'])) {
|
|
||||||
$result->withAttribute($options['with_attr']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 输出属性控制
|
$result = $this->model->newInstance($result, $resultSet ? null : $this->getModelUpdateCondition($options), $options);
|
||||||
if (!empty($options['visible'])) {
|
|
||||||
$result->visible($options['visible']);
|
|
||||||
} elseif (!empty($options['hidden'])) {
|
|
||||||
$result->hidden($options['hidden']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($options['append'])) {
|
/**
|
||||||
$result->append($options['append']);
|
* 查询软删除数据
|
||||||
|
* @access public
|
||||||
|
* @return Query
|
||||||
|
*/
|
||||||
|
public function withTrashed()
|
||||||
|
{
|
||||||
|
return $this->model ? $this->model->queryWithTrashed() : $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关联查询
|
/**
|
||||||
if (!empty($options['relation'])) {
|
* 只查询软删除数据
|
||||||
$result->relationQuery($options['relation'], $withRelationAttr);
|
* @access public
|
||||||
|
* @return Query
|
||||||
|
*/
|
||||||
|
public function onlyTrashed()
|
||||||
|
{
|
||||||
|
return $this->model ? $this->model->queryOnlyTrashed() : $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 预载入查询
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,23 @@ use think\Model;
|
||||||
*/
|
*/
|
||||||
trait ResultOperation
|
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
|
* @access public
|
||||||
|
|
@ -62,11 +79,9 @@ trait ResultOperation
|
||||||
$this->jsonResult($result, $this->options['json'], true);
|
$this->jsonResult($result, $this->options['json'], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($this->options['with_attr'])) {
|
foreach ($this->options['filter'] as $filter) {
|
||||||
$this->getResultAttr($result, $this->options['with_attr']);
|
$result = call_user_func($filter, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->filterResult($result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -78,22 +93,8 @@ trait ResultOperation
|
||||||
*/
|
*/
|
||||||
protected function resultSet(array &$resultSet, bool $toCollection = true): void
|
protected function resultSet(array &$resultSet, bool $toCollection = true): void
|
||||||
{
|
{
|
||||||
if (!empty($this->options['json'])) {
|
|
||||||
foreach ($resultSet as &$result) {
|
foreach ($resultSet as &$result) {
|
||||||
$this->jsonResult($result, $this->options['json'], true);
|
$this->result($result);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回Collection对象
|
// 返回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
|
* @access protected
|
||||||
* @param array $result 查询数据
|
* @param array $result 查询数据
|
||||||
* @param array $withAttr 字段获取器
|
* @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) {
|
foreach ($withAttr as $name => $closure) {
|
||||||
$name = Str::snake($name);
|
$name = Str::snake($name);
|
||||||
|
|
@ -147,6 +126,8 @@ trait ResultOperation
|
||||||
$result[$name] = $closure($result[$name] ?? null, $result);
|
$result[$name] = $closure($result[$name] ?? null, $result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -170,7 +151,7 @@ trait ResultOperation
|
||||||
* 查找单条记录 不存在返回空数据(或者空模型)
|
* 查找单条记录 不存在返回空数据(或者空模型)
|
||||||
* @access public
|
* @access public
|
||||||
* @param mixed $data 数据
|
* @param mixed $data 数据
|
||||||
* @return array|Model|static
|
* @return array|Model|static|mixed
|
||||||
*/
|
*/
|
||||||
public function findOrEmpty($data = null)
|
public function findOrEmpty($data = null)
|
||||||
{
|
{
|
||||||
|
|
@ -242,7 +223,7 @@ trait ResultOperation
|
||||||
* 查找单条记录 如果不存在则抛出异常
|
* 查找单条记录 如果不存在则抛出异常
|
||||||
* @access public
|
* @access public
|
||||||
* @param array|string|Query|Closure $data 数据
|
* @param array|string|Query|Closure $data 数据
|
||||||
* @return array|Model|static
|
* @return array|Model|static|mixed
|
||||||
* @throws ModelNotFoundException
|
* @throws ModelNotFoundException
|
||||||
* @throws DataNotFoundException
|
* @throws DataNotFoundException
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@ class Collection extends BaseCollection
|
||||||
public function withAttr($name, $callback = null)
|
public function withAttr($name, $callback = null)
|
||||||
{
|
{
|
||||||
$this->each(function (Model $model) use ($name, $callback) {
|
$this->each(function (Model $model) use ($name, $callback) {
|
||||||
$model->withAttribute($name, $callback);
|
$model->withAttr($name, $callback);
|
||||||
});
|
});
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,12 @@ trait Attribute
|
||||||
*/
|
*/
|
||||||
private $withAttr = [];
|
private $withAttr = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据处理
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $filter = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取模型对象的主键
|
* 获取模型对象的主键
|
||||||
* @access public
|
* @access public
|
||||||
|
|
@ -177,6 +183,24 @@ trait Attribute
|
||||||
return $this;
|
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
|
* @access protected
|
||||||
|
|
@ -633,11 +657,11 @@ trait Attribute
|
||||||
* @param callable $callback 闭包获取器
|
* @param callable $callback 闭包获取器
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function withAttribute($name, callable $callback = null)
|
public function withAttr($name, callable $callback = null)
|
||||||
{
|
{
|
||||||
if (is_array($name)) {
|
if (is_array($name)) {
|
||||||
foreach ($name as $key => $val) {
|
foreach ($name as $key => $val) {
|
||||||
$this->withAttribute($key, $val);
|
$this->withAttr($key, $val);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$name = $this->getRealFieldName($name);
|
$name = $this->getRealFieldName($name);
|
||||||
|
|
|
||||||
|
|
@ -330,6 +330,7 @@ trait Conversion
|
||||||
}
|
}
|
||||||
|
|
||||||
// JsonSerializable
|
// JsonSerializable
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function jsonSerialize()
|
public function jsonSerialize()
|
||||||
{
|
{
|
||||||
return $this->toArray();
|
return $this->toArray();
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,16 @@ trait SoftDelete
|
||||||
return $model->withTrashedData(true)->db();
|
return $model->withTrashedData(true)->db();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询软删除数据
|
||||||
|
* @access public
|
||||||
|
* @return Query
|
||||||
|
*/
|
||||||
|
public function queryWithTrashed(): Query
|
||||||
|
{
|
||||||
|
return $this->withTrashedData(true)->db();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否包含软删除数据
|
* 是否包含软删除数据
|
||||||
* @access protected
|
* @access protected
|
||||||
|
|
@ -86,6 +96,23 @@ trait SoftDelete
|
||||||
return $model->db();
|
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
|
* @access protected
|
||||||
|
|
@ -152,12 +179,12 @@ trait SoftDelete
|
||||||
public static function destroy($data, bool $force = false): bool
|
public static function destroy($data, bool $force = false): bool
|
||||||
{
|
{
|
||||||
// 传入空值(包括空字符串和空数组)的时候不会做任何的数据删除操作,但传入0则是有效的
|
// 传入空值(包括空字符串和空数组)的时候不会做任何的数据删除操作,但传入0则是有效的
|
||||||
if(empty($data) && $data !== 0){
|
if (empty($data) && 0 !== $data) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 仅当强制删除时包含软删除数据
|
// 仅当强制删除时包含软删除数据
|
||||||
$model = (new static());
|
$model = (new static());
|
||||||
if($force){
|
if ($force) {
|
||||||
$model->withTrashedData(true);
|
$model->withTrashedData(true);
|
||||||
}
|
}
|
||||||
$query = $model->db(false);
|
$query = $model->db(false);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ use think\db\Raw;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
use think\model\Pivot;
|
use think\model\Pivot;
|
||||||
use think\model\Relation;
|
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
|
* @access public
|
||||||
|
|
@ -158,62 +132,9 @@ class BelongsToMany extends Relation
|
||||||
$closure($this->getClosureType($closure));
|
$closure($this->getClosureType($closure));
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->relation($subRelation)
|
return $this->relation($subRelation)
|
||||||
->select()
|
->select()
|
||||||
->setParent(clone $this->parent);
|
->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;
|
$foreignKey = $this->foreignKey;
|
||||||
$localKey = $this->localKey;
|
$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()) {
|
if (null === $this->parent->getKey()) {
|
||||||
$condition = ['pivot.' . $localKey, 'exp', new Raw('=' . $this->parent->getTable() . '.' . $this->parent->getPk())];
|
$condition = ['pivot.' . $localKey, 'exp', new Raw('=' . $this->parent->getTable() . '.' . $this->parent->getPk())];
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue