diff --git a/app/admin/controller/Index.php b/app/admin/controller/Index.php
index 0cc744b..a5fa097 100644
--- a/app/admin/controller/Index.php
+++ b/app/admin/controller/Index.php
@@ -51,6 +51,12 @@ class Index extends AuthController
$this->assign("friend_link_count", $FriendLinkCount);
$messageFormCount = MessageForm::counts(new MessageForm());
$this->assign("message_form_count", $messageFormCount);
+ $data =[
+ "page"=> 0 ,
+ "limit" => 5
+ ];
+ $articleList = Document::systemPage($data)['data'];
+ $this->assign("article_list", $articleList);
return $this->fetch();
}
diff --git a/app/admin/view/index/main.html b/app/admin/view/index/main.html
index 2374d95..3167ad8 100644
--- a/app/admin/view/index/main.html
+++ b/app/admin/view/index/main.html
@@ -69,6 +69,40 @@
+
+
+
+
+
+
+
+
+
+ | # |
+ 文章标题 |
+ 文章分类 |
+ 发布时间 |
+
+
+
+ {volist name="article_list" id="vo"}
+
+ | {$vo.id} |
+ {$vo.title} |
+ {$vo.category_title} |
+ {$vo.create_time} |
+
+ {/volist}
+
+
+
+
+
+
+
+
diff --git a/app/common/model/Document.php b/app/common/model/Document.php
index e5b383d..cdfb1f7 100644
--- a/app/common/model/Document.php
+++ b/app/common/model/Document.php
@@ -33,10 +33,10 @@ class Document extends BaseModel
{
$model = new self;
$model = $model->where("type", "=", $where['type'] ?? Data::DOCUMENT_TYPE_ARTICLE);
- if ($where['title'] != '') $model = $model->where("title", "like", "%$where[title]%");
- if ($where['start_time'] != '') $model = $model->where("create_time", ">", strtotime($where['start_time'] . " 00:00:00"));
- if ($where['end_time'] != '') $model = $model->where("create_time", "<", strtotime($where['end_time'] . " 23:59:59"));
- if ($where['status'] != '') $model = $model->where("status", $where['status']);
+ if (!empty($where['title'])) $model = $model->where("title", "like", "%$where[title]%");
+ if (!empty($where['start_time'])) $model = $model->where("create_time", ">", strtotime($where['start_time'] . " 00:00:00"));
+ if (!empty($where['end_time'])) $model = $model->where("create_time", "<", strtotime($where['end_time'] . " 23:59:59"));
+ if (!empty($where['status'])) $model = $model->where("status", $where['status']);
$model = $model->order("sort desc")->order("id desc");
$count = self::counts($model);
if ($where['page'] && $where['limit']) $model = $model->page((int)$where['page'], (int)$where['limit']);
diff --git a/vendor/bin/var-dump-server b/vendor/bin/var-dump-server
index 527f3ed..c52c772 100644
--- a/vendor/bin/var-dump-server
+++ b/vendor/bin/var-dump-server
@@ -108,7 +108,10 @@ if (PHP_VERSION_ID < 80000) {
}
}
- if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) {
+ if (
+ (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
+ || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
+ ) {
include("phpvfscomposer://" . __DIR__ . '/..'.'/symfony/var-dumper/Resources/bin/var-dump-server');
exit(0);
}
diff --git a/vendor/bin/var-dump-server.bat b/vendor/bin/var-dump-server.bat
index c3c7476..94333da 100644
--- a/vendor/bin/var-dump-server.bat
+++ b/vendor/bin/var-dump-server.bat
@@ -1,5 +1,5 @@
@ECHO OFF
setlocal DISABLEDELAYEDEXPANSION
SET BIN_TARGET=%~dp0/var-dump-server
-SET COMPOSER_BIN_DIR=%~dp0
+SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
php "%BIN_TARGET%" %*
diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php
index 6dc14fe..f39169b 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-template/src', $vendorDir . '/topthink/think-orm/src'),
+ 'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src'),
'app\\' => array($baseDir . '/app'),
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
index bc17c4e..4a0b0ca 100644
--- a/vendor/composer/autoload_static.php
+++ b/vendor/composer/autoload_static.php
@@ -81,8 +81,8 @@ class ComposerStaticInit4b57298e8d0e895486f3307a354a7e1a
array (
0 => __DIR__ . '/..' . '/topthink/framework/src/think',
1 => __DIR__ . '/..' . '/topthink/think-helper/src',
- 2 => __DIR__ . '/..' . '/topthink/think-template/src',
- 3 => __DIR__ . '/..' . '/topthink/think-orm/src',
+ 2 => __DIR__ . '/..' . '/topthink/think-orm/src',
+ 3 => __DIR__ . '/..' . '/topthink/think-template/src',
),
'app\\' =>
array (
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index 65e20e0..fd2eb61 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -915,17 +915,17 @@
},
{
"name": "symfony/http-foundation",
- "version": "v5.4.10",
- "version_normalized": "5.4.10.0",
+ "version": "v5.4.12",
+ "version_normalized": "5.4.12.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "e7793b7906f72a8cc51054fbca9dcff7a8af1c1e"
+ "reference": "f4bfe9611b113b15d98a43da68ec9b5a00d56791"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e7793b7906f72a8cc51054fbca9dcff7a8af1c1e",
- "reference": "e7793b7906f72a8cc51054fbca9dcff7a8af1c1e",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f4bfe9611b113b15d98a43da68ec9b5a00d56791",
+ "reference": "f4bfe9611b113b15d98a43da68ec9b5a00d56791",
"shasum": "",
"mirrors": [
{
@@ -943,13 +943,16 @@
"require-dev": {
"predis/predis": "~1.0",
"symfony/cache": "^4.4|^5.0|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
"symfony/expression-language": "^4.4|^5.0|^6.0",
- "symfony/mime": "^4.4|^5.0|^6.0"
+ "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4",
+ "symfony/mime": "^4.4|^5.0|^6.0",
+ "symfony/rate-limiter": "^5.2|^6.0"
},
"suggest": {
"symfony/mime": "To use the file extension guesser"
},
- "time": "2022-06-19T13:13:40+00:00",
+ "time": "2022-08-19T07:33:17+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -977,7 +980,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.10"
+ "source": "https://github.com/symfony/http-foundation/tree/v5.4.12"
},
"funding": [
{
@@ -1266,17 +1269,17 @@
},
{
"name": "symfony/var-dumper",
- "version": "v4.4.42",
- "version_normalized": "4.4.42.0",
+ "version": "v4.4.44",
+ "version_normalized": "4.4.44.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "742aab50ad097bcb62d91fccb613f66b8047d2ca"
+ "reference": "f19951007dae942cc79b979c1fe26bfdfbeb54ed"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/742aab50ad097bcb62d91fccb613f66b8047d2ca",
- "reference": "742aab50ad097bcb62d91fccb613f66b8047d2ca",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/f19951007dae942cc79b979c1fe26bfdfbeb54ed",
+ "reference": "f19951007dae942cc79b979c1fe26bfdfbeb54ed",
"shasum": "",
"mirrors": [
{
@@ -1306,7 +1309,7 @@
"ext-intl": "To show region name in time zone dump",
"symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
},
- "time": "2022-05-21T10:00:54+00:00",
+ "time": "2022-07-20T09:59:04+00:00",
"bin": [
"Resources/bin/var-dump-server"
],
@@ -1344,7 +1347,7 @@
"dump"
],
"support": {
- "source": "https://github.com/symfony/var-dumper/tree/v4.4.42"
+ "source": "https://github.com/symfony/var-dumper/tree/v4.4.44"
},
"funding": [
{
@@ -1364,17 +1367,17 @@
},
{
"name": "topthink/framework",
- "version": "v6.0.12",
- "version_normalized": "6.0.12.0",
+ "version": "v6.0.13",
+ "version_normalized": "6.0.13.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/framework.git",
- "reference": "e478316ac843c1a884a3b3a7a94db17c4001ff5c"
+ "reference": "126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/top-think/framework/zipball/e478316ac843c1a884a3b3a7a94db17c4001ff5c",
- "reference": "e478316ac843c1a884a3b3a7a94db17c4001ff5c",
+ "url": "https://api.github.com/repos/top-think/framework/zipball/126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6",
+ "reference": "126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6",
"shasum": "",
"mirrors": [
{
@@ -1402,7 +1405,7 @@
"mockery/mockery": "^1.2",
"phpunit/phpunit": "^7.0"
},
- "time": "2022-01-21T06:31:07+00:00",
+ "time": "2022-07-15T02:52:08+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -1434,7 +1437,7 @@
],
"support": {
"issues": "https://github.com/top-think/framework/issues",
- "source": "https://github.com/top-think/framework/tree/v6.0.12"
+ "source": "https://github.com/top-think/framework/tree/v6.0.13"
},
"install-path": "../topthink/framework"
},
@@ -1614,17 +1617,17 @@
},
{
"name": "topthink/think-orm",
- "version": "v2.0.53",
- "version_normalized": "2.0.53.0",
+ "version": "v2.0.54",
+ "version_normalized": "2.0.54.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-orm.git",
- "reference": "06783eda65547a70ea686360a897759e1f873fff"
+ "reference": "97b061b47616301ff29fbd4c35ed9184e1162e4e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/top-think/think-orm/zipball/06783eda65547a70ea686360a897759e1f873fff",
- "reference": "06783eda65547a70ea686360a897759e1f873fff",
+ "url": "https://api.github.com/repos/top-think/think-orm/zipball/97b061b47616301ff29fbd4c35ed9184e1162e4e",
+ "reference": "97b061b47616301ff29fbd4c35ed9184e1162e4e",
"shasum": "",
"mirrors": [
{
@@ -1637,14 +1640,14 @@
"ext-json": "*",
"ext-pdo": "*",
"php": ">=7.1.0",
- "psr/log": "~1.0",
- "psr/simple-cache": "^1.0",
+ "psr/log": "^1.0|^2.0",
+ "psr/simple-cache": "^1.0|^2.0",
"topthink/think-helper": "^3.1"
},
"require-dev": {
"phpunit/phpunit": "^7|^8|^9.5"
},
- "time": "2022-02-28T14:54:22+00:00",
+ "time": "2022-07-05T05:25:51+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -1672,7 +1675,7 @@
],
"support": {
"issues": "https://github.com/top-think/think-orm/issues",
- "source": "https://github.com/top-think/think-orm/tree/v2.0.53"
+ "source": "https://github.com/top-think/think-orm/tree/v2.0.54"
},
"install-path": "../topthink/think-orm"
},
diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php
index 4458ba7..767c1a5 100644
--- a/vendor/composer/installed.php
+++ b/vendor/composer/installed.php
@@ -3,7 +3,7 @@
'name' => 'topthink/think',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
- 'reference' => 'dc0fcfd1eb5f19c42b2ec51208d3bca840538c92',
+ 'reference' => 'ecdf50d35553ba71e48f82e41d38feb090fd0f7b',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -128,9 +128,9 @@
'dev_requirement' => false,
),
'symfony/http-foundation' => array(
- 'pretty_version' => 'v5.4.10',
- 'version' => '5.4.10.0',
- 'reference' => 'e7793b7906f72a8cc51054fbca9dcff7a8af1c1e',
+ 'pretty_version' => 'v5.4.12',
+ 'version' => '5.4.12.0',
+ 'reference' => 'f4bfe9611b113b15d98a43da68ec9b5a00d56791',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/http-foundation',
'aliases' => array(),
@@ -164,18 +164,18 @@
'dev_requirement' => false,
),
'symfony/var-dumper' => array(
- 'pretty_version' => 'v4.4.42',
- 'version' => '4.4.42.0',
- 'reference' => '742aab50ad097bcb62d91fccb613f66b8047d2ca',
+ 'pretty_version' => 'v4.4.44',
+ 'version' => '4.4.44.0',
+ 'reference' => 'f19951007dae942cc79b979c1fe26bfdfbeb54ed',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/var-dumper',
'aliases' => array(),
'dev_requirement' => true,
),
'topthink/framework' => array(
- 'pretty_version' => 'v6.0.12',
- 'version' => '6.0.12.0',
- 'reference' => 'e478316ac843c1a884a3b3a7a94db17c4001ff5c',
+ 'pretty_version' => 'v6.0.13',
+ 'version' => '6.0.13.0',
+ 'reference' => '126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/framework',
'aliases' => array(),
@@ -184,7 +184,7 @@
'topthink/think' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
- 'reference' => 'dc0fcfd1eb5f19c42b2ec51208d3bca840538c92',
+ 'reference' => 'ecdf50d35553ba71e48f82e41d38feb090fd0f7b',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -218,9 +218,9 @@
'dev_requirement' => false,
),
'topthink/think-orm' => array(
- 'pretty_version' => 'v2.0.53',
- 'version' => '2.0.53.0',
- 'reference' => '06783eda65547a70ea686360a897759e1f873fff',
+ 'pretty_version' => 'v2.0.54',
+ 'version' => '2.0.54.0',
+ 'reference' => '97b061b47616301ff29fbd4c35ed9184e1162e4e',
'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-orm',
'aliases' => array(),
diff --git a/vendor/services.php b/vendor/services.php
index 82b4c38..3b59f21 100644
--- a/vendor/services.php
+++ b/vendor/services.php
@@ -1,5 +1,5 @@
'think\\captcha\\CaptchaService',
diff --git a/vendor/symfony/http-foundation/BinaryFileResponse.php b/vendor/symfony/http-foundation/BinaryFileResponse.php
index 4769cab..beb0eda 100644
--- a/vendor/symfony/http-foundation/BinaryFileResponse.php
+++ b/vendor/symfony/http-foundation/BinaryFileResponse.php
@@ -34,6 +34,7 @@ class BinaryFileResponse extends Response
protected $offset = 0;
protected $maxlen = -1;
protected $deleteFileAfterSend = false;
+ protected $chunkSize = 8 * 1024;
/**
* @param \SplFileInfo|string $file The file to stream
@@ -125,6 +126,22 @@ class BinaryFileResponse extends Response
return $this->file;
}
+ /**
+ * Sets the response stream chunk size.
+ *
+ * @return $this
+ */
+ public function setChunkSize(int $chunkSize): self
+ {
+ if ($chunkSize < 1 || $chunkSize > \PHP_INT_MAX) {
+ throw new \LogicException('The chunk size of a BinaryFileResponse cannot be less than 1 or greater than PHP_INT_MAX.');
+ }
+
+ $this->chunkSize = $chunkSize;
+
+ return $this;
+ }
+
/**
* Automatically sets the Last-Modified header according the file modification date.
*
@@ -306,7 +323,23 @@ class BinaryFileResponse extends Response
$out = fopen('php://output', 'w');
$file = fopen($this->file->getPathname(), 'r');
- stream_copy_to_stream($file, $out, $this->maxlen, $this->offset);
+ ignore_user_abort(true);
+
+ if (0 !== $this->offset) {
+ fseek($file, $this->offset);
+ }
+
+ $length = $this->maxlen;
+ while ($length && !feof($file)) {
+ $read = ($length > $this->chunkSize) ? $this->chunkSize : $length;
+ $length -= $read;
+
+ stream_copy_to_stream($file, $out, $read);
+
+ if (connection_aborted()) {
+ break;
+ }
+ }
fclose($out);
fclose($file);
diff --git a/vendor/symfony/http-foundation/File/UploadedFile.php b/vendor/symfony/http-foundation/File/UploadedFile.php
index cf50a02..fcc6299 100644
--- a/vendor/symfony/http-foundation/File/UploadedFile.php
+++ b/vendor/symfony/http-foundation/File/UploadedFile.php
@@ -223,8 +223,8 @@ class UploadedFile extends File
*/
public static function getMaxFilesize()
{
- $sizePostMax = self::parseFilesize(ini_get('post_max_size'));
- $sizeUploadMax = self::parseFilesize(ini_get('upload_max_filesize'));
+ $sizePostMax = self::parseFilesize(\ini_get('post_max_size'));
+ $sizeUploadMax = self::parseFilesize(\ini_get('upload_max_filesize'));
return min($sizePostMax ?: \PHP_INT_MAX, $sizeUploadMax ?: \PHP_INT_MAX);
}
@@ -253,8 +253,11 @@ class UploadedFile extends File
switch (substr($size, -1)) {
case 't': $max *= 1024;
+ // no break
case 'g': $max *= 1024;
+ // no break
case 'm': $max *= 1024;
+ // no break
case 'k': $max *= 1024;
}
diff --git a/vendor/symfony/http-foundation/InputBag.php b/vendor/symfony/http-foundation/InputBag.php
index b36001d..a9d3cd8 100644
--- a/vendor/symfony/http-foundation/InputBag.php
+++ b/vendor/symfony/http-foundation/InputBag.php
@@ -29,14 +29,14 @@ final class InputBag extends ParameterBag
*/
public function get(string $key, $default = null)
{
- if (null !== $default && !is_scalar($default) && !(\is_object($default) && method_exists($default, '__toString'))) {
+ if (null !== $default && !\is_scalar($default) && !(\is_object($default) && method_exists($default, '__toString'))) {
trigger_deprecation('symfony/http-foundation', '5.1', 'Passing a non-scalar value as 2nd argument to "%s()" is deprecated, pass a scalar or null instead.', __METHOD__);
}
$value = parent::get($key, $this);
- if (null !== $value && $this !== $value && !is_scalar($value) && !(\is_object($value) && method_exists($value, '__toString'))) {
- trigger_deprecation('symfony/http-foundation', '5.1', 'Retrieving a non-string value from "%s()" is deprecated, and will throw a "%s" exception in Symfony 6.0, use "%s::all($key)" instead.', __METHOD__, BadRequestException::class, __CLASS__);
+ if (null !== $value && $this !== $value && !\is_scalar($value) && !(\is_object($value) && method_exists($value, '__toString'))) {
+ trigger_deprecation('symfony/http-foundation', '5.1', 'Retrieving a non-scalar value from "%s()" is deprecated, and will throw a "%s" exception in Symfony 6.0, use "%s::all($key)" instead.', __METHOD__, BadRequestException::class, __CLASS__);
}
return $this === $value ? $default : $value;
@@ -76,7 +76,7 @@ final class InputBag extends ParameterBag
*/
public function set(string $key, $value)
{
- if (null !== $value && !is_scalar($value) && !\is_array($value) && !method_exists($value, '__toString')) {
+ if (null !== $value && !\is_scalar($value) && !\is_array($value) && !method_exists($value, '__toString')) {
trigger_deprecation('symfony/http-foundation', '5.1', 'Passing "%s" as a 2nd Argument to "%s()" is deprecated, pass a scalar, array, or null instead.', get_debug_type($value), __METHOD__);
}
diff --git a/vendor/symfony/http-foundation/ParameterBag.php b/vendor/symfony/http-foundation/ParameterBag.php
index 7d051ab..e1f89d6 100644
--- a/vendor/symfony/http-foundation/ParameterBag.php
+++ b/vendor/symfony/http-foundation/ParameterBag.php
@@ -39,7 +39,7 @@ class ParameterBag implements \IteratorAggregate, \Countable
*
* @return array
*/
- public function all(/*string $key = null*/)
+ public function all(/* string $key = null */)
{
$key = \func_num_args() > 0 ? func_get_arg(0) : null;
diff --git a/vendor/symfony/http-foundation/RateLimiter/AbstractRequestRateLimiter.php b/vendor/symfony/http-foundation/RateLimiter/AbstractRequestRateLimiter.php
index c91d614..a6dd993 100644
--- a/vendor/symfony/http-foundation/RateLimiter/AbstractRequestRateLimiter.php
+++ b/vendor/symfony/http-foundation/RateLimiter/AbstractRequestRateLimiter.php
@@ -35,9 +35,7 @@ abstract class AbstractRequestRateLimiter implements RequestRateLimiterInterface
foreach ($limiters as $limiter) {
$rateLimit = $limiter->consume(1);
- if (null === $minimalRateLimit || $rateLimit->getRemainingTokens() < $minimalRateLimit->getRemainingTokens()) {
- $minimalRateLimit = $rateLimit;
- }
+ $minimalRateLimit = $minimalRateLimit ? self::getMinimalRateLimit($minimalRateLimit, $rateLimit) : $rateLimit;
}
return $minimalRateLimit;
@@ -54,4 +52,20 @@ abstract class AbstractRequestRateLimiter implements RequestRateLimiterInterface
* @return LimiterInterface[] a set of limiters using keys extracted from the request
*/
abstract protected function getLimiters(Request $request): array;
+
+ private static function getMinimalRateLimit(RateLimit $first, RateLimit $second): RateLimit
+ {
+ if ($first->isAccepted() !== $second->isAccepted()) {
+ return $first->isAccepted() ? $second : $first;
+ }
+
+ $firstRemainingTokens = $first->getRemainingTokens();
+ $secondRemainingTokens = $second->getRemainingTokens();
+
+ if ($firstRemainingTokens === $secondRemainingTokens) {
+ return $first->getRetryAfter() < $second->getRetryAfter() ? $second : $first;
+ }
+
+ return $firstRemainingTokens > $secondRemainingTokens ? $second : $first;
+ }
}
diff --git a/vendor/symfony/http-foundation/Request.php b/vendor/symfony/http-foundation/Request.php
index d112b1f..65f30a1 100644
--- a/vendor/symfony/http-foundation/Request.php
+++ b/vendor/symfony/http-foundation/Request.php
@@ -562,7 +562,7 @@ class Request
$request = ['g' => $_GET, 'p' => $_POST, 'c' => $_COOKIE];
- $requestOrder = ini_get('request_order') ?: ini_get('variables_order');
+ $requestOrder = \ini_get('request_order') ?: \ini_get('variables_order');
$requestOrder = preg_replace('#[^cgp]#', '', strtolower($requestOrder)) ?: 'gp';
$_REQUEST = [[]];
diff --git a/vendor/symfony/http-foundation/Response.php b/vendor/symfony/http-foundation/Response.php
index def7f8e..88635bb 100644
--- a/vendor/symfony/http-foundation/Response.php
+++ b/vendor/symfony/http-foundation/Response.php
@@ -72,7 +72,7 @@ class Response
public const HTTP_PRECONDITION_REQUIRED = 428; // RFC6585
public const HTTP_TOO_MANY_REQUESTS = 429; // RFC6585
public const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; // RFC6585
- public const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451;
+ public const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451; // RFC7725
public const HTTP_INTERNAL_SERVER_ERROR = 500;
public const HTTP_NOT_IMPLEMENTED = 501;
public const HTTP_BAD_GATEWAY = 502;
@@ -1245,6 +1245,7 @@ class Response
while ($level-- > $targetLevel && ($s = $status[$level]) && (!isset($s['del']) ? !isset($s['flags']) || ($s['flags'] & $flags) === $flags : $s['del'])) {
if ($flush) {
ob_end_flush();
+ flush();
} else {
ob_end_clean();
}
diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php
index bc7b944..35d7b4b 100644
--- a/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php
+++ b/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php
@@ -35,8 +35,8 @@ abstract class AbstractSessionHandler implements \SessionHandlerInterface, \Sess
public function open($savePath, $sessionName)
{
$this->sessionName = $sessionName;
- if (!headers_sent() && !ini_get('session.cache_limiter') && '0' !== ini_get('session.cache_limiter')) {
- header(sprintf('Cache-Control: max-age=%d, private, must-revalidate', 60 * (int) ini_get('session.cache_expire')));
+ if (!headers_sent() && !\ini_get('session.cache_limiter') && '0' !== \ini_get('session.cache_limiter')) {
+ header(sprintf('Cache-Control: max-age=%d, private, must-revalidate', 60 * (int) \ini_get('session.cache_expire')));
}
return true;
@@ -126,7 +126,7 @@ abstract class AbstractSessionHandler implements \SessionHandlerInterface, \Sess
#[\ReturnTypeWillChange]
public function destroy($sessionId)
{
- if (!headers_sent() && filter_var(ini_get('session.use_cookies'), \FILTER_VALIDATE_BOOLEAN)) {
+ if (!headers_sent() && filter_var(\ini_get('session.use_cookies'), \FILTER_VALIDATE_BOOLEAN)) {
if (!$this->sessionName) {
throw new \LogicException(sprintf('Session name cannot be empty, did you forget to call "parent::open()" in "%s"?.', static::class));
}
@@ -141,7 +141,7 @@ abstract class AbstractSessionHandler implements \SessionHandlerInterface, \Sess
*/
if (null === $cookie || isset($_COOKIE[$this->sessionName])) {
if (\PHP_VERSION_ID < 70300) {
- setcookie($this->sessionName, '', 0, ini_get('session.cookie_path'), ini_get('session.cookie_domain'), filter_var(ini_get('session.cookie_secure'), \FILTER_VALIDATE_BOOLEAN), filter_var(ini_get('session.cookie_httponly'), \FILTER_VALIDATE_BOOLEAN));
+ setcookie($this->sessionName, '', 0, \ini_get('session.cookie_path'), \ini_get('session.cookie_domain'), filter_var(\ini_get('session.cookie_secure'), \FILTER_VALIDATE_BOOLEAN), filter_var(\ini_get('session.cookie_httponly'), \FILTER_VALIDATE_BOOLEAN));
} else {
$params = session_get_cookie_params();
unset($params['lifetime']);
diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php
index a5a78eb..9cb841a 100644
--- a/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php
+++ b/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php
@@ -77,7 +77,7 @@ class MemcachedSessionHandler extends AbstractSessionHandler
#[\ReturnTypeWillChange]
public function updateTimestamp($sessionId, $data)
{
- $this->memcached->touch($this->prefix.$sessionId, time() + (int) ($this->ttl ?? ini_get('session.gc_maxlifetime')));
+ $this->memcached->touch($this->prefix.$sessionId, time() + (int) ($this->ttl ?? \ini_get('session.gc_maxlifetime')));
return true;
}
@@ -87,7 +87,7 @@ class MemcachedSessionHandler extends AbstractSessionHandler
*/
protected function doWrite(string $sessionId, string $data)
{
- return $this->memcached->set($this->prefix.$sessionId, $data, time() + (int) ($this->ttl ?? ini_get('session.gc_maxlifetime')));
+ return $this->memcached->set($this->prefix.$sessionId, $data, time() + (int) ($this->ttl ?? \ini_get('session.gc_maxlifetime')));
}
/**
diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php
index 8384e79..ef8f719 100644
--- a/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php
+++ b/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php
@@ -121,7 +121,7 @@ class MongoDbSessionHandler extends AbstractSessionHandler
*/
protected function doWrite(string $sessionId, string $data)
{
- $expiry = new UTCDateTime((time() + (int) ini_get('session.gc_maxlifetime')) * 1000);
+ $expiry = new UTCDateTime((time() + (int) \ini_get('session.gc_maxlifetime')) * 1000);
$fields = [
$this->options['time_field'] => new UTCDateTime(),
@@ -144,7 +144,7 @@ class MongoDbSessionHandler extends AbstractSessionHandler
#[\ReturnTypeWillChange]
public function updateTimestamp($sessionId, $data)
{
- $expiry = new UTCDateTime((time() + (int) ini_get('session.gc_maxlifetime')) * 1000);
+ $expiry = new UTCDateTime((time() + (int) \ini_get('session.gc_maxlifetime')) * 1000);
$this->getCollection()->updateOne(
[$this->options['id_field'] => $sessionId],
diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php
index effc9db..1ca4bfe 100644
--- a/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php
+++ b/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php
@@ -31,7 +31,7 @@ class NativeFileSessionHandler extends \SessionHandler
public function __construct(string $savePath = null)
{
if (null === $savePath) {
- $savePath = ini_get('session.save_path');
+ $savePath = \ini_get('session.save_path');
}
$baseDir = $savePath;
diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php
index 067bfcb..24c9894 100644
--- a/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php
+++ b/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php
@@ -344,7 +344,7 @@ class PdoSessionHandler extends AbstractSessionHandler
*/
protected function doWrite(string $sessionId, string $data)
{
- $maxlifetime = (int) ini_get('session.gc_maxlifetime');
+ $maxlifetime = (int) \ini_get('session.gc_maxlifetime');
try {
// We use a single MERGE SQL query when supported by the database.
@@ -391,7 +391,7 @@ class PdoSessionHandler extends AbstractSessionHandler
#[\ReturnTypeWillChange]
public function updateTimestamp($sessionId, $data)
{
- $expiry = time() + (int) ini_get('session.gc_maxlifetime');
+ $expiry = time() + (int) \ini_get('session.gc_maxlifetime');
try {
$updateStmt = $this->pdo->prepare(
@@ -687,7 +687,7 @@ class PdoSessionHandler extends AbstractSessionHandler
throw new \RuntimeException('Failed to read session: INSERT reported a duplicate id but next SELECT did not return any data.');
}
- if (!filter_var(ini_get('session.use_strict_mode'), \FILTER_VALIDATE_BOOLEAN) && self::LOCK_TRANSACTIONAL === $this->lockMode && 'sqlite' !== $this->driver) {
+ if (!filter_var(\ini_get('session.use_strict_mode'), \FILTER_VALIDATE_BOOLEAN) && self::LOCK_TRANSACTIONAL === $this->lockMode && 'sqlite' !== $this->driver) {
// In strict mode, session fixation is not possible: new sessions always start with a unique
// random id, so that concurrency is not possible and this code path can be skipped.
// Exclusive-reading of non-existent rows does not block, so we need to do an insert to block
@@ -935,7 +935,7 @@ class PdoSessionHandler extends AbstractSessionHandler
protected function getConnection()
{
if (null === $this->pdo) {
- $this->connect($this->dsn ?: ini_get('session.save_path'));
+ $this->connect($this->dsn ?: \ini_get('session.save_path'));
}
return $this->pdo;
diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/RedisSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/RedisSessionHandler.php
index 9573b31..31954e6 100644
--- a/vendor/symfony/http-foundation/Session/Storage/Handler/RedisSessionHandler.php
+++ b/vendor/symfony/http-foundation/Session/Storage/Handler/RedisSessionHandler.php
@@ -79,7 +79,7 @@ class RedisSessionHandler extends AbstractSessionHandler
*/
protected function doWrite(string $sessionId, string $data): bool
{
- $result = $this->redis->setEx($this->prefix.$sessionId, (int) ($this->ttl ?? ini_get('session.gc_maxlifetime')), $data);
+ $result = $this->redis->setEx($this->prefix.$sessionId, (int) ($this->ttl ?? \ini_get('session.gc_maxlifetime')), $data);
return $result && !$result instanceof ErrorInterface;
}
@@ -132,6 +132,6 @@ class RedisSessionHandler extends AbstractSessionHandler
#[\ReturnTypeWillChange]
public function updateTimestamp($sessionId, $data)
{
- return (bool) $this->redis->expire($this->prefix.$sessionId, (int) ($this->ttl ?? ini_get('session.gc_maxlifetime')));
+ return (bool) $this->redis->expire($this->prefix.$sessionId, (int) ($this->ttl ?? \ini_get('session.gc_maxlifetime')));
}
}
diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php
index 0461e99..f7c385f 100644
--- a/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php
+++ b/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php
@@ -30,6 +30,16 @@ class StrictSessionHandler extends AbstractSessionHandler
$this->handler = $handler;
}
+ /**
+ * Returns true if this handler wraps an internal PHP session save handler using \SessionHandler.
+ *
+ * @internal
+ */
+ public function isWrapper(): bool
+ {
+ return $this->handler instanceof \SessionHandler;
+ }
+
/**
* @return bool
*/
diff --git a/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php b/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php
index 1bfce55..595a9e2 100644
--- a/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php
+++ b/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php
@@ -162,6 +162,6 @@ class MetadataBag implements SessionBagInterface
{
$timeStamp = time();
$this->meta[self::CREATED] = $this->meta[self::UPDATED] = $this->lastUsed = $timeStamp;
- $this->meta[self::LIFETIME] = $lifetime ?? (int) ini_get('session.cookie_lifetime');
+ $this->meta[self::LIFETIME] = $lifetime ?? (int) \ini_get('session.cookie_lifetime');
}
}
diff --git a/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php b/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php
index 4440dcc..a50c827 100644
--- a/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php
+++ b/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php
@@ -141,12 +141,42 @@ class NativeSessionStorage implements SessionStorageInterface
throw new \RuntimeException('Failed to start the session: already started by PHP.');
}
- if (filter_var(ini_get('session.use_cookies'), \FILTER_VALIDATE_BOOLEAN) && headers_sent($file, $line)) {
+ if (filter_var(\ini_get('session.use_cookies'), \FILTER_VALIDATE_BOOLEAN) && headers_sent($file, $line)) {
throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line));
}
$sessionId = $_COOKIE[session_name()] ?? null;
- if ($sessionId && $this->saveHandler instanceof AbstractProxy && 'files' === $this->saveHandler->getSaveHandlerName() && !preg_match('/^[a-zA-Z0-9,-]{22,}$/', $sessionId)) {
+ /*
+ * Explanation of the session ID regular expression: `/^[a-zA-Z0-9,-]{22,250}$/`.
+ *
+ * ---------- Part 1
+ *
+ * The part `[a-zA-Z0-9,-]` is related to the PHP ini directive `session.sid_bits_per_character` defined as 6.
+ * See https://www.php.net/manual/en/session.configuration.php#ini.session.sid-bits-per-character.
+ * Allowed values are integers such as:
+ * - 4 for range `a-f0-9`
+ * - 5 for range `a-v0-9`
+ * - 6 for range `a-zA-Z0-9,-`
+ *
+ * ---------- Part 2
+ *
+ * The part `{22,250}` is related to the PHP ini directive `session.sid_length`.
+ * See https://www.php.net/manual/en/session.configuration.php#ini.session.sid-length.
+ * Allowed values are integers between 22 and 256, but we use 250 for the max.
+ *
+ * Where does the 250 come from?
+ * - The length of Windows and Linux filenames is limited to 255 bytes. Then the max must not exceed 255.
+ * - The session filename prefix is `sess_`, a 5 bytes string. Then the max must not exceed 255 - 5 = 250.
+ *
+ * ---------- Conclusion
+ *
+ * The parts 1 and 2 prevent the warning below:
+ * `PHP Warning: SessionHandler::read(): Session ID is too long or contains illegal characters. Only the A-Z, a-z, 0-9, "-", and "," characters are allowed.`
+ *
+ * The part 2 prevents the warning below:
+ * `PHP Warning: SessionHandler::read(): open(filepath, O_RDWR) failed: No such file or directory (2).`
+ */
+ if ($sessionId && $this->saveHandler instanceof AbstractProxy && 'files' === $this->saveHandler->getSaveHandlerName() && !preg_match('/^[a-zA-Z0-9,-]{22,250}$/', $sessionId)) {
// the session ID in the header is invalid, create a new one
session_id(session_create_id());
}
@@ -214,7 +244,7 @@ class NativeSessionStorage implements SessionStorageInterface
return false;
}
- if (null !== $lifetime && $lifetime != ini_get('session.cookie_lifetime')) {
+ if (null !== $lifetime && $lifetime != \ini_get('session.cookie_lifetime')) {
$this->save();
ini_set('session.cookie_lifetime', $lifetime);
$this->start();
@@ -249,7 +279,7 @@ class NativeSessionStorage implements SessionStorageInterface
unset($_SESSION[$key]);
}
}
- if ([$key = $this->metadataBag->getStorageKey()] === array_keys($_SESSION)) {
+ if ($_SESSION && [$key = $this->metadataBag->getStorageKey()] === array_keys($_SESSION)) {
unset($_SESSION[$key]);
}
diff --git a/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php b/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php
index 9b0cdeb..0defa4a 100644
--- a/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php
+++ b/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\StrictSessionHandler;
+
/**
* @author Drak
*/
@@ -22,7 +24,7 @@ class SessionHandlerProxy extends AbstractProxy implements \SessionHandlerInterf
{
$this->handler = $handler;
$this->wrapper = $handler instanceof \SessionHandler;
- $this->saveHandlerName = $this->wrapper ? ini_get('session.save_handler') : 'user';
+ $this->saveHandlerName = $this->wrapper || ($handler instanceof StrictSessionHandler && $handler->isWrapper()) ? \ini_get('session.save_handler') : 'user';
}
/**
diff --git a/vendor/symfony/http-foundation/composer.json b/vendor/symfony/http-foundation/composer.json
index d54bbfd..cb8d59f 100644
--- a/vendor/symfony/http-foundation/composer.json
+++ b/vendor/symfony/http-foundation/composer.json
@@ -24,8 +24,11 @@
"require-dev": {
"predis/predis": "~1.0",
"symfony/cache": "^4.4|^5.0|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4",
"symfony/mime": "^4.4|^5.0|^6.0",
- "symfony/expression-language": "^4.4|^5.0|^6.0"
+ "symfony/expression-language": "^4.4|^5.0|^6.0",
+ "symfony/rate-limiter": "^5.2|^6.0"
},
"suggest" : {
"symfony/mime": "To use the file extension guesser"
diff --git a/vendor/symfony/var-dumper/Caster/ArgsStub.php b/vendor/symfony/var-dumper/Caster/ArgsStub.php
index f8b485b..b3f7bbe 100644
--- a/vendor/symfony/var-dumper/Caster/ArgsStub.php
+++ b/vendor/symfony/var-dumper/Caster/ArgsStub.php
@@ -28,7 +28,7 @@ class ArgsStub extends EnumStub
$values = [];
foreach ($args as $k => $v) {
- $values[$k] = !is_scalar($v) && !$v instanceof Stub ? new CutStub($v) : $v;
+ $values[$k] = !\is_scalar($v) && !$v instanceof Stub ? new CutStub($v) : $v;
}
if (null === $params) {
parent::__construct($values, false);
diff --git a/vendor/symfony/var-dumper/Caster/IntlCaster.php b/vendor/symfony/var-dumper/Caster/IntlCaster.php
index d7099cb..581324d 100644
--- a/vendor/symfony/var-dumper/Caster/IntlCaster.php
+++ b/vendor/symfony/var-dumper/Caster/IntlCaster.php
@@ -102,7 +102,7 @@ class IntlCaster
'SIGNIFICANT_DIGIT_SYMBOL' => $c->getSymbol(\NumberFormatter::SIGNIFICANT_DIGIT_SYMBOL),
'MONETARY_GROUPING_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL),
]
- ),
+ ),
];
return self::castError($c, $a);
diff --git a/vendor/symfony/var-dumper/Dumper/AbstractDumper.php b/vendor/symfony/var-dumper/Dumper/AbstractDumper.php
index 2d3bb01..4185329 100644
--- a/vendor/symfony/var-dumper/Dumper/AbstractDumper.php
+++ b/vendor/symfony/var-dumper/Dumper/AbstractDumper.php
@@ -45,7 +45,7 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
public function __construct($output = null, string $charset = null, int $flags = 0)
{
$this->flags = $flags;
- $this->setCharset($charset ?: ini_get('php.output_encoding') ?: ini_get('default_charset') ?: 'UTF-8');
+ $this->setCharset($charset ?: \ini_get('php.output_encoding') ?: \ini_get('default_charset') ?: 'UTF-8');
$this->decimalPoint = \PHP_VERSION_ID >= 80000 ? '.' : localeconv()['decimal_point'];
$this->setOutput($output ?: static::$defaultOutput);
if (!$output && \is_string(static::$defaultOutput)) {
diff --git a/vendor/symfony/var-dumper/Dumper/CliDumper.php b/vendor/symfony/var-dumper/Dumper/CliDumper.php
index b3d9e25..e3861cd 100644
--- a/vendor/symfony/var-dumper/Dumper/CliDumper.php
+++ b/vendor/symfony/var-dumper/Dumper/CliDumper.php
@@ -83,7 +83,7 @@ class CliDumper extends AbstractDumper
]);
}
- $this->displayOptions['fileLinkFormat'] = ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: 'file://%f#L%l';
+ $this->displayOptions['fileLinkFormat'] = \ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: 'file://%f#L%l';
}
/**
diff --git a/vendor/symfony/var-dumper/Dumper/HtmlDumper.php b/vendor/symfony/var-dumper/Dumper/HtmlDumper.php
index 7fe31ef..9b57f90 100644
--- a/vendor/symfony/var-dumper/Dumper/HtmlDumper.php
+++ b/vendor/symfony/var-dumper/Dumper/HtmlDumper.php
@@ -81,7 +81,7 @@ class HtmlDumper extends CliDumper
{
AbstractDumper::__construct($output, $charset, $flags);
$this->dumpId = 'sf-dump-'.mt_rand();
- $this->displayOptions['fileLinkFormat'] = ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
+ $this->displayOptions['fileLinkFormat'] = \ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
$this->styles = static::$themes['dark'] ?? self::$themes['dark'];
}
@@ -882,7 +882,7 @@ EOHTML
}
if ('const' === $style && isset($attr['value'])) {
- $style .= sprintf(' title="%s"', esc(is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value'])));
+ $style .= sprintf(' title="%s"', esc(\is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value'])));
} elseif ('public' === $style) {
$style .= sprintf(' title="%s"', empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property');
} elseif ('str' === $style && 1 < $attr['length']) {
diff --git a/vendor/topthink/framework/.gitignore b/vendor/topthink/framework/.gitignore
index b267fba..b2fd3b9 100644
--- a/vendor/topthink/framework/.gitignore
+++ b/vendor/topthink/framework/.gitignore
@@ -4,4 +4,7 @@ composer.lock
.DS_Store
Thumbs.db
/.idea
-/.vscode
\ No newline at end of file
+/.vscode
+/.settings
+/.buildpath
+/.project
\ No newline at end of file
diff --git a/vendor/topthink/framework/src/helper.php b/vendor/topthink/framework/src/helper.php
index e436e14..caba0ae 100644
--- a/vendor/topthink/framework/src/helper.php
+++ b/vendor/topthink/framework/src/helper.php
@@ -58,10 +58,11 @@ if (!function_exists('abort')) {
if (!function_exists('app')) {
/**
* 快速获取容器中的实例 支持依赖注入
- * @param string $name 类名或标识 默认获取当前应用实例
- * @param array $args 参数
- * @param bool $newInstance 是否每次创建新的实例
- * @return object|App
+ * @template T
+ * @param string|class-string $name 类名或标识 默认获取当前应用实例
+ * @param array $args 参数
+ * @param bool $newInstance 是否每次创建新的实例
+ * @return T|object|App
*/
function app(string $name = '', array $args = [], bool $newInstance = false)
{
diff --git a/vendor/topthink/framework/src/think/App.php b/vendor/topthink/framework/src/think/App.php
index 073a41a..b189cd9 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.12LTS';
+ const VERSION = '6.0.13LTS';
/**
* 应用调试模式
diff --git a/vendor/topthink/framework/src/think/Container.php b/vendor/topthink/framework/src/think/Container.php
index e3a4341..60b4b35 100644
--- a/vendor/topthink/framework/src/think/Container.php
+++ b/vendor/topthink/framework/src/think/Container.php
@@ -108,11 +108,11 @@ class Container implements ContainerInterface, ArrayAccess, IteratorAggregate, C
/**
* 获取容器中的对象实例 不存在则创建
- * @access public
- * @param string $abstract 类名或者标识
- * @param array|true $vars 变量
- * @param bool $newInstance 是否每次创建新的实例
- * @return object
+ * @template T
+ * @param string|class-string $abstract 类名或者标识
+ * @param array $vars 变量
+ * @param bool $newInstance 是否每次创建新的实例
+ * @return T|object
*/
public static function pull(string $abstract, array $vars = [], bool $newInstance = false)
{
@@ -121,9 +121,9 @@ class Container implements ContainerInterface, ArrayAccess, IteratorAggregate, C
/**
* 获取容器中的对象实例
- * @access public
- * @param string $abstract 类名或者标识
- * @return object
+ * @template T
+ * @param string|class-string $abstract 类名或者标识
+ * @return T|object
*/
public function get($abstract)
{
@@ -232,11 +232,11 @@ class Container implements ContainerInterface, ArrayAccess, IteratorAggregate, C
/**
* 创建类的实例 已经存在则直接获取
- * @access public
- * @param string $abstract 类名或者标识
- * @param array $vars 变量
- * @param bool $newInstance 是否每次创建新的实例
- * @return mixed
+ * @template T
+ * @param string|class-string $abstract 类名或者标识
+ * @param array $vars 变量
+ * @param bool $newInstance 是否每次创建新的实例
+ * @return T|object
*/
public function make(string $abstract, array $vars = [], bool $newInstance = false)
{
diff --git a/vendor/topthink/framework/src/think/Lang.php b/vendor/topthink/framework/src/think/Lang.php
index 0226f81..5f16c46 100644
--- a/vendor/topthink/framework/src/think/Lang.php
+++ b/vendor/topthink/framework/src/think/Lang.php
@@ -129,6 +129,8 @@ class Lang
return;
}
+ $this->setLangSet($langset);
+
// 加载系统语言包
$this->load([
$this->app->getThinkPath() . 'lang' . DIRECTORY_SEPARATOR . $langset . '.php',
diff --git a/vendor/topthink/framework/src/think/Request.php b/vendor/topthink/framework/src/think/Request.php
index fe9938d..99f4f80 100644
--- a/vendor/topthink/framework/src/think/Request.php
+++ b/vendor/topthink/framework/src/think/Request.php
@@ -1237,7 +1237,7 @@ class Request implements ArrayAccess
* @access public
* @param string $name header名称
* @param string $default 默认值
- * @return string|array
+ * @return string|array|null
*/
public function header(string $name = '', string $default = null)
{
@@ -1416,6 +1416,10 @@ class Request implements ArrayAccess
foreach ($filters as $filter) {
if (is_callable($filter)) {
// 调用函数或者方法过滤
+ if (is_null($value)) {
+ continue;
+ }
+
$value = call_user_func($filter, $value);
} elseif (is_scalar($value)) {
if (is_string($filter) && false !== strpos($filter, '/')) {
@@ -1490,7 +1494,7 @@ class Request implements ArrayAccess
if (is_int($key)) {
$default = null;
$key = $val;
- if (!isset($data[$key])) {
+ if (!key_exists($key, $data)) {
continue;
}
} else {
diff --git a/vendor/topthink/framework/src/think/Route.php b/vendor/topthink/framework/src/think/Route.php
index a3acf85..e45cb33 100644
--- a/vendor/topthink/framework/src/think/Route.php
+++ b/vendor/topthink/framework/src/think/Route.php
@@ -167,6 +167,8 @@ class Route
}
$this->config = array_merge($this->config, $this->app->config->get('route'));
+
+ $this->init();
}
protected function init()
@@ -630,6 +632,18 @@ class Route
return $this->rule($rule, $route, 'PATCH');
}
+ /**
+ * 注册HEAD路由
+ * @access public
+ * @param string $rule 路由规则
+ * @param mixed $route 路由地址
+ * @return RuleItem
+ */
+ public function head(string $rule, $route): RuleItem
+ {
+ return $this->rule($rule, $route, 'HEAD');
+ }
+
/**
* 注册OPTIONS路由
* @access public
@@ -752,7 +766,6 @@ class Route
{
$this->request = $request;
$this->host = $this->request->host(true);
- $this->init();
if ($withRoute) {
//加载路由
diff --git a/vendor/topthink/framework/src/think/cache/Driver.php b/vendor/topthink/framework/src/think/cache/Driver.php
index 37ffbc9..7dc0d30 100644
--- a/vendor/topthink/framework/src/think/cache/Driver.php
+++ b/vendor/topthink/framework/src/think/cache/Driver.php
@@ -153,7 +153,9 @@ abstract class Driver implements CacheInterface, CacheHandlerInterface
public function remember(string $name, $value, $expire = null)
{
if ($this->has($name)) {
- return $this->get($name);
+ if (($hit = $this->get($name)) !== null) {
+ return $hit;
+ }
}
$time = time();
diff --git a/vendor/topthink/framework/src/think/console/output/driver/Console.php b/vendor/topthink/framework/src/think/console/output/driver/Console.php
index 31bdf1f..3061f55 100644
--- a/vendor/topthink/framework/src/think/console/output/driver/Console.php
+++ b/vendor/topthink/framework/src/think/console/output/driver/Console.php
@@ -214,12 +214,12 @@ class Console
/**
* 获取终端模式
- * @return string x 或 null
+ * @return string x
*/
private function getMode()
{
if (!function_exists('proc_open')) {
- return;
+ return '';
}
$descriptorspec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
@@ -234,7 +234,8 @@ class Console
return $matches[2] . 'x' . $matches[1];
}
}
- return;
+
+ return '';
}
private function stringWidth(string $string): int
diff --git a/vendor/topthink/framework/src/think/facade/Route.php b/vendor/topthink/framework/src/think/facade/Route.php
index 5a5b955..37504ce 100644
--- a/vendor/topthink/framework/src/think/facade/Route.php
+++ b/vendor/topthink/framework/src/think/facade/Route.php
@@ -56,6 +56,7 @@ use think\route\Url as UrlBuild;
* @method static RuleItem put(string $rule, mixed $route) 注册PUT路由
* @method static RuleItem delete(string $rule, mixed $route) 注册DELETE路由
* @method static RuleItem patch(string $rule, mixed $route) 注册PATCH路由
+ * @method static RuleItem head(string $rule, mixed $route) 注册HEAD路由
* @method static RuleItem options(string $rule, mixed $route) 注册OPTIONS路由
* @method static Resource resource(string $rule, string $route) 注册资源路由
* @method static RuleItem view(string $rule, string $template = '', array $vars = []) 注册视图路由
diff --git a/vendor/topthink/framework/src/think/filesystem/driver/Local.php b/vendor/topthink/framework/src/think/filesystem/driver/Local.php
index 31172d0..5749335 100644
--- a/vendor/topthink/framework/src/think/filesystem/driver/Local.php
+++ b/vendor/topthink/framework/src/think/filesystem/driver/Local.php
@@ -42,8 +42,15 @@ class Local extends Driver
);
}
+ /**
+ * 获取文件访问地址
+ * @param string $path 文件路径
+ * @return string
+ */
public function url(string $path): string
{
+ $path = str_replace('\\', '/', $path);
+
if (isset($this->config['url'])) {
return $this->concatPathToUrl($this->config['url'], $path);
}
diff --git a/vendor/topthink/framework/src/think/response/Redirect.php b/vendor/topthink/framework/src/think/response/Redirect.php
index 1f38764..ee067be 100644
--- a/vendor/topthink/framework/src/think/response/Redirect.php
+++ b/vendor/topthink/framework/src/think/response/Redirect.php
@@ -74,9 +74,9 @@ class Redirect extends Response
* @access public
* @return $this
*/
- public function remember()
+ public function remember($complete = false)
{
- $this->session->set('redirect_url', $this->request->url());
+ $this->session->set('redirect_url', $this->request->url($complete));
return $this;
}
diff --git a/vendor/topthink/framework/src/think/route/Dispatch.php b/vendor/topthink/framework/src/think/route/Dispatch.php
index 0599dc1..58666b5 100644
--- a/vendor/topthink/framework/src/think/route/Dispatch.php
+++ b/vendor/topthink/framework/src/think/route/Dispatch.php
@@ -96,7 +96,7 @@ abstract class Dispatch
if ($data instanceof Response) {
$response = $data;
} elseif ($data instanceof ResponseInterface) {
- $response = Response::create($data->getBody()->getContents(), 'html', $data->getStatusCode());
+ $response = Response::create((string) $data->getBody(), 'html', $data->getStatusCode());
foreach ($data->getHeaders() as $header => $values) {
$response->header([$header => implode(", ", $values)]);
diff --git a/vendor/topthink/framework/src/tpl/think_exception.tpl b/vendor/topthink/framework/src/tpl/think_exception.tpl
index 7766caf..6ea9677 100644
--- a/vendor/topthink/framework/src/tpl/think_exception.tpl
+++ b/vendor/topthink/framework/src/tpl/think_exception.tpl
@@ -492,7 +492,7 @@ if (!function_exists('echo_value')) {
}
})();
- $.getScript('//cdn.bootcss.com/prettify/r298/prettify.min.js', function(){
+ $.getScript('//cdn.bootcdn.net/ajax/libs/prettify/r298/prettify.min.js', function(){
prettyPrint();
});
})();
diff --git a/vendor/topthink/think-orm/composer.json b/vendor/topthink/think-orm/composer.json
index 5e86ac8..097d924 100644
--- a/vendor/topthink/think-orm/composer.json
+++ b/vendor/topthink/think-orm/composer.json
@@ -16,8 +16,8 @@
"php": ">=7.1.0",
"ext-json": "*",
"ext-pdo": "*",
- "psr/simple-cache": "^1.0",
- "psr/log": "~1.0",
+ "psr/simple-cache": "^1.0|^2.0",
+ "psr/log": "^1.0|^2.0",
"topthink/think-helper":"^3.1"
},
"require-dev": {
diff --git a/vendor/topthink/think-orm/src/db/BaseQuery.php b/vendor/topthink/think-orm/src/db/BaseQuery.php
index d472590..d05905c 100644
--- a/vendor/topthink/think-orm/src/db/BaseQuery.php
+++ b/vendor/topthink/think-orm/src/db/BaseQuery.php
@@ -628,7 +628,7 @@ abstract class BaseQuery
if (!isset($total) && !$simple) {
$options = $this->getOptions();
- unset($this->options['order'], $this->options['limit'], $this->options['page'], $this->options['field']);
+ unset($this->options['order'], $this->options['cache'], $this->options['limit'], $this->options['page'], $this->options['field']);
$bind = $this->bind;
$total = $this->count();
@@ -705,7 +705,7 @@ abstract class BaseQuery
->limit(1)
->find();
- $result = $data[$key];
+ $result = $data[$key] ?? 0;
if (is_numeric($result)) {
$lastId = 'asc' == $sort ? ($result - 1) + ($page - 1) * $listRows : ($result + 1) - ($page - 1) * $listRows;
diff --git a/vendor/topthink/think-orm/src/db/PDOConnection.php b/vendor/topthink/think-orm/src/db/PDOConnection.php
index 77a0b01..1748d20 100644
--- a/vendor/topthink/think-orm/src/db/PDOConnection.php
+++ b/vendor/topthink/think-orm/src/db/PDOConnection.php
@@ -1274,7 +1274,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 = '\'' . addcslashes($value, "'") . '\'';
+ $value = '\'' . addslashes($value) . '\'';
} elseif (PDO::PARAM_INT == $type && '' === $value) {
$value = '0';
}
diff --git a/vendor/topthink/think-orm/src/db/builder/Oracle.php b/vendor/topthink/think-orm/src/db/builder/Oracle.php
index 77ad3c8..38feb5d 100644
--- a/vendor/topthink/think-orm/src/db/builder/Oracle.php
+++ b/vendor/topthink/think-orm/src/db/builder/Oracle.php
@@ -12,6 +12,8 @@ namespace think\db\builder;
use think\db\Builder;
use think\db\Query;
+use think\db\exception\DbException as Exception;
+use think\db\Raw;
/**
* Oracle数据库驱动
@@ -64,19 +66,51 @@ class Oracle extends Builder
/**
* 字段和表名处理
* @access public
- * @param Query $query 查询对象
- * @param string $key
- * @param string $strict
+ * @param Query $query 查询对象
+ * @param string $key
+ * @param bool $strict
* @return string
+ * @throws Exception
*/
public function parseKey(Query $query, $key, bool $strict = false): string
{
+ if (is_int($key)) {
+ return (string) $key;
+ } elseif ($key instanceof Raw) {
+ return $this->parseRaw($query, $key);
+ }
+
$key = trim($key);
if (strpos($key, '->') && false === strpos($key, '(')) {
// JSON字段支持
[$field, $name] = explode($key, '->');
$key = $field . '."' . $name . '"';
+ } elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)\[\s]/', $key)) {
+ [$table, $key] = explode('.', $key, 2);
+
+ $alias = $query->getOptions('alias');
+
+ if ('__TABLE__' == $table) {
+ $table = $query->getOptions('table');
+ $table = is_array($table) ? array_shift($table) : $table;
+ }
+
+ if (isset($alias[$table])) {
+ $table = $alias[$table];
+ }
+ }
+
+ if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) {
+ throw new Exception('not support data:' . $key);
+ }
+
+ if ('*' != $key && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) {
+ $key = '"' . $key . '"';
+ }
+
+ if (isset($table)) {
+ $key = '"' . $table . '".' . $key;
}
return $key;
diff --git a/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php b/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php
index dabfb92..0eab363 100644
--- a/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php
+++ b/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php
@@ -12,6 +12,7 @@ declare (strict_types = 1);
namespace think\db\concern;
+use think\db\exception\DbException;
use think\db\Raw;
/**
@@ -42,6 +43,11 @@ trait AggregateQuery
{
if (!empty($this->options['group'])) {
// 支持GROUP
+
+ if (!preg_match('/^[\w\.\*]+$/', $field)) {
+ throw new DbException('not support data:' . $field);
+ }
+
$options = $this->getOptions();
$subSql = $this->options($options)
->field('count(' . $field . ') AS think_count')
diff --git a/vendor/topthink/think-orm/src/db/connector/Oracle.php b/vendor/topthink/think-orm/src/db/connector/Oracle.php
index 236d8bf..c8e957a 100644
--- a/vendor/topthink/think-orm/src/db/connector/Oracle.php
+++ b/vendor/topthink/think-orm/src/db/connector/Oracle.php
@@ -51,7 +51,7 @@ class Oracle extends PDOConnection
public function getFields(string $tableName): array
{
[$tableName] = explode(' ', $tableName);
- $sql = "select a.column_name,data_type,DECODE (nullable, 'Y', 0, 1) notnull,data_default, DECODE (A .column_name,b.column_name,1,0) pk from all_tab_columns a,(select column_name from all_constraints c, all_cons_columns col where c.constraint_name = col.constraint_name and c.constraint_type = 'P' and c.table_name = '" . strtoupper($tableName) . "' ) b where table_name = '" . strtoupper($tableName) . "' and a.column_name = b.column_name (+)";
+ $sql = "select a.column_name,data_type,DECODE (nullable, 'Y', 0, 1) notnull,data_default, DECODE (A .column_name,b.column_name,1,0) pk from all_tab_columns a,(select column_name from all_constraints c, all_cons_columns col where c.constraint_name = col.constraint_name and c.constraint_type = 'P' and c.table_name = '" . $tableName . "' ) b where table_name = '" . $tableName . "' and a.column_name = b.column_name (+)";
$pdo = $this->getPDOStatement($sql);
$result = $pdo->fetchAll(PDO::FETCH_ASSOC);
@@ -98,16 +98,18 @@ class Oracle extends PDOConnection
/**
* 获取最近插入的ID
* @access public
- * @param BaseQuery $query 查询对象
- * @param string $sequence 自增序列名
+ * @param BaseQuery $query 查询对象
+ * @param string|null $sequence 自增序列名
* @return mixed
*/
public function getLastInsID(BaseQuery $query, string $sequence = null)
{
- $pdo = $this->linkID->query("select {$sequence}.currval as id from dual");
- $result = $pdo->fetchColumn();
+ if(!is_null($sequence)) {
+ $pdo = $this->linkID->query("select {$sequence}.currval as id from dual");
+ $result = $pdo->fetchColumn();
+ }
- return $result;
+ return $result ?? null;
}
protected function supportSavepoint(): bool
diff --git a/vendor/topthink/think-orm/src/db/connector/Sqlsrv.php b/vendor/topthink/think-orm/src/db/connector/Sqlsrv.php
index 10d944f..aee3343 100644
--- a/vendor/topthink/think-orm/src/db/connector/Sqlsrv.php
+++ b/vendor/topthink/think-orm/src/db/connector/Sqlsrv.php
@@ -44,6 +44,10 @@ class Sqlsrv extends PDOConnection
$dsn .= ',' . $config['hostport'];
}
+ if (!empty($config['trust_server_certificate'])) {
+ $dsn .= ';TrustServerCertificate=' . $config['trust_server_certificate'];
+ }
+
return $dsn;
}
diff --git a/vendor/topthink/think-orm/src/model/Collection.php b/vendor/topthink/think-orm/src/model/Collection.php
index 9d31e20..079e856 100644
--- a/vendor/topthink/think-orm/src/model/Collection.php
+++ b/vendor/topthink/think-orm/src/model/Collection.php
@@ -81,12 +81,13 @@ class Collection extends BaseCollection
* 设置需要隐藏的输出属性
* @access public
* @param array $hidden 属性列表
+ * @param bool $merge 是否合并
* @return $this
*/
- public function hidden(array $hidden)
+ public function hidden(array $hidden, bool $merge = false)
{
- $this->each(function (Model $model) use ($hidden) {
- $model->hidden($hidden);
+ $this->each(function (Model $model) use ($hidden, $merge) {
+ $model->hidden($hidden, $merge);
});
return $this;
@@ -96,12 +97,13 @@ class Collection extends BaseCollection
* 设置需要输出的属性
* @access public
* @param array $visible
+ * @param bool $merge 是否合并
* @return $this
*/
- public function visible(array $visible)
+ public function visible(array $visible, bool $merge = false)
{
- $this->each(function (Model $model) use ($visible) {
- $model->visible($visible);
+ $this->each(function (Model $model) use ($visible, $merge) {
+ $model->visible($visible, $merge);
});
return $this;
@@ -111,12 +113,13 @@ class Collection extends BaseCollection
* 设置需要追加的输出属性
* @access public
* @param array $append 属性列表
+ * @param bool $merge 是否合并
* @return $this
*/
- public function append(array $append)
+ public function append(array $append, bool $merge = false)
{
- $this->each(function (Model $model) use ($append) {
- $model->append($append);
+ $this->each(function (Model $model) use ($append, $merge) {
+ $model->append($append, $merge);
});
return $this;
diff --git a/vendor/topthink/think-orm/src/model/Pivot.php b/vendor/topthink/think-orm/src/model/Pivot.php
index 893c01b..ac16d9e 100644
--- a/vendor/topthink/think-orm/src/model/Pivot.php
+++ b/vendor/topthink/think-orm/src/model/Pivot.php
@@ -35,9 +35,9 @@ class Pivot extends Model
/**
* 架构函数
* @access public
- * @param array $data 数据
- * @param Model $parent 上级模型
- * @param string $table 中间数据表名
+ * @param array $data 数据
+ * @param Model|null $parent 上级模型
+ * @param string $table 中间数据表名
*/
public function __construct(array $data = [], Model $parent = null, string $table = '')
{
@@ -50,4 +50,21 @@ class Pivot extends Model
parent::__construct($data);
}
+ /**
+ * 创建新的模型实例
+ * @access public
+ * @param array $data 数据
+ * @param mixed $where 更新条件
+ * @param array $options 参数
+ * @return Model
+ */
+ public function newInstance(array $data = [], $where = null, array $options = []): Model
+ {
+ $model = parent::newInstance($data, $where, $options);
+
+ $model->parent = $this->parent;
+ $model->name = $this->name;
+
+ return $model;
+ }
}
diff --git a/vendor/topthink/think-orm/src/model/concern/Conversion.php b/vendor/topthink/think-orm/src/model/concern/Conversion.php
index 22d6256..b584ba9 100644
--- a/vendor/topthink/think-orm/src/model/concern/Conversion.php
+++ b/vendor/topthink/think-orm/src/model/concern/Conversion.php
@@ -82,11 +82,16 @@ trait Conversion
* 设置需要附加的输出属性
* @access public
* @param array $append 属性列表
+ * @param bool $merge 是否合并
* @return $this
*/
- public function append(array $append = [])
+ public function append(array $append = [], bool $merge = false)
{
- $this->append = $append;
+ if ($merge) {
+ $this->append = array_merge($this->append, $append);
+ } else {
+ $this->append = $append;
+ }
return $this;
}
@@ -147,11 +152,16 @@ trait Conversion
* 设置需要隐藏的输出属性
* @access public
* @param array $hidden 属性列表
+ * @param bool $merge 是否合并
* @return $this
*/
- public function hidden(array $hidden = [])
+ public function hidden(array $hidden = [], bool $merge = false)
{
- $this->hidden = $hidden;
+ if ($merge) {
+ $this->hidden = array_merge($this->hidden, $hidden);
+ } else {
+ $this->hidden = $hidden;
+ }
return $this;
}
@@ -160,11 +170,16 @@ trait Conversion
* 设置需要输出的属性
* @access public
* @param array $visible
+ * @param bool $merge 是否合并
* @return $this
*/
- public function visible(array $visible = [])
+ public function visible(array $visible = [], bool $merge = false)
{
- $this->visible = $visible;
+ if ($merge) {
+ $this->visible = array_merge($this->visible, $visible);
+ } else {
+ $this->visible = $visible;
+ }
return $this;
}
diff --git a/vendor/topthink/think-orm/src/model/relation/BelongsTo.php b/vendor/topthink/think-orm/src/model/relation/BelongsTo.php
index 0802b11..dd54f52 100644
--- a/vendor/topthink/think-orm/src/model/relation/BelongsTo.php
+++ b/vendor/topthink/think-orm/src/model/relation/BelongsTo.php
@@ -241,6 +241,7 @@ class BelongsTo extends OneToOne
if (!empty($this->bindAttr)) {
// 绑定关联属性
$this->bindAttr($result, $relationModel);
+ $result->hidden([$relation]);
}
}
}
@@ -282,6 +283,7 @@ class BelongsTo extends OneToOne
if (!empty($this->bindAttr)) {
// 绑定关联属性
$this->bindAttr($result, $relationModel);
+ $result->hidden([$relation]);
}
}
diff --git a/vendor/topthink/think-orm/src/model/relation/BelongsToMany.php b/vendor/topthink/think-orm/src/model/relation/BelongsToMany.php
index 9890906..6049f01 100644
--- a/vendor/topthink/think-orm/src/model/relation/BelongsToMany.php
+++ b/vendor/topthink/think-orm/src/model/relation/BelongsToMany.php
@@ -157,7 +157,12 @@ class BelongsToMany extends Relation
}
}
- $result->setRelation($this->pivotDataName, $this->newPivot($pivot));
+ $pivotData = $this->pivot->newInstance($pivot, [
+ [$this->localKey, '=', $this->parent->getKey(), null],
+ [$this->foreignKey, '=', $result->getKey(), null],
+ ]);
+
+ $result->setRelation($this->pivotDataName, $pivotData);
return $pivot;
}
diff --git a/vendor/topthink/think-orm/src/model/relation/HasOne.php b/vendor/topthink/think-orm/src/model/relation/HasOne.php
index 269f0d7..43f220c 100644
--- a/vendor/topthink/think-orm/src/model/relation/HasOne.php
+++ b/vendor/topthink/think-orm/src/model/relation/HasOne.php
@@ -240,6 +240,7 @@ class HasOne extends OneToOne
if (!empty($this->bindAttr)) {
// 绑定关联属性
$this->bindAttr($result, $relationModel);
+ $result->hidden([$relation]);
}
}
}
@@ -281,6 +282,7 @@ class HasOne extends OneToOne
if (!empty($this->bindAttr)) {
// 绑定关联属性
$this->bindAttr($result, $relationModel);
+ $result->hidden([$relation]);
}
}
diff --git a/vendor/topthink/think-orm/src/model/relation/MorphMany.php b/vendor/topthink/think-orm/src/model/relation/MorphMany.php
index 82910cb..39209ae 100644
--- a/vendor/topthink/think-orm/src/model/relation/MorphMany.php
+++ b/vendor/topthink/think-orm/src/model/relation/MorphMany.php
@@ -30,6 +30,7 @@ class MorphMany extends Relation
* @var string
*/
protected $morphKey;
+
/**
* 多态字段名
* @var string
@@ -331,6 +332,33 @@ class MorphMany extends Relation
return empty($result) ? false : $result;
}
+ /**
+ * 获取多态关联外键
+ * @return string
+ */
+ public function getMorphKey()
+ {
+ return $this->morphKey;
+ }
+
+ /**
+ * 获取多态字段名
+ * @return string
+ */
+ public function getMorphType()
+ {
+ return $this->morphType;
+ }
+
+ /**
+ * 获取多态类型
+ * @return string
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
/**
* 执行基础查询(仅执行一次)
* @access protected
diff --git a/vendor/topthink/think-orm/src/model/relation/MorphTo.php b/vendor/topthink/think-orm/src/model/relation/MorphTo.php
index 986380e..f53fe4f 100644
--- a/vendor/topthink/think-orm/src/model/relation/MorphTo.php
+++ b/vendor/topthink/think-orm/src/model/relation/MorphTo.php
@@ -208,6 +208,9 @@ class MorphTo extends Relation
// 多态类型映射
$model = $this->parseModel($key);
$obj = new $model;
+ if (!\is_null($closure)) {
+ $obj = $closure($obj);
+ }
$pk = $obj->getPk();
$list = $obj->with($subRelation)
->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)
diff --git a/vendor/topthink/think-orm/src/model/relation/MorphToMany.php b/vendor/topthink/think-orm/src/model/relation/MorphToMany.php
index 32f853f..c566488 100644
--- a/vendor/topthink/think-orm/src/model/relation/MorphToMany.php
+++ b/vendor/topthink/think-orm/src/model/relation/MorphToMany.php
@@ -24,6 +24,13 @@ use think\model\Pivot;
class MorphToMany extends BelongsToMany
{
+ /**
+ * 多态关系的模型名映射别名的数组
+ *
+ * @var array
+ */
+ protected static $morphMap = [];
+
/**
* 多态字段名
* @var string
@@ -58,6 +65,9 @@ class MorphToMany extends BelongsToMany
$this->morphType = $morphType;
$this->inverse = $inverse;
$this->morphClass = $inverse ? $model : get_class($parent);
+ if (isset(static::$morphMap[$this->morphClass])) {
+ $this->morphClass = static::$morphMap[$this->morphClass];
+ }
$foreignKey = $inverse ? $morphKey : $localKey;
$localKey = $inverse ? $localKey : $morphKey;
@@ -460,4 +470,21 @@ class MorphToMany extends BelongsToMany
}
}
+ /**
+ * 设置或获取多态关系的模型名映射别名的数组
+ *
+ * @param array|null $map
+ * @param bool $merge
+ * @return array
+ */
+ public static function morphMap(array $map = null, $merge = true): array
+ {
+ if (is_array($map)) {
+ static::$morphMap = $merge && static::$morphMap
+ ? $map + static::$morphMap : $map;
+ }
+
+ return static::$morphMap;
+ }
+
}
diff --git a/vendor/topthink/think-orm/src/model/relation/OneToOne.php b/vendor/topthink/think-orm/src/model/relation/OneToOne.php
index d47d7f3..ba51753 100644
--- a/vendor/topthink/think-orm/src/model/relation/OneToOne.php
+++ b/vendor/topthink/think-orm/src/model/relation/OneToOne.php
@@ -186,18 +186,30 @@ abstract class OneToOne extends Relation
* @return Model|false
*/
public function save($data, bool $replace = true)
+ {
+ $model = $this->make();
+
+ return $model->replace($replace)->save($data) ? $model : false;
+ }
+
+ /**
+ * 创建关联对象实例
+ * @param array|Model $data
+ * @return Model
+ */
+ public function make($data = []): Model
{
if ($data instanceof Model) {
$data = $data->getData();
}
- $model = new $this->model;
// 保存关联表数据
$data[$this->foreignKey] = $this->parent->{$this->localKey};
- return $model->replace($replace)->save($data) ? $model : false;
+ return new $this->model($data);
}
+
/**
* 绑定关联表的属性到父模型属性
* @access public