From 87db0d0569846bbaf13c86920f27069b4f2fee05 Mon Sep 17 00:00:00 2001 From: jacky huang Date: Thu, 21 Jan 2021 17:47:40 +0800 Subject: [PATCH 01/10] v.1.2.5 (#21) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 1:更新ip2region,php-cron-scheduler包 2:替换phpqrcode 3:移除lcobucci/jwt * 后台接入产品动态,相关链接指向官网 * 升级composer依赖包 * v1.2.5阶段新合并 Co-authored-by: winzer --- CHANGELOG.md | 17 + README.md | 9 +- app/Console/Tasks/CourseIndexTask.php | 8 +- app/Console/Tasks/GroupIndexTask.php | 8 +- app/Console/Tasks/UserIndexTask.php | 8 +- .../Admin/Controllers/IndexController.php | 2 + app/Http/Admin/Services/Index.php | 14 + app/Http/Admin/Views/index/index.volt | 2 +- app/Http/Admin/Views/index/main_app_info.volt | 2 +- .../Admin/Views/index/main_app_trend.volt | 15 +- .../Admin/Views/index/main_team_info.volt | 2 +- .../Home/Controllers/PublicController.php | 15 +- app/Http/Home/Views/partials/footer.volt | 6 +- app/Library/AppInfo.php | 4 +- app/Library/Helper.php | 7 +- composer.json | 7 +- composer.lock | 4825 ++++++++++------- 17 files changed, 2974 insertions(+), 1977 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5ac9d27..26b077a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +### [v1.2.5](https://gitee.com/koogua/course-tencent-cloud/releases/v1.2.5)(2021-01-20) + +### 新增 + +- 自动化安装脚本 +- 自动化更新脚本 +- 自动化备份脚本 + +### 更新 + +- 更新ip2region包 +- 更新php-cron-scheduler包 +- 替换aferrandini/phpqrcode为endroid/qr-code +- 替换joyqi/hyper-down为league/commonmark +- 移除lcobucci/jwt包 +- 相关连接指向官网 + ### [v1.2.4](https://gitee.com/koogua/course-tencent-cloud/releases/v1.2.4)(2021-01-10) #### 增加 diff --git a/README.md b/README.md index 29951f81..b8019549 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,11 @@ 酷瓜云课堂,依托腾讯云基础服务架构,采用C扩展框架Phalcon开发,GPL-2.0开源协议,致力开源网课系统,开源网校系统,开源在线教育系统。 -![](https://img.shields.io/static/v1?label=release&message=1.2.4&color=blue) -![](https://img.shields.io/static/v1?label=stars&message=170&color=blue) -![](https://img.shields.io/static/v1?label=forks&message=66&color=blue) -![](https://img.shields.io/static/v1?label=license&message=GPL-2.0&color=blue) +[![Gitee star](https://gitee.com/koogua/course-tencent-cloud/badge/star.svg?theme=gitee)](https://gitee.com/koogua/course-tencent-cloud) +[![Gitee fork](https://gitee.com/koogua/course-tencent-cloud/badge/fork.svg?theme=gitee)](https://gitee.com/koogua/course-tencent-cloud) +[![Github stars](https://img.shields.io/github/stars/mindskip/xzs-mysql?logo=github)](https://github.com/xiaochong0302/course-tencent-cloud) +[![Github forks](https://img.shields.io/github/forks/mindskip/xzs-mysql?logo=github)](https://github.com/xiaochong0302/course-tencent-cloud) +![GPL-2.0](https://img.shields.io/static/v1?label=license&message=GPL-2.0&color=blue) ### 系统功能 diff --git a/app/Console/Tasks/CourseIndexTask.php b/app/Console/Tasks/CourseIndexTask.php index 23a148cc..ec4fc523 100644 --- a/app/Console/Tasks/CourseIndexTask.php +++ b/app/Console/Tasks/CourseIndexTask.php @@ -60,11 +60,11 @@ class CourseIndexTask extends Task $index = $handler->getXS()->getIndex(); - echo 'start clean index' . PHP_EOL; + echo 'start clean course index' . PHP_EOL; $index->clean(); - echo 'end clean index' . PHP_EOL; + echo 'end clean course index' . PHP_EOL; } /** @@ -82,7 +82,7 @@ class CourseIndexTask extends Task $index = $handler->getXS()->getIndex(); - echo 'start rebuild index' . PHP_EOL; + echo 'start rebuild course index' . PHP_EOL; $index->beginRebuild(); @@ -93,7 +93,7 @@ class CourseIndexTask extends Task $index->endRebuild(); - echo 'end rebuild index' . PHP_EOL; + echo 'end rebuild course index' . PHP_EOL; } /** diff --git a/app/Console/Tasks/GroupIndexTask.php b/app/Console/Tasks/GroupIndexTask.php index 4e9c2918..2b3818c8 100644 --- a/app/Console/Tasks/GroupIndexTask.php +++ b/app/Console/Tasks/GroupIndexTask.php @@ -60,11 +60,11 @@ class GroupIndexTask extends Task $index = $handler->getXS()->getIndex(); - echo 'start clean index' . PHP_EOL; + echo 'start clean group index' . PHP_EOL; $index->clean(); - echo 'end clean index' . PHP_EOL; + echo 'end clean group index' . PHP_EOL; } /** @@ -82,7 +82,7 @@ class GroupIndexTask extends Task $index = $handler->getXS()->getIndex(); - echo 'start rebuild index' . PHP_EOL; + echo 'start rebuild group index' . PHP_EOL; $index->beginRebuild(); @@ -93,7 +93,7 @@ class GroupIndexTask extends Task $index->endRebuild(); - echo 'end rebuild index' . PHP_EOL; + echo 'end rebuild group index' . PHP_EOL; } /** diff --git a/app/Console/Tasks/UserIndexTask.php b/app/Console/Tasks/UserIndexTask.php index 6ce9c7d6..ccf999f4 100644 --- a/app/Console/Tasks/UserIndexTask.php +++ b/app/Console/Tasks/UserIndexTask.php @@ -60,11 +60,11 @@ class UserIndexTask extends Task $index = $handler->getXS()->getIndex(); - echo 'start clean index' . PHP_EOL; + echo 'start clean user index' . PHP_EOL; $index->clean(); - echo 'end clean index' . PHP_EOL; + echo 'end clean user index' . PHP_EOL; } /** @@ -82,7 +82,7 @@ class UserIndexTask extends Task $index = $handler->getXS()->getIndex(); - echo 'start rebuild index' . PHP_EOL; + echo 'start rebuild user index' . PHP_EOL; $index->beginRebuild(); @@ -93,7 +93,7 @@ class UserIndexTask extends Task $index->endRebuild(); - echo 'end rebuild index' . PHP_EOL; + echo 'end rebuild user index' . PHP_EOL; } /** diff --git a/app/Http/Admin/Controllers/IndexController.php b/app/Http/Admin/Controllers/IndexController.php index 4684800a..7b7b9da2 100644 --- a/app/Http/Admin/Controllers/IndexController.php +++ b/app/Http/Admin/Controllers/IndexController.php @@ -39,11 +39,13 @@ class IndexController extends Controller $todayStat = $indexService->getTodayStat(); $appInfo = $indexService->getAppInfo(); $serverInfo = $indexService->getServerInfo(); + $releases = $indexService->getReleases(); $this->view->setVar('global_stat', $globalStat); $this->view->setVar('today_stat', $todayStat); $this->view->setVar('app_info', $appInfo); $this->view->setVar('server_info', $serverInfo); + $this->view->setVar('releases', $releases); } /** diff --git a/app/Http/Admin/Services/Index.php b/app/Http/Admin/Services/Index.php index cf89b904..9febad0f 100644 --- a/app/Http/Admin/Services/Index.php +++ b/app/Http/Admin/Services/Index.php @@ -6,6 +6,7 @@ use App\Caches\SiteGlobalStat; use App\Caches\SiteTodayStat; use App\Library\AppInfo; use App\Library\Utils\ServerInfo; +use GuzzleHttp\Client; class Index extends Service { @@ -52,4 +53,17 @@ class Index extends Service return $cache->get(); } + public function getReleases() + { + $url = 'https://koogua.com/api-releases.json'; + + $client = new Client(); + + $response = $client->get($url, ['timeout' => 3]); + + $content = json_decode($response->getBody(), true); + + return $content['releases'] ?? []; + } + } diff --git a/app/Http/Admin/Views/index/index.volt b/app/Http/Admin/Views/index/index.volt index a676fc79..fd48a48a 100644 --- a/app/Http/Admin/Views/index/index.volt +++ b/app/Http/Admin/Views/index/index.volt @@ -63,7 +63,7 @@ diff --git a/app/Http/Admin/Views/index/main_app_info.volt b/app/Http/Admin/Views/index/main_app_info.volt index e5199d2e..4dbf67a5 100644 --- a/app/Http/Admin/Views/index/main_app_info.volt +++ b/app/Http/Admin/Views/index/main_app_info.volt @@ -13,7 +13,7 @@ 系统框架 - Phalcon 3.4.5 + Phalcon 3.4.5 获取渠道 diff --git a/app/Http/Admin/Views/index/main_app_trend.volt b/app/Http/Admin/Views/index/main_app_trend.volt index 44cef704..fd4d4684 100644 --- a/app/Http/Admin/Views/index/main_app_trend.volt +++ b/app/Http/Admin/Views/index/main_app_trend.volt @@ -1,6 +1,19 @@
产品动态
- + + + + + + + {% for release in releases %} + + + + + {% endfor %} + +
{{ release.title }}{{ release.date }}
\ No newline at end of file diff --git a/app/Http/Admin/Views/index/main_team_info.volt b/app/Http/Admin/Views/index/main_team_info.volt index c09a7637..85c36e01 100644 --- a/app/Http/Admin/Views/index/main_team_info.volt +++ b/app/Http/Admin/Views/index/main_team_info.volt @@ -9,7 +9,7 @@ 版权所有 - 深圳市酷瓜软件有限公司 + 深圳市酷瓜软件有限公司 产品经理 diff --git a/app/Http/Home/Controllers/PublicController.php b/app/Http/Home/Controllers/PublicController.php index e297095c..c37faf2f 100644 --- a/app/Http/Home/Controllers/PublicController.php +++ b/app/Http/Home/Controllers/PublicController.php @@ -10,7 +10,7 @@ use App\Services\Pay\Wxpay as WxpayService; use App\Services\Storage as StorageService; use App\Traits\Response as ResponseTrait; use App\Traits\Security as SecurityTrait; -use PHPQRCode\QRcode; +use Endroid\QrCode\QrCode; class PublicController extends \Phalcon\Mvc\Controller { @@ -49,14 +49,17 @@ class PublicController extends \Phalcon\Mvc\Controller public function qrcodeAction() { $text = $this->request->getQuery('text', 'string'); - $level = $this->request->getQuery('level', 'int', 0); - $size = $this->request->getQuery('size', 'int', 5); + $size = $this->request->getQuery('size', 'int', 320); - $url = urldecode($text); + $text = urldecode($text); - QRcode::png($url, false, $level, $size); + $qrCode = new QrCode($text); - $this->response->send(); + $qrCode->setSize($size); + + $qrCode->getContentType(); + + echo $qrCode->writeString(); exit; } diff --git a/app/Http/Home/Views/partials/footer.volt b/app/Http/Home/Views/partials/footer.volt index 745f6e85..9ac1d4a5 100644 --- a/app/Http/Home/Views/partials/footer.volt +++ b/app/Http/Home/Views/partials/footer.volt @@ -9,12 +9,12 @@ {% if site_info.copyright %} © {{ site_info.copyright }} {% endif %} - Powered by {{ app_info.alias }} {{ app_info.version }} + Powered by {{ app_info.alias }} {{ app_info.version }} {% if site_info.icp_sn %} - {{ site_info.icp_sn }} + {{ site_info.icp_sn }} {% endif %} {% if site_info.police_sn %} - {{ site_info.police_sn }} + {{ site_info.police_sn }} {% endif %} diff --git a/app/Library/AppInfo.php b/app/Library/AppInfo.php index f130a713..8283f49c 100644 --- a/app/Library/AppInfo.php +++ b/app/Library/AppInfo.php @@ -9,9 +9,9 @@ class AppInfo protected $alias = 'CTC'; - protected $link = 'https://gitee.com/koogua'; + protected $link = 'https://koogua.com'; - protected $version = '1.2.4'; + protected $version = '1.2.5'; public function __get($name) { diff --git a/app/Library/Helper.php b/app/Library/Helper.php index 709266c8..af1d528a 100644 --- a/app/Library/Helper.php +++ b/app/Library/Helper.php @@ -281,9 +281,12 @@ function kg_parse_markdown($content) return sprintf('/img/content/%s!content_800)', trim($matches[1])); }, $content); - $parser = new HyperDown\Parser(); + $parser = new League\CommonMark\GithubFlavoredMarkdownConverter([ + 'html_input' => 'strip', + 'allow_unsafe_links' => false, + ]); - return $parser->makeHtml($content); + return $parser->convertToHtml($content); } /** diff --git a/composer.json b/composer.json index 5b23da95..f5ff6f3e 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,7 @@ "phalcon/incubator": "^3.4", "guzzlehttp/guzzle": "^6.3", "swiftmailer/swiftmailer": "^6.0", - "peppeocchi/php-cron-scheduler": "^2.4", + "peppeocchi/php-cron-scheduler": "^3.0", "yansongda/pay": "^2.9", "tencentcloud/tencentcloud-sdk-php": "^3.0", "qcloudsms/qcloudsms_php": "^0.1", @@ -17,12 +17,11 @@ "workerman/gatewayclient": "^3.0", "whichbrowser/parser": "^2.0", "hightman/xunsearch": "^1.4", - "aferrandini/phpqrcode": "1.0.1", "xiaochong0302/ip2region": "^1.0", "robmorgan/phinx": "^0.12", - "lcobucci/jwt": "^3.3", "overtrue/wechat": "^4.2", - "joyqi/hyper-down": "dev-master" + "endroid/qr-code": "^3.9", + "league/commonmark": "^1.5" }, "require-dev": { "odan/phinx-migrations-generator": "^5.3", diff --git a/composer.lock b/composer.lock index ba5a5787..f728973d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,71 +4,79 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "907178db979a21189806683196c6516b", + "content-hash": "e715dca0b2629f1a9c59a984206adf9f", "packages": [ { - "name": "aferrandini/phpqrcode", - "version": "1.0.1", + "name": "bacon/bacon-qr-code", + "version": "2.0.3", "source": { "type": "git", - "url": "https://github.com/aferrandini/PHPQRCode.git", - "reference": "3c1c0454d43710ab5bbe19a51ad4cb41c22e3d46" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/aferrandini/PHPQRCode/zipball/3c1c0454d43710ab5bbe19a51ad4cb41c22e3d46", - "reference": "3c1c0454d43710ab5bbe19a51ad4cb41c22e3d46", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "PHPQRCode": "lib/" - } - }, - "notification-url": "https://packagist.jp/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ariel Ferrandini", - "email": "arielferrandini@gmail.com", - "homepage": "http://www.ferrandini.com/", - "role": "Developer" - } - ], - "description": "PHPQRCode porting and changed for PHP 5.3 compatibility", - "homepage": "https://github.com/aferrandini/PHPQRCode", - "keywords": [ - "barcode", - "php", - "qrcode" - ], - "abandoned": "endroid/qr-code", - "time": "2013-07-08T09:39:08+00:00" - }, - { - "name": "cakephp/core", - "version": "4.1.3", - "source": { - "type": "git", - "url": "https://github.com/cakephp/core.git", - "reference": "c7e88f1cd6dfe17065e71f1af305d415f155e97e" + "url": "https://github.com/Bacon/BaconQrCode.git", + "reference": "3e9d791b67d0a2912922b7b7c7312f4b37af41e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/core/zipball/c7e88f1cd6dfe17065e71f1af305d415f155e97e", - "reference": "c7e88f1cd6dfe17065e71f1af305d415f155e97e", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/3e9d791b67d0a2912922b7b7c7312f4b37af41e4", + "reference": "3e9d791b67d0a2912922b7b7c7312f4b37af41e4", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "dasprid/enum": "^1.0.3", + "ext-iconv": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phly/keep-a-changelog": "^1.4", + "phpunit/phpunit": "^7 | ^8 | ^9", + "squizlabs/php_codesniffer": "^3.4" + }, + "suggest": { + "ext-imagick": "to generate QR code images" + }, + "type": "library", + "autoload": { + "psr-4": { + "BaconQrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "BaconQrCode is a QR code generator for PHP.", + "homepage": "https://github.com/Bacon/BaconQrCode", + "support": { + "issues": "https://github.com/Bacon/BaconQrCode/issues", + "source": "https://github.com/Bacon/BaconQrCode/tree/2.0.3" + }, + "time": "2020-10-30T02:02:47+00:00" + }, + { + "name": "cakephp/core", + "version": "4.2.2", + "source": { + "type": "git", + "url": "https://github.com/cakephp/core.git", + "reference": "54d11c1356cea54623a3ec55530259d3c47153e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cakephp/core/zipball/54d11c1356cea54623a3ec55530259d3c47153e0", + "reference": "54d11c1356cea54623a3ec55530259d3c47153e0", "shasum": "", "mirrors": [ { @@ -83,7 +91,8 @@ }, "suggest": { "cakephp/cache": "To use Configure::store() and restore().", - "cakephp/event": "To use PluginApplicationInterface or plugin applications." + "cakephp/event": "To use PluginApplicationInterface or plugin applications.", + "league/container": "To use Container and ServiceProvider classes" }, "type": "library", "autoload": { @@ -111,20 +120,26 @@ "core", "framework" ], - "time": "2020-08-13T23:43:58+00:00" + "support": { + "forum": "https://stackoverflow.com/tags/cakephp", + "irc": "irc://irc.freenode.org/cakephp", + "issues": "https://github.com/cakephp/cakephp/issues", + "source": "https://github.com/cakephp/core" + }, + "time": "2020-12-29T02:05:46+00:00" }, { "name": "cakephp/database", - "version": "4.1.3", + "version": "4.2.2", "source": { "type": "git", "url": "https://github.com/cakephp/database.git", - "reference": "b5342110aca5dea9c902c2e12d2077ea2c11eecb" + "reference": "f5cbd97516ef2a0bddeb1c38e72034cddf875482" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/database/zipball/b5342110aca5dea9c902c2e12d2077ea2c11eecb", - "reference": "b5342110aca5dea9c902c2e12d2077ea2c11eecb", + "url": "https://api.github.com/repos/cakephp/database/zipball/f5cbd97516ef2a0bddeb1c38e72034cddf875482", + "reference": "f5cbd97516ef2a0bddeb1c38e72034cddf875482", "shasum": "", "mirrors": [ { @@ -166,20 +181,26 @@ "database abstraction", "pdo" ], - "time": "2020-08-14T17:56:57+00:00" + "support": { + "forum": "https://stackoverflow.com/tags/cakephp", + "irc": "irc://irc.freenode.org/cakephp", + "issues": "https://github.com/cakephp/cakephp/issues", + "source": "https://github.com/cakephp/database" + }, + "time": "2021-01-01T07:34:22+00:00" }, { "name": "cakephp/datasource", - "version": "4.1.3", + "version": "4.2.2", "source": { "type": "git", "url": "https://github.com/cakephp/datasource.git", - "reference": "4514e256c3da3c88c0cb4754218a217f9f20ec1d" + "reference": "e2c8c895254837722a5a00609644b72ef01290a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/datasource/zipball/4514e256c3da3c88c0cb4754218a217f9f20ec1d", - "reference": "4514e256c3da3c88c0cb4754218a217f9f20ec1d", + "url": "https://api.github.com/repos/cakephp/datasource/zipball/e2c8c895254837722a5a00609644b72ef01290a0", + "reference": "e2c8c895254837722a5a00609644b72ef01290a0", "shasum": "", "mirrors": [ { @@ -224,20 +245,26 @@ "entity", "query" ], - "time": "2020-07-21T05:44:43+00:00" + "support": { + "forum": "https://stackoverflow.com/tags/cakephp", + "irc": "irc://irc.freenode.org/cakephp", + "issues": "https://github.com/cakephp/cakephp/issues", + "source": "https://github.com/cakephp/datasource" + }, + "time": "2021-01-01T07:34:22+00:00" }, { "name": "cakephp/utility", - "version": "4.1.3", + "version": "4.2.2", "source": { "type": "git", "url": "https://github.com/cakephp/utility.git", - "reference": "c65a5a169077c561b6e850e6d0ee85d9a54b6f5a" + "reference": "37d737eef64f3f09af871b70730a99912248d157" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/utility/zipball/c65a5a169077c561b6e850e6d0ee85d9a54b6f5a", - "reference": "c65a5a169077c561b6e850e6d0ee85d9a54b6f5a", + "url": "https://api.github.com/repos/cakephp/utility/zipball/37d737eef64f3f09af871b70730a99912248d157", + "reference": "37d737eef64f3f09af871b70730a99912248d157", "shasum": "", "mirrors": [ { @@ -283,20 +310,79 @@ "string", "utility" ], - "time": "2020-08-12T08:25:29+00:00" + "support": { + "forum": "https://stackoverflow.com/tags/cakephp", + "irc": "irc://irc.freenode.org/cakephp", + "issues": "https://github.com/cakephp/cakephp/issues", + "source": "https://github.com/cakephp/utility" + }, + "time": "2020-12-29T02:05:46+00:00" }, { - "name": "doctrine/lexer", - "version": "1.1.0", + "name": "dasprid/enum", + "version": "1.0.3", "source": { "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "e17f069ede36f7534b95adec71910ed1b49c74ea" + "url": "https://github.com/DASPRiD/Enum.git", + "reference": "5abf82f213618696dda8e3bf6f64dd042d8542b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/e17f069ede36f7534b95adec71910ed1b49c74ea", - "reference": "e17f069ede36f7534b95adec71910ed1b49c74ea", + "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/5abf82f213618696dda8e3bf6f64dd042d8542b2", + "reference": "5abf82f213618696dda8e3bf6f64dd042d8542b2", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require-dev": { + "phpunit/phpunit": "^7 | ^8 | ^9", + "squizlabs/php_codesniffer": "^3.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "DASPRiD\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "PHP 7.1 enum implementation", + "keywords": [ + "enum", + "map" + ], + "support": { + "issues": "https://github.com/DASPRiD/Enum/issues", + "source": "https://github.com/DASPRiD/Enum/tree/1.0.3" + }, + "time": "2020-10-02T16:03:48+00:00" + }, + { + "name": "doctrine/lexer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", "shasum": "", "mirrors": [ { @@ -306,7 +392,7 @@ ] }, "require": { - "php": "^7.2" + "php": "^7.2 || ^8.0" }, "require-dev": { "doctrine/coding-standard": "^6.0", @@ -316,7 +402,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -329,115 +415,200 @@ "MIT" ], "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } ], - "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "https://www.doctrine-project.org/projects/lexer.html", - "keywords": [ - "annotations", - "docblock", - "lexer", - "parser", - "php" - ], - "time": "2019-07-30T19:33:28+00:00" + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2020-05-25T17:44:05+00:00" }, - { - "name": "easywechat-composer/easywechat-composer", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/mingyoung/easywechat-composer.git", - "reference": "93cfce1ec842b9a5b1b0791a52afd18b833f114a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mingyoung/easywechat-composer/zipball/93cfce1ec842b9a5b1b0791a52afd18b833f114a", - "reference": "93cfce1ec842b9a5b1b0791a52afd18b833f114a", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=7.0" - }, - "require-dev": { - "composer/composer": "^1.0 || ^2.0", - "phpunit/phpunit": "^6.5 || ^7.0" - }, - "type": "composer-plugin", - "extra": { - "class": "EasyWeChatComposer\\Plugin" - }, - "autoload": { - "psr-4": { - "EasyWeChatComposer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ { - "name": "张铭阳", - "email": "mingyoungcheung@gmail.com" - } - ], - "description": "The composer plugin for EasyWeChat", - "support": { - "issues": "https://github.com/mingyoung/easywechat-composer/issues", - "source": "https://github.com/mingyoung/easywechat-composer/tree/1.4.0" - }, - "time": "2020-07-23T11:06:47+00:00" - }, - { - "name": "egulias/email-validator", - "version": "2.1.11", - "source": { - "type": "git", - "url": "https://github.com/egulias/EmailValidator.git", - "reference": "92dd169c32f6f55ba570c309d83f5209cefb5e23" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/92dd169c32f6f55ba570c309d83f5209cefb5e23", - "reference": "92dd169c32f6f55ba570c309d83f5209cefb5e23", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "doctrine/lexer": "^1.0.1", - "php": ">= 5.5" - }, - "require-dev": { - "dominicsayers/isemail": "dev-master", - "phpunit/phpunit": "^4.8.35||^5.7||^6.0", - "satooshi/php-coveralls": "^1.0.1", - "symfony/phpunit-bridge": "^4.4@dev" - }, - "suggest": { + "name": "dragonmantank/cron-expression", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "7a8c6e56ab3ffcc538d05e8155bb42269abf1a0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/7a8c6e56ab3ffcc538d05e8155bb42269abf1a0c", + "reference": "7a8c6e56ab3ffcc538d05e8155bb42269abf1a0c", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.7.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-webmozart-assert": "^0.12.7", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.1.0" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2020-11-24T19:55:57+00:00" + }, + { + "name": "easywechat-composer/easywechat-composer", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/mingyoung/easywechat-composer.git", + "reference": "93cfce1ec842b9a5b1b0791a52afd18b833f114a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mingyoung/easywechat-composer/zipball/93cfce1ec842b9a5b1b0791a52afd18b833f114a", + "reference": "93cfce1ec842b9a5b1b0791a52afd18b833f114a", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=7.0" + }, + "require-dev": { + "composer/composer": "^1.0 || ^2.0", + "phpunit/phpunit": "^6.5 || ^7.0" + }, + "type": "composer-plugin", + "extra": { + "class": "EasyWeChatComposer\\Plugin" + }, + "autoload": { + "psr-4": { + "EasyWeChatComposer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "张铭阳", + "email": "mingyoungcheung@gmail.com" + } + ], + "description": "The composer plugin for EasyWeChat", + "support": { + "issues": "https://github.com/mingyoung/easywechat-composer/issues", + "source": "https://github.com/mingyoung/easywechat-composer/tree/1.4.0" + }, + "time": "2020-07-23T11:06:47+00:00" + }, + { + "name": "egulias/email-validator", + "version": "2.1.25", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "0dbf5d78455d4d6a41d186da50adc1122ec066f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/0dbf5d78455d4d6a41d186da50adc1122ec066f4", + "reference": "0dbf5d78455d4d6a41d186da50adc1122ec066f4", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "doctrine/lexer": "^1.0.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.10" + }, + "require-dev": { + "dominicsayers/isemail": "^3.0.7", + "phpunit/phpunit": "^4.8.36|^7.5.15", + "satooshi/php-coveralls": "^1.0.1" + }, + "suggest": { "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" }, "type": "library", @@ -448,7 +619,7 @@ }, "autoload": { "psr-4": { - "Egulias\\EmailValidator\\": "EmailValidator" + "Egulias\\EmailValidator\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -469,7 +640,98 @@ "validation", "validator" ], - "time": "2019-08-13T17:33:27+00:00" + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/2.1.25" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2020-12-29T14:50:06+00:00" + }, + { + "name": "endroid/qr-code", + "version": "3.9.6", + "source": { + "type": "git", + "url": "https://github.com/endroid/qr-code.git", + "reference": "9cdd4f5d609bfc8811ca4a62b4d23eb16976242f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/endroid/qr-code/zipball/9cdd4f5d609bfc8811ca4a62b4d23eb16976242f", + "reference": "9cdd4f5d609bfc8811ca4a62b4d23eb16976242f", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "bacon/bacon-qr-code": "^2.0", + "khanamiryan/qrcode-detector-decoder": "^1.0.2", + "myclabs/php-enum": "^1.5", + "php": ">=7.2", + "symfony/options-resolver": "^3.4||^4.4||^5.0", + "symfony/property-access": "^3.4||^4.4||^5.0" + }, + "require-dev": { + "endroid/quality": "^1.3.7", + "setasign/fpdf": "^1.8" + }, + "suggest": { + "ext-gd": "Required for generating PNG images", + "roave/security-advisories": "Avoids installation of package versions with vulnerabilities", + "setasign/fpdf": "Required to use the FPDF writer.", + "symfony/security-checker": "Checks your composer.lock for vulnerabilities" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Endroid\\QrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeroen van den Enden", + "email": "info@endroid.nl" + } + ], + "description": "Endroid QR Code", + "homepage": "https://github.com/endroid/qr-code", + "keywords": [ + "bundle", + "code", + "endroid", + "php", + "qr", + "qrcode" + ], + "support": { + "issues": "https://github.com/endroid/qr-code/issues", + "source": "https://github.com/endroid/qr-code/tree/3.9.6" + }, + "funding": [ + { + "url": "https://github.com/endroid", + "type": "github" + } + ], + "time": "2020-11-27T14:30:38+00:00" }, { "name": "guzzlehttp/command", @@ -528,20 +790,24 @@ } ], "description": "Provides the foundation for building command-based web service clients", + "support": { + "issues": "https://github.com/guzzle/command/issues", + "source": "https://github.com/guzzle/command/tree/1.0.0" + }, "time": "2016-11-24T13:34:15+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "6.3.3", + "version": "6.5.5", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba" + "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba", - "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", + "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", "shasum": "", "mirrors": [ { @@ -551,14 +817,16 @@ ] }, "require": { + "ext-json": "*", "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.4", - "php": ">=5.5" + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.17.0" }, "require-dev": { "ext-curl": "*", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", - "psr/log": "^1.0" + "psr/log": "^1.1" }, "suggest": { "psr/log": "Required for using the Log middleware" @@ -566,16 +834,16 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "6.3-dev" + "dev-master": "6.5-dev" } }, "autoload": { - "files": [ - "src/functions_include.php" - ], "psr-4": { "GuzzleHttp\\": "src/" - } + }, + "files": [ + "src/functions_include.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -599,7 +867,11 @@ "rest", "web service" ], - "time": "2018-04-22T15:46:56+00:00" + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/6.5" + }, + "time": "2020-06-16T21:01:06+00:00" }, { "name": "guzzlehttp/guzzle-services", @@ -665,20 +937,24 @@ } ], "description": "Provides an implementation of the Guzzle Command library that uses Guzzle service descriptions to describe web services, serialize requests, and parse responses into easy to use model structures.", + "support": { + "issues": "https://github.com/guzzle/guzzle-services/issues", + "source": "https://github.com/guzzle/guzzle-services/tree/1.1.3" + }, "time": "2017-10-06T14:32:02+00:00" }, { "name": "guzzlehttp/promises", - "version": "v1.3.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + "reference": "60d379c243457e073cff02bc323a2a86cb355631" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "url": "https://api.github.com/repos/guzzle/promises/zipball/60d379c243457e073cff02bc323a2a86cb355631", + "reference": "60d379c243457e073cff02bc323a2a86cb355631", "shasum": "", "mirrors": [ { @@ -688,10 +964,10 @@ ] }, "require": { - "php": ">=5.5.0" + "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "^4.0" + "symfony/phpunit-bridge": "^4.4 || ^5.1" }, "type": "library", "extra": { @@ -722,20 +998,24 @@ "keywords": [ "promise" ], - "time": "2016-12-20T10:07:11+00:00" + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.4.0" + }, + "time": "2020-09-30T07:37:28+00:00" }, { "name": "guzzlehttp/psr7", - "version": "1.6.1", + "version": "1.7.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", - "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/53330f47520498c0ae1f61f7e2c90f55690c06a3", + "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3", "shasum": "", "mirrors": [ { @@ -754,15 +1034,15 @@ }, "require-dev": { "ext-zlib": "*", - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" }, "suggest": { - "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6-dev" + "dev-master": "1.7-dev" } }, "autoload": { @@ -799,7 +1079,11 @@ "uri", "url" ], - "time": "2019-07-01T23:21:34+00:00" + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.7.0" + }, + "time": "2020-09-30T07:37:11+00:00" }, { "name": "hightman/xunsearch", @@ -856,27 +1140,93 @@ } ], "description": "xunsearch php sdk, include yii, yii2 supports", - "homepage": "http://www.xunsearch.com/", - "keywords": [ - "search engine", - "xunsearch", - "yii", - "yii2" - ], - "time": "2020-09-03T16:46:04+00:00" + "homepage": "http://www.xunsearch.com/", + "keywords": [ + "search engine", + "xunsearch", + "yii", + "yii2" + ], + "support": { + "forum": "http://bbs.xunsearch.com/", + "guide": "http://www.xunsearch.com/doc/php", + "issues": "https://github.com/hightman/xunsearch/issues?q=is%3Aopen", + "source": "https://github.com/hightman/xunsearch/" + }, + "time": "2020-09-03T16:46:04+00:00" + }, + { + "name": "khanamiryan/qrcode-detector-decoder", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/khanamiryan/php-qrcode-detector-decoder.git", + "reference": "07fceefb79d895e858e52921afb9c1433d2f3d5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/khanamiryan/php-qrcode-detector-decoder/zipball/07fceefb79d895e858e52921afb9c1433d2f3d5e", + "reference": "07fceefb79d895e858e52921afb9c1433d2f3d5e", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Zxing\\": "lib/" + }, + "files": [ + "lib/Common/customFunctions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ashot Khanamiryan", + "email": "a.khanamiryan@gmail.com", + "homepage": "https://github.com/khanamiryan", + "role": "Developer" + } + ], + "description": "QR code decoder / reader", + "homepage": "https://github.com/khanamiryan/php-qrcode-detector-decoder/", + "keywords": [ + "barcode", + "qr", + "zxing" + ], + "support": { + "issues": "https://github.com/khanamiryan/php-qrcode-detector-decoder/issues", + "source": "https://github.com/khanamiryan/php-qrcode-detector-decoder/tree/1.0.4" + }, + "time": "2020-11-29T18:50:26+00:00" }, { - "name": "joyqi/hyper-down", - "version": "dev-master", + "name": "league/commonmark", + "version": "1.5.7", "source": { "type": "git", - "url": "https://github.com/SegmentFault/HyperDown.git", - "reference": "1774a7bb8a3853503e44cfa5a2186b1943f6493f" + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "11df9b36fd4f1d2b727a73bf14931d81373b9a54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/SegmentFault/HyperDown/zipball/1774a7bb8a3853503e44cfa5a2186b1943f6493f", - "reference": "1774a7bb8a3853503e44cfa5a2186b1943f6493f", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/11df9b36fd4f1d2b727a73bf14931d81373b9a54", + "reference": "11df9b36fd4f1d2b727a73bf14931d81373b9a54", "shasum": "", "mirrors": [ { @@ -887,115 +1237,103 @@ }, "require": { "ext-mbstring": "*", - "php": ">=5.4.0" + "php": "^7.1 || ^8.0" }, - "default-branch": true, + "conflict": { + "scrutinizer/ocular": "1.7.*" + }, + "require-dev": { + "cebe/markdown": "~1.0", + "commonmark/commonmark.js": "0.29.2", + "erusev/parsedown": "~1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "~1.4", + "mikehaertl/php-shellcommand": "^1.4", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.2", + "scrutinizer/ocular": "^1.5", + "symfony/finder": "^4.2" + }, + "bin": [ + "bin/commonmark" + ], "type": "library", "autoload": { "psr-4": { - "HyperDown\\": "./" + "League\\CommonMark\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD" + "BSD-3-Clause" ], "authors": [ { - "name": "joyqi", - "email": "joyqi@segmentfault.com" + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" } ], - "description": "A light weight markdown parser library", + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and Github-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", + "keywords": [ + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" + ], "support": { - "issues": "https://github.com/SegmentFault/HyperDown/issues", - "source": "https://github.com/SegmentFault/HyperDown/tree/master" + "docs": "https://commonmark.thephpleague.com/", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" }, - "time": "2020-11-30T04:05:08+00:00" + "funding": [ + { + "url": "https://enjoy.gitstore.app/repositories/thephpleague/commonmark", + "type": "custom" + }, + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://www.patreon.com/colinodell", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2020-10-31T13:49:32+00:00" }, { - "name": "lcobucci/jwt", - "version": "3.3.3", + "name": "monolog/monolog", + "version": "2.2.0", "source": { "type": "git", - "url": "https://github.com/lcobucci/jwt.git", - "reference": "c1123697f6a2ec29162b82f170dd4a491f524773" + "url": "https://github.com/Seldaek/monolog.git", + "reference": "1cb1cde8e8dd0f70cc0fe51354a59acad9302084" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lcobucci/jwt/zipball/c1123697f6a2ec29162b82f170dd4a491f524773", - "reference": "c1123697f6a2ec29162b82f170dd4a491f524773", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-mbstring": "*", - "ext-openssl": "*", - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "mikey179/vfsstream": "~1.5", - "phpmd/phpmd": "~2.2", - "phpunit/php-invoker": "~1.1", - "phpunit/phpunit": "^5.7 || ^7.3", - "squizlabs/php_codesniffer": "~2.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "psr-4": { - "Lcobucci\\JWT\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Luís Otávio Cobucci Oblonczyk", - "email": "lcobucci@gmail.com", - "role": "Developer" - } - ], - "description": "A simple library to work with JSON Web Token and JSON Web Signature", - "keywords": [ - "JWS", - "jwt" - ], - "funding": [ - { - "url": "https://github.com/lcobucci", - "type": "github" - }, - { - "url": "https://www.patreon.com/lcobucci", - "type": "patreon" - } - ], - "time": "2020-08-20T13:22:28+00:00" - }, - { - "name": "monolog/monolog", - "version": "2.1.1", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "f9eee5cec93dfb313a38b6b288741e84e53f02d5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f9eee5cec93dfb313a38b6b288741e84e53f02d5", - "reference": "f9eee5cec93dfb313a38b6b288741e84e53f02d5", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/1cb1cde8e8dd0f70cc0fe51354a59acad9302084", + "reference": "1cb1cde8e8dd0f70cc0fe51354a59acad9302084", "shasum": "", "mirrors": [ { @@ -1014,16 +1352,17 @@ "require-dev": { "aws/aws-sdk-php": "^2.4.9 || ^3.0", "doctrine/couchdb": "~1.0@dev", - "elasticsearch/elasticsearch": "^6.0", + "elasticsearch/elasticsearch": "^7", "graylog2/gelf-php": "^1.4.2", + "mongodb/mongodb": "^1.8", "php-amqplib/php-amqplib": "~2.4", "php-console/php-console": "^3.1.3", - "php-parallel-lint/php-parallel-lint": "^1.0", "phpspec/prophecy": "^1.6.1", + "phpstan/phpstan": "^0.12.59", "phpunit/phpunit": "^8.5", "predis/predis": "^1.1", "rollbar/rollbar": "^1.3", - "ruflin/elastica": ">=0.90 <3.0", + "ruflin/elastica": ">=0.90 <7.0.1", "swiftmailer/swiftmailer": "^5.3|^6.0" }, "suggest": { @@ -1043,7 +1382,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-main": "2.x-dev" } }, "autoload": { @@ -1059,16 +1398,20 @@ { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" + "homepage": "https://seld.be" } ], "description": "Sends your logs to files, sockets, inboxes, databases and various web services", - "homepage": "http://github.com/Seldaek/monolog", + "homepage": "https://github.com/Seldaek/monolog", "keywords": [ "log", "logging", "psr-3" ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/2.2.0" + }, "funding": [ { "url": "https://github.com/Seldaek", @@ -1079,20 +1422,20 @@ "type": "tidelift" } ], - "time": "2020-07-23T08:41:23+00:00" + "time": "2020-12-14T13:15:25+00:00" }, { - "name": "mtdowling/cron-expression", - "version": "v1.2.1", + "name": "myclabs/php-enum", + "version": "1.7.7", "source": { "type": "git", - "url": "https://github.com/mtdowling/cron-expression.git", - "reference": "9504fa9ea681b586028adaaa0877db4aecf32bad" + "url": "https://github.com/myclabs/php-enum.git", + "reference": "d178027d1e679832db9f38248fcc7200647dc2b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/9504fa9ea681b586028adaaa0877db4aecf32bad", - "reference": "9504fa9ea681b586028adaaa0877db4aecf32bad", + "url": "https://api.github.com/repos/myclabs/php-enum/zipball/d178027d1e679832db9f38248fcc7200647dc2b7", + "reference": "d178027d1e679832db9f38248fcc7200647dc2b7", "shasum": "", "mirrors": [ { @@ -1102,246 +1445,63 @@ ] }, "require": { - "php": ">=5.3.2" + "ext-json": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7", + "squizlabs/php_codesniffer": "1.*", + "vimeo/psalm": "^3.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "MyCLabs\\Enum\\": "src/" + } }, - "require-dev": { - "phpunit/phpunit": "~4.0|~5.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Cron\\": "src/Cron/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", - "keywords": [ - "cron", - "schedule" - ], - "abandoned": "dragonmantank/cron-expression", - "time": "2017-01-23T04:29:33+00:00" - }, - { - "name": "overtrue/socialite", - "version": "2.0.22", - "source": { - "type": "git", - "url": "https://github.com/overtrue/socialite.git", - "reference": "0ce3285293026a639de317a70b01eeef051e9962" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/overtrue/socialite/zipball/0ce3285293026a639de317a70b01eeef051e9962", - "reference": "0ce3285293026a639de317a70b01eeef051e9962", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-json": "*", - "guzzlehttp/guzzle": "^5.0|^6.0|^7.0", - "php": ">=5.6", - "symfony/http-foundation": "^2.7|^3.0|^4.0|^5.0" - }, - "conflict": { - "socialiteproviders/weixin": "*" - }, - "require-dev": { - "mockery/mockery": "~1.2", - "phpunit/phpunit": "~6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Overtrue\\Socialite\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "overtrue", - "email": "anzhengchao@gmail.com" - } - ], - "description": "A collection of OAuth 2 packages that extracts from laravel/socialite.", - "keywords": [ - "login", - "oauth", - "qq", - "social", - "wechat", - "weibo" - ], - "support": { - "issues": "https://github.com/overtrue/socialite/issues", - "source": "https://github.com/overtrue/socialite/tree/2.0.22" - }, - "funding": [ - { - "url": "https://www.patreon.com/overtrue", - "type": "patreon" - } - ], - "time": "2020-11-12T23:23:15+00:00" - }, - { - "name": "overtrue/wechat", - "version": "4.3.3", - "source": { - "type": "git", - "url": "https://github.com/w7corp/easywechat.git", - "reference": "121607188e1cb1039a5ea0f49bcec011cb44dbdd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/w7corp/easywechat/zipball/121607188e1cb1039a5ea0f49bcec011cb44dbdd", - "reference": "121607188e1cb1039a5ea0f49bcec011cb44dbdd", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "easywechat-composer/easywechat-composer": "^1.1", - "ext-fileinfo": "*", - "ext-openssl": "*", - "ext-simplexml": "*", - "guzzlehttp/guzzle": "^6.2 || ^7.0", - "monolog/monolog": "^1.22 || ^2.0", - "overtrue/socialite": "~2.0", - "php": ">=7.2", - "pimple/pimple": "^3.0", - "psr/simple-cache": "^1.0", - "symfony/cache": "^3.3 || ^4.3 || ^5.0", - "symfony/event-dispatcher": "^4.3 || ^5.0", - "symfony/http-foundation": "^2.7 || ^3.0 || ^4.0 || ^5.0", - "symfony/psr-http-message-bridge": "^0.3 || ^1.0 || ^2.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.15", - "mikey179/vfsstream": "^1.6", - "mockery/mockery": "^1.2.3", - "phpstan/phpstan": "^0.12.0", - "phpunit/phpunit": "^7.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "EasyWeChat\\": "src/" - }, - "files": [ - "src/Kernel/Support/Helpers.php", - "src/Kernel/Helpers.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "overtrue", - "email": "anzhengchao@gmail.com" - } - ], - "description": "微信SDK", - "keywords": [ - "easywechat", - "sdk", - "wechat", - "weixin", - "weixin-sdk" - ], - "support": { - "issues": "https://github.com/w7corp/easywechat/issues", - "source": "https://github.com/w7corp/easywechat/tree/4.3.3" - }, - "time": "2020-12-07T08:20:11+00:00" - }, - { - "name": "paragonie/random_compat", - "version": "v9.99.99", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", - "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*", - "vimeo/psalm": "^1" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "type": "library", "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" + "name": "PHP Enum contributors", + "homepage": "https://github.com/myclabs/php-enum/graphs/contributors" } ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "description": "PHP Enum implementation", + "homepage": "http://github.com/myclabs/php-enum", "keywords": [ - "csprng", - "polyfill", - "pseudorandom", - "random" + "enum" ], - "time": "2018-07-02T15:55:56+00:00" + "support": { + "issues": "https://github.com/myclabs/php-enum/issues", + "source": "https://github.com/myclabs/php-enum/tree/1.7.7" + }, + "funding": [ + { + "url": "https://github.com/mnapoli", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum", + "type": "tidelift" + } + ], + "time": "2020-11-14T18:14:52+00:00" }, { - "name": "peppeocchi/php-cron-scheduler", - "version": "v2.4", + "name": "overtrue/socialite", + "version": "2.0.23", "source": { "type": "git", - "url": "https://github.com/peppeocchi/php-cron-scheduler.git", - "reference": "1b18892fdd4f9c913107fda1544ac402eb7ec6e5" + "url": "https://github.com/overtrue/socialite.git", + "reference": "0bc60597b589592243f074a4d9016aabd2e9cfb2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/peppeocchi/php-cron-scheduler/zipball/1b18892fdd4f9c913107fda1544ac402eb7ec6e5", - "reference": "1b18892fdd4f9c913107fda1544ac402eb7ec6e5", + "url": "https://api.github.com/repos/overtrue/socialite/zipball/0bc60597b589592243f074a4d9016aabd2e9cfb2", + "reference": "0bc60597b589592243f074a4d9016aabd2e9cfb2", "shasum": "", "mirrors": [ { @@ -1351,8 +1511,166 @@ ] }, "require": { - "mtdowling/cron-expression": "~1.0", - "php": ">=5.5.9" + "ext-json": "*", + "guzzlehttp/guzzle": "^5.0|^6.0|^7.0", + "php": ">=5.6", + "symfony/http-foundation": "^2.7|^3.0|^4.0|^5.0" + }, + "require-dev": { + "mockery/mockery": "~1.2", + "phpunit/phpunit": "~6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Overtrue\\Socialite\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "overtrue", + "email": "anzhengchao@gmail.com" + } + ], + "description": "A collection of OAuth 2 packages that extracts from laravel/socialite.", + "keywords": [ + "login", + "oauth", + "qq", + "social", + "wechat", + "weibo" + ], + "support": { + "issues": "https://github.com/overtrue/socialite/issues", + "source": "https://github.com/overtrue/socialite/tree/2.0.23" + }, + "funding": [ + { + "url": "https://www.patreon.com/overtrue", + "type": "patreon" + } + ], + "time": "2020-12-14T03:30:08+00:00" + }, + { + "name": "overtrue/wechat", + "version": "4.4.0", + "source": { + "type": "git", + "url": "https://github.com/w7corp/easywechat.git", + "reference": "20bdd3fe8056ee9297692caf53bd131be8079ee6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/w7corp/easywechat/zipball/20bdd3fe8056ee9297692caf53bd131be8079ee6", + "reference": "20bdd3fe8056ee9297692caf53bd131be8079ee6", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "easywechat-composer/easywechat-composer": "^1.1", + "ext-fileinfo": "*", + "ext-openssl": "*", + "ext-simplexml": "*", + "guzzlehttp/guzzle": "^6.2 || ^7.0", + "monolog/monolog": "^1.22 || ^2.0", + "overtrue/socialite": "~2.0", + "php": ">=7.2", + "pimple/pimple": "^3.0", + "psr/simple-cache": "^1.0", + "symfony/cache": "^3.3 || ^4.3 || ^5.0", + "symfony/event-dispatcher": "^4.3 || ^5.0", + "symfony/http-foundation": "^2.7 || ^3.0 || ^4.0 || ^5.0", + "symfony/psr-http-message-bridge": "^0.3 || ^1.0 || ^2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.15", + "mikey179/vfsstream": "^1.6", + "mockery/mockery": "^1.2.3", + "phpstan/phpstan": "^0.12.0", + "phpunit/phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "EasyWeChat\\": "src/" + }, + "files": [ + "src/Kernel/Support/Helpers.php", + "src/Kernel/Helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "overtrue", + "email": "anzhengchao@gmail.com" + } + ], + "description": "微信SDK", + "keywords": [ + "easywechat", + "sdk", + "wechat", + "weixin", + "weixin-sdk" + ], + "support": { + "issues": "https://github.com/w7corp/easywechat/issues", + "source": "https://github.com/w7corp/easywechat/tree/4.4.0" + }, + "funding": [ + { + "url": "https://www.easywechat.com/img/pay/wechat.jpg", + "type": "custom" + }, + { + "url": "https://github.com/overtrue", + "type": "github" + }, + { + "url": "https://www.patreon.com/overtrue", + "type": "patreon" + } + ], + "time": "2020-12-30T06:39:40+00:00" + }, + { + "name": "peppeocchi/php-cron-scheduler", + "version": "v3.1", + "source": { + "type": "git", + "url": "https://github.com/peppeocchi/php-cron-scheduler.git", + "reference": "18fcf4c98d4cf0cd4f3eb64728a8b0d082bbc2f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/peppeocchi/php-cron-scheduler/zipball/18fcf4c98d4cf0cd4f3eb64728a8b0d082bbc2f9", + "reference": "18fcf4c98d4cf0cd4f3eb64728a8b0d082bbc2f9", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "dragonmantank/cron-expression": "^3.0", + "php": "^7.1" }, "require-dev": { "phpunit/phpunit": "~5.7", @@ -1389,7 +1707,11 @@ "cron job", "scheduler" ], - "time": "2018-10-25T21:33:38+00:00" + "support": { + "issues": "https://github.com/peppeocchi/php-cron-scheduler/issues", + "source": "https://github.com/peppeocchi/php-cron-scheduler/tree/v3.1" + }, + "time": "2020-10-19T09:21:17+00:00" }, { "name": "phalcon/incubator", @@ -1447,115 +1769,124 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Phalcon Team", - "email": "team@phalconphp.com", - "homepage": "https://phalconphp.com/en/team" - }, - { - "name": "Contributors", - "homepage": "https://github.com/phalcon/incubator/graphs/contributors" - } + { + "name": "Phalcon Team", + "email": "team@phalconphp.com", + "homepage": "https://phalconphp.com/en/team" + }, + { + "name": "Contributors", + "homepage": "https://github.com/phalcon/incubator/graphs/contributors" + } ], - "description": "Adapters, prototypes or functionality that can be potentially incorporated to the C-framework.", - "homepage": "https://phalconphp.com", - "keywords": [ - "framework", - "incubator", - "phalcon" - ], - "time": "2019-09-16T13:54:24+00:00" + "description": "Adapters, prototypes or functionality that can be potentially incorporated to the C-framework.", + "homepage": "https://phalconphp.com", + "keywords": [ + "framework", + "incubator", + "phalcon" + ], + "support": { + "docs": "https://docs.phalconphp.com/", + "email": "support@phalconphp.com", + "forum": "https://forum.phalconphp.com/", + "irc": "irc://irc.freenode.org/phalconphp", + "issues": "https://github.com/phalcon/incubator/issues", + "rss": "https://blog.phalconphp.com/rss", + "source": "https://github.com/phalcon/incubator" + }, + "time": "2019-09-16T13:54:24+00:00" }, - { - "name": "pimple/pimple", - "version": "v3.3.1", - "source": { - "type": "git", - "url": "https://github.com/silexphp/Pimple.git", - "reference": "21e45061c3429b1e06233475cc0e1f6fc774d5b0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/silexphp/Pimple/zipball/21e45061c3429b1e06233475cc0e1f6fc774d5b0", - "reference": "21e45061c3429b1e06233475cc0e1f6fc774d5b0", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.2.5", - "psr/container": "^1.0" - }, - "require-dev": { - "symfony/phpunit-bridge": "^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.3.x-dev" - } - }, - "autoload": { - "psr-0": { - "Pimple": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Pimple, a simple Dependency Injection Container", - "homepage": "https://pimple.symfony.com", - "keywords": [ - "container", - "dependency injection" - ], - "support": { - "source": "https://github.com/silexphp/Pimple/tree/v3.3.1" - }, - "time": "2020-11-24T20:35:42+00:00" - }, - { - "name": "psr/cache", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { + "name": "pimple/pimple", + "version": "v3.3.1", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Pimple.git", + "reference": "21e45061c3429b1e06233475cc0e1f6fc774d5b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/21e45061c3429b1e06233475cc0e1f6fc774d5b0", + "reference": "21e45061c3429b1e06233475cc0e1f6fc774d5b0", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3.x-dev" + } + }, + "autoload": { + "psr-0": { + "Pimple": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Pimple, a simple Dependency Injection Container", + "homepage": "https://pimple.symfony.com", + "keywords": [ + "container", + "dependency injection" + ], + "support": { + "source": "https://github.com/silexphp/Pimple/tree/v3.3.1" + }, + "time": "2020-11-24T20:35:42+00:00" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { "Psr\\Cache\\": "src/" } }, @@ -1575,6 +1906,9 @@ "psr", "psr-6" ], + "support": { + "source": "https://github.com/php-fig/cache/tree/master" + }, "time": "2016-08-06T20:24:11+00:00" }, { @@ -1630,8 +1964,68 @@ "container-interop", "psr" ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/master" + }, "time": "2017-02-14T16:28:37+00:00" }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, { "name": "psr/http-message", "version": "1.0.1", @@ -1686,6 +2080,9 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, "time": "2016-08-06T14:39:51+00:00" }, { @@ -1739,6 +2136,9 @@ "psr", "psr-3" ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.3" + }, "time": "2020-03-23T09:12:05+00:00" }, { @@ -1751,62 +2151,65 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", - "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\SimpleCache\\": "src/" - } - }, - "notification-url": "https://packagist.jp/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interfaces for simple caching", - "keywords": [ - "cache", - "caching", - "psr", - "psr-16", - "simple-cache" - ], - "time": "2017-10-23T01:57:42+00:00" + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/master" + }, + "time": "2017-10-23T01:57:42+00:00" }, { "name": "qcloud/cos-sdk-v5", - "version": "v2.0.9", + "version": "v2.1.1", "source": { "type": "git", "url": "https://github.com/tencentyun/cos-php-sdk-v5.git", - "reference": "d9fa5e8468ce4462d671976555efaa9acd2896e4" + "reference": "8dab76e9898f862c2cdc074b8411cbd77ca291f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tencentyun/cos-php-sdk-v5/zipball/d9fa5e8468ce4462d671976555efaa9acd2896e4", - "reference": "d9fa5e8468ce4462d671976555efaa9acd2896e4", + "url": "https://api.github.com/repos/tencentyun/cos-php-sdk-v5/zipball/8dab76e9898f862c2cdc074b8411cbd77ca291f3", + "reference": "8dab76e9898f862c2cdc074b8411cbd77ca291f3", "shasum": "", "mirrors": [ { @@ -1846,7 +2249,11 @@ "php", "qcloud" ], - "time": "2020-06-16T13:09:21+00:00" + "support": { + "issues": "https://github.com/tencentyun/cos-php-sdk-v5/issues", + "source": "https://github.com/tencentyun/cos-php-sdk-v5/tree/v2.1.1" + }, + "time": "2020-09-27T03:57:55+00:00" }, { "name": "qcloudsms/qcloudsms_php", @@ -1888,6 +2295,10 @@ "sdk", "sms" ], + "support": { + "issues": "https://github.com/qcloudsms/qcloudsms_php/issues", + "source": "https://github.com/qcloudsms/qcloudsms_php/tree/master" + }, "time": "2018-09-19T07:19:17+00:00" }, { @@ -1934,6 +2345,10 @@ } ], "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, "time": "2019-03-08T08:55:37+00:00" }, { @@ -2022,20 +2437,24 @@ "migrations", "phinx" ], + "support": { + "issues": "https://github.com/cakephp/phinx/issues", + "source": "https://github.com/cakephp/phinx/tree/master" + }, "time": "2020-08-15T07:42:40+00:00" }, { "name": "swiftmailer/swiftmailer", - "version": "v6.2.1", + "version": "v6.2.5", "source": { "type": "git", "url": "https://github.com/swiftmailer/swiftmailer.git", - "reference": "5397cd05b0a0f7937c47b0adcb4c60e5ab936b6a" + "reference": "698a6a9f54d7eb321274de3ad19863802c879fb7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/5397cd05b0a0f7937c47b0adcb4c60e5ab936b6a", - "reference": "5397cd05b0a0f7937c47b0adcb4c60e5ab936b6a", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/698a6a9f54d7eb321274de3ad19863802c879fb7", + "reference": "698a6a9f54d7eb321274de3ad19863802c879fb7", "shasum": "", "mirrors": [ { @@ -2045,19 +2464,18 @@ ] }, "require": { - "egulias/email-validator": "~2.0", + "egulias/email-validator": "^2.0", "php": ">=7.0.0", "symfony/polyfill-iconv": "^1.0", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0" }, "require-dev": { - "mockery/mockery": "~0.9.1", - "symfony/phpunit-bridge": "^3.4.19|^4.1.8" + "mockery/mockery": "^1.0", + "symfony/phpunit-bridge": "^4.4|^5.0" }, "suggest": { - "ext-intl": "Needed to support internationalized email addresses", - "true/punycode": "Needed to support internationalized email addresses, if ext-intl is not installed" + "ext-intl": "Needed to support internationalized email addresses" }, "type": "library", "extra": { @@ -2065,250 +2483,264 @@ "dev-master": "6.2-dev" } }, - "autoload": { - "files": [ - "lib/swift_required.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Chris Corbyn" + "autoload": { + "files": [ + "lib/swift_required.php" + ] }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Swiftmailer, free feature-rich PHP mailer", - "homepage": "https://swiftmailer.symfony.com", - "keywords": [ - "email", - "mail", - "mailer" - ], - "time": "2019-04-21T09:21:45+00:00" - }, - { - "name": "symfony/cache", - "version": "v5.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/cache.git", - "reference": "c15fd2b3dcf2bd7d5ee3265874870d6cc694306b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/c15fd2b3dcf2bd7d5ee3265874870d6cc694306b", - "reference": "c15fd2b3dcf2bd7d5ee3265874870d6cc694306b", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.2.5", - "psr/cache": "~1.0", - "psr/log": "^1.1", - "symfony/cache-contracts": "^1.1.7|^2", - "symfony/polyfill-php80": "^1.15", - "symfony/service-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0" - }, - "conflict": { - "doctrine/dbal": "<2.10", - "symfony/dependency-injection": "<4.4", - "symfony/http-kernel": "<4.4", - "symfony/var-dumper": "<4.4" - }, - "provide": { - "psr/cache-implementation": "1.0", - "psr/simple-cache-implementation": "1.0", - "symfony/cache-implementation": "1.0" - }, - "require-dev": { - "cache/integration-tests": "dev-master", - "doctrine/cache": "^1.6", - "doctrine/dbal": "^2.10|^3.0", - "predis/predis": "^1.1", - "psr/simple-cache": "^1.0", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/filesystem": "^4.4|^5.0", - "symfony/http-kernel": "^4.4|^5.0", - "symfony/messenger": "^4.4|^5.0", - "symfony/var-dumper": "^4.4|^5.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Cache\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Corbyn" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Swiftmailer, free feature-rich PHP mailer", + "homepage": "https://swiftmailer.symfony.com", + "keywords": [ + "email", + "mail", + "mailer" + ], + "support": { + "issues": "https://github.com/swiftmailer/swiftmailer/issues", + "source": "https://github.com/swiftmailer/swiftmailer/tree/v6.2.5" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/swiftmailer/swiftmailer", + "type": "tidelift" + } + ], + "time": "2021-01-12T09:35:59+00:00" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Cache component with PSR-6, PSR-16, and tags", - "homepage": "https://symfony.com", - "keywords": [ - "caching", - "psr6" - ], - "support": { - "source": "https://github.com/symfony/cache/tree/v5.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" + "name": "symfony/cache", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "5e61d63b1ef4fb4852994038267ad45e12f3ec52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/5e61d63b1ef4fb4852994038267ad45e12f3ec52", + "reference": "5e61d63b1ef4fb4852994038267ad45e12f3ec52", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.2.5", + "psr/cache": "~1.0", + "psr/log": "^1.1", + "symfony/cache-contracts": "^1.1.7|^2", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.4|^5.0" + }, + "conflict": { + "doctrine/dbal": "<2.10", + "symfony/dependency-injection": "<4.4", + "symfony/http-kernel": "<4.4", + "symfony/var-dumper": "<4.4" + }, + "provide": { + "psr/cache-implementation": "1.0", + "psr/simple-cache-implementation": "1.0", + "symfony/cache-implementation": "1.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/cache": "^1.6", + "doctrine/dbal": "^2.10|^3.0", + "predis/predis": "^1.1", + "psr/simple-cache": "^1.0", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/filesystem": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0", + "symfony/messenger": "^4.4|^5.0", + "symfony/var-dumper": "^4.4|^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Cache component with PSR-6, PSR-16, and tags", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "support": { + "source": "https://github.com/symfony/cache/tree/v5.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-12-10T19:16:15+00:00" }, { - "url": "https://github.com/fabpot", - "type": "github" + "name": "symfony/cache-contracts", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "8034ca0b61d4dd967f3698aaa1da2507b631d0cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/8034ca0b61d4dd967f3698aaa1da2507b631d0cb", + "reference": "8034ca0b61d4dd967f3698aaa1da2507b631d0cb", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.2.5", + "psr/cache": "^1.0" + }, + "suggest": { + "symfony/cache-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Cache\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to caching", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/cache-contracts/tree/v2.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-07T11:33:47+00:00" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-11-21T09:39:55+00:00" - }, - { - "name": "symfony/cache-contracts", - "version": "v2.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/cache-contracts.git", - "reference": "8034ca0b61d4dd967f3698aaa1da2507b631d0cb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/8034ca0b61d4dd967f3698aaa1da2507b631d0cb", - "reference": "8034ca0b61d4dd967f3698aaa1da2507b631d0cb", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.2.5", - "psr/cache": "^1.0" - }, - "suggest": { - "symfony/cache-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Cache\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to caching", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/cache-contracts/tree/v2.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-09-07T11:33:47+00:00" - }, - { - "name": "symfony/config", - "version": "v5.1.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/config.git", - "reference": "cf63f0613a6c6918e96db39c07a43b01e19a0773" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/cf63f0613a6c6918e96db39c07a43b01e19a0773", - "reference": "cf63f0613a6c6918e96db39c07a43b01e19a0773", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/filesystem": "^4.4|^5.0", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-php80": "^1.15" - }, - "conflict": { - "symfony/finder": "<4.4" - }, - "require-dev": { + "name": "symfony/config", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "d0a82d965296083fe463d655a3644cbe49cbaa80" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/d0a82d965296083fe463d655a3644cbe49cbaa80", + "reference": "d0a82d965296083fe463d655a3644cbe49cbaa80", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/filesystem": "^4.4|^5.0", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php80": "^1.15" + }, + "conflict": { + "symfony/finder": "<4.4" + }, + "require-dev": { "symfony/event-dispatcher": "^4.4|^5.0", "symfony/finder": "^4.4|^5.0", "symfony/messenger": "^4.4|^5.0", @@ -2319,11 +2751,6 @@ "symfony/yaml": "To use the yaml reference dumper" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Config\\": "" @@ -2348,6 +2775,9 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v5.2.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -2362,20 +2792,20 @@ "type": "tidelift" } ], - "time": "2020-07-15T10:53:22+00:00" + "time": "2020-12-09T18:54:12+00:00" }, { "name": "symfony/console", - "version": "v4.4.11", + "version": "v5.2.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "55d07021da933dd0d633ffdab6f45d5b230c7e02" + "reference": "47c02526c532fb381374dab26df05e7313978976" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/55d07021da933dd0d633ffdab6f45d5b230c7e02", - "reference": "55d07021da933dd0d633ffdab6f45d5b230c7e02", + "url": "https://api.github.com/repos/symfony/console/zipball/47c02526c532fb381374dab26df05e7313978976", + "reference": "47c02526c532fb381374dab26df05e7313978976", "shasum": "", "mirrors": [ { @@ -2385,29 +2815,31 @@ ] }, "require": { - "php": ">=7.1.3", + "php": ">=7.2.5", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", "symfony/polyfill-php80": "^1.15", - "symfony/service-contracts": "^1.1|^2" + "symfony/service-contracts": "^1.1|^2", + "symfony/string": "^5.1" }, "conflict": { - "symfony/dependency-injection": "<3.4", - "symfony/event-dispatcher": "<4.3|>=5", + "symfony/dependency-injection": "<4.4", + "symfony/dotenv": "<5.1", + "symfony/event-dispatcher": "<4.4", "symfony/lock": "<4.4", - "symfony/process": "<3.3" + "symfony/process": "<4.4" }, "provide": { "psr/log-implementation": "1.0" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/event-dispatcher": "^4.3", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/event-dispatcher": "^4.4|^5.0", "symfony/lock": "^4.4|^5.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/var-dumper": "^4.3|^5.0" + "symfony/process": "^4.4|^5.0", + "symfony/var-dumper": "^4.4|^5.0" }, "suggest": { "psr/log": "For using the console logger", @@ -2416,11 +2848,6 @@ "symfony/process": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Console\\": "" @@ -2445,62 +2872,71 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } + "keywords": [ + "cli", + "command line", + "console", + "terminal" ], - "time": "2020-07-06T13:18:39+00:00" + "support": { + "source": "https://github.com/symfony/console/tree/v5.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-12-18T08:03:05+00:00" }, - { - "name": "symfony/deprecation-contracts", - "version": "v2.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", - "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ + { + "name": "symfony/deprecation-contracts", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", + "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ "MIT" ], "authors": [ @@ -2515,63 +2951,68 @@ ], "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/master" + }, "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } ], - "time": "2020-09-07T11:33:47+00:00" - }, - { - "name": "symfony/event-dispatcher", - "version": "v4.4.17", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "f029d6f21eac61ab23198e7aca40e7638e8c8924" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f029d6f21eac61ab23198e7aca40e7638e8c8924", - "reference": "f029d6f21eac61ab23198e7aca40e7638e8c8924", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.1.3", - "symfony/event-dispatcher-contracts": "^1.1" - }, - "conflict": { - "symfony/dependency-injection": "<3.4" - }, - "provide": { - "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "1.1" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/error-handler": "~3.4|~4.4", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/http-foundation": "^3.4|^4.0|^5.0", - "symfony/service-contracts": "^1.1|^2", - "symfony/stopwatch": "^3.4|^4.0|^5.0" - }, + "time": "2020-09-07T11:33:47+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "1c93f7a1dff592c252574c79a8635a8a80856042" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1c93f7a1dff592c252574c79a8635a8a80856042", + "reference": "1c93f7a1dff592c252574c79a8635a8a80856042", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/event-dispatcher-contracts": "^2", + "symfony/polyfill-php80": "^1.15" + }, + "conflict": { + "symfony/dependency-injection": "<4.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/error-handler": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/http-foundation": "^4.4|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/stopwatch": "^4.4|^5.0" + }, "suggest": { "symfony/dependency-injection": "", "symfony/http-kernel": "" @@ -2579,156 +3020,157 @@ "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" + "Symfony\\Component\\EventDispatcher\\": "" }, - "exclude-from-classmap": [ - "/Tests/" - ] + "exclude-from-classmap": [ + "/Tests/" + ] }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v5.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-12-18T08:03:05+00:00" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony EventDispatcher Component", - "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" + "name": "symfony/event-dispatcher-contracts", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0ba7d54483095a198fa51781bc608d17e84dffa2", + "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.2.5", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-07T11:33:47+00:00" }, { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-10-31T22:44:29+00:00" - }, - { - "name": "symfony/event-dispatcher-contracts", - "version": "v1.1.9", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/84e23fdcd2517bf37aecbd16967e83f0caee25a7", - "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.1.3" - }, - "suggest": { - "psr/event-dispatcher": "", - "symfony/event-dispatcher-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\EventDispatcher\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to dispatching event", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-07-06T13:19:58+00:00" - }, - { - "name": "symfony/filesystem", - "version": "v5.1.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "6e4320f06d5f2cce0d96530162491f4465179157" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/6e4320f06d5f2cce0d96530162491f4465179157", - "reference": "6e4320f06d5f2cce0d96530162491f4465179157", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, + "name": "symfony/filesystem", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/fa8f8cab6b65e2d99a118e082935344c5ba8c60d", + "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, "require": { "php": ">=7.2.5", "symfony/polyfill-ctype": "~1.8" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Filesystem\\": "" @@ -2753,62 +3195,65 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.2.1" + }, "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } ], - "time": "2020-05-30T20:35:19+00:00" - }, - { - "name": "symfony/http-foundation", - "version": "v5.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-foundation.git", - "reference": "e4576271ee99123aa59a40564c7b5405f0ebd1e6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e4576271ee99123aa59a40564c7b5405f0ebd1e6", - "reference": "e4576271ee99123aa59a40564c7b5405f0ebd1e6", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php80": "^1.15" - }, - "require-dev": { - "predis/predis": "~1.0", - "symfony/cache": "^4.4|^5.0", - "symfony/expression-language": "^4.4|^5.0", - "symfony/mime": "^4.4|^5.0" - }, - "suggest": { - "symfony/mime": "To use the file extension guesser" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" + "time": "2020-11-30T17:05:38+00:00" }, + { + "name": "symfony/http-foundation", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "a1f6218b29897ab52acba58cfa905b83625bef8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/a1f6218b29897ab52acba58cfa905b83625bef8d", + "reference": "a1f6218b29897ab52acba58cfa905b83625bef8d", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php80": "^1.15" + }, + "require-dev": { + "predis/predis": "~1.0", + "symfony/cache": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/mime": "^4.4|^5.0" + }, + "suggest": { + "symfony/mime": "To use the file extension guesser" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, "exclude-from-classmap": [ "/Tests/" ] @@ -2829,6 +3274,9 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v5.2.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -2843,20 +3291,20 @@ "type": "tidelift" } ], - "time": "2020-11-27T06:13:25+00:00" + "time": "2020-12-18T10:00:10+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.18.1", + "name": "symfony/options-resolver", + "version": "v5.2.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "1c302646f6efc070cd46856e600e5e0684d6b454" + "url": "https://github.com/symfony/options-resolver.git", + "reference": "87a2a4a766244e796dd9cb9d6f58c123358cd986" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", - "reference": "1c302646f6efc070cd46856e600e5e0684d6b454", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/87a2a4a766244e796dd9cb9d6f58c123358cd986", + "reference": "87a2a4a766244e796dd9cb9d6f58c123358cd986", "shasum": "", "mirrors": [ { @@ -2866,7 +3314,82 @@ ] }, "require": { - "php": ">=5.3.3" + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php73": "~1.0", + "symfony/polyfill-php80": "^1.15" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony OptionsResolver Component", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v5.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T12:08:07+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.22.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1" }, "suggest": { "ext-ctype": "For best performance" @@ -2874,7 +3397,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2911,6 +3434,9 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -2925,20 +3451,20 @@ "type": "tidelift" } ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-iconv", - "version": "v1.12.0", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "685968b11e61a347c18bf25db32effa478be610f" + "reference": "b34bfb8c4c22650ac080d2662ae3502e5f2f4ae6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/685968b11e61a347c18bf25db32effa478be610f", - "reference": "685968b11e61a347c18bf25db32effa478be610f", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/b34bfb8c4c22650ac080d2662ae3502e5f2f4ae6", + "reference": "b34bfb8c4c22650ac080d2662ae3502e5f2f4ae6", "shasum": "", "mirrors": [ { @@ -2948,7 +3474,7 @@ ] }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-iconv": "For best performance" @@ -2956,7 +3482,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -2990,20 +3520,37 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.22.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-07T16:49:33+00:00" }, { - "name": "symfony/polyfill-intl-idn", - "version": "v1.18.1", + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.22.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "5dcab1bc7146cf8c1beaa4502a3d9be344334251" + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "267a9adeb8ecb8071040a740930e077cdfb987af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/5dcab1bc7146cf8c1beaa4502a3d9be344334251", - "reference": "5dcab1bc7146cf8c1beaa4502a3d9be344334251", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/267a9adeb8ecb8071040a740930e077cdfb987af", + "reference": "267a9adeb8ecb8071040a740930e077cdfb987af", "shasum": "", "mirrors": [ { @@ -3013,9 +3560,95 @@ ] }, "require": { - "php": ">=5.3.3", + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-07T16:49:33+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.22.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "0eb8293dbbcd6ef6bf81404c9ce7d95bcdf34f44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/0eb8293dbbcd6ef6bf81404c9ce7d95bcdf34f44", + "reference": "0eb8293dbbcd6ef6bf81404c9ce7d95bcdf34f44", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1", "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php70": "^1.10", "symfony/polyfill-php72": "^1.10" }, "suggest": { @@ -3024,7 +3657,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3067,6 +3700,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.22.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3081,20 +3717,20 @@ "type": "tidelift" } ], - "time": "2020-08-04T06:02:08+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.18.1", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e" + "reference": "6e971c891537eb617a00bb07a43d182a6915faba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e", - "reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/6e971c891537eb617a00bb07a43d182a6915faba", + "reference": "6e971c891537eb617a00bb07a43d182a6915faba", "shasum": "", "mirrors": [ { @@ -3104,7 +3740,7 @@ ] }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-intl": "For best performance" @@ -3112,7 +3748,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3154,62 +3790,65 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.0" + }, "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } ], - "time": "2020-07-14T12:35:20+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.20.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.20-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" + "time": "2021-01-07T17:09:11+00:00" }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.22.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", + "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, "files": [ "bootstrap.php" ] @@ -3237,6 +3876,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3251,103 +3893,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" - }, - { - "name": "symfony/polyfill-php70", - "version": "v1.18.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "0dd93f2c578bdc9c72697eaa5f1dd25644e618d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/0dd93f2c578bdc9c72697eaa5f1dd25644e618d3", - "reference": "0dd93f2c578bdc9c72697eaa5f1dd25644e618d3", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "paragonie/random_compat": "~1.0|~2.0|~9.99", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.18-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php70\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.18.1", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "639447d008615574653fb3bc60d1986d7172eaae" + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/639447d008615574653fb3bc60d1986d7172eaae", - "reference": "639447d008615574653fb3bc60d1986d7172eaae", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", "shasum": "", "mirrors": [ { @@ -3357,12 +3916,12 @@ ] }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3399,6 +3958,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.22.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3413,20 +3975,20 @@ "type": "tidelift" } ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.18.1", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "fffa1a52a023e782cdcc221d781fe1ec8f87fcca" + "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fffa1a52a023e782cdcc221d781fe1ec8f87fcca", - "reference": "fffa1a52a023e782cdcc221d781fe1ec8f87fcca", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", + "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", "shasum": "", "mirrors": [ { @@ -3436,12 +3998,12 @@ ] }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3481,62 +4043,65 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.0" + }, "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2021-01-07T16:49:33+00:00" }, - { - "name": "symfony/polyfill-php80", - "version": "v1.20.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de", - "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.20-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "files": [ - "bootstrap.php" - ], + { + "name": "symfony/polyfill-php80", + "version": "v1.22.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91", + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], "classmap": [ "Resources/stubs" ] @@ -3567,151 +4132,337 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.0" + }, "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } ], - "time": "2020-10-23T14:02:19+00:00" - }, - { - "name": "symfony/psr-http-message-bridge", - "version": "v2.0.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "51a21cb3ba3927d4b4bf8f25cc55763351af5f2e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/51a21cb3ba3927d4b4bf8f25cc55763351af5f2e", - "reference": "51a21cb3ba3927d4b4bf8f25cc55763351af5f2e", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.1", - "psr/http-message": "^1.0", - "symfony/http-foundation": "^4.4 || ^5.0" - }, - "require-dev": { - "nyholm/psr7": "^1.1", - "symfony/phpunit-bridge": "^4.4 || ^5.0" - }, - "suggest": { - "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" - }, - "type": "symfony-bridge", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Bridge\\PsrHttpMessage\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "time": "2021-01-07T16:49:33+00:00" }, { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "PSR HTTP message bridge", - "homepage": "http://symfony.com", - "keywords": [ - "http", - "http-message", - "psr-17", - "psr-7" - ], - "support": { - "issues": "https://github.com/symfony/psr-http-message-bridge/issues", - "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.0.2" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" + "name": "symfony/property-access", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-access.git", + "reference": "243dcdda2f276cb31efa31a015d0fdb5076931ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-access/zipball/243dcdda2f276cb31efa31a015d0fdb5076931ce", + "reference": "243dcdda2f276cb31efa31a015d0fdb5076931ce", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php80": "^1.15", + "symfony/property-info": "^5.2" + }, + "require-dev": { + "symfony/cache": "^4.4|^5.0" + }, + "suggest": { + "psr/cache-implementation": "To cache access methods." + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyAccess\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony PropertyAccess Component", + "homepage": "https://symfony.com", + "keywords": [ + "access", + "array", + "extraction", + "index", + "injection", + "object", + "property", + "property path", + "reflection" + ], + "support": { + "source": "https://github.com/symfony/property-access/tree/v5.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-12-10T19:16:15+00:00" }, { - "url": "https://github.com/fabpot", - "type": "github" + "name": "symfony/property-info", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-info.git", + "reference": "f65694a05eb7742c5f2951f20676de367ffaaaea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-info/zipball/f65694a05eb7742c5f2951f20676de367ffaaaea", + "reference": "f65694a05eb7742c5f2951f20676de367ffaaaea", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php80": "^1.15", + "symfony/string": "^5.1" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<0.3.0", + "symfony/dependency-injection": "<4.4" + }, + "require-dev": { + "doctrine/annotations": "~1.7", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/cache": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/serializer": "^4.4|^5.0" + }, + "suggest": { + "phpdocumentor/reflection-docblock": "To use the PHPDoc", + "psr/cache-implementation": "To cache results", + "symfony/doctrine-bridge": "To use Doctrine metadata", + "symfony/serializer": "To use Serializer metadata" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "dunglas@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Property Info Component", + "homepage": "https://symfony.com", + "keywords": [ + "doctrine", + "phpdoc", + "property", + "symfony", + "type", + "validator" + ], + "support": { + "source": "https://github.com/symfony/property-info/tree/v5.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-12-11T23:40:07+00:00" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-09-29T08:17:46+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v2.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", - "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.2.5", - "psr/container": "^1.0" - }, - "suggest": { - "symfony/service-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev" + "name": "symfony/psr-http-message-bridge", + "version": "v2.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "51a21cb3ba3927d4b4bf8f25cc55763351af5f2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/51a21cb3ba3927d4b4bf8f25cc55763351af5f2e", + "reference": "51a21cb3ba3927d4b4bf8f25cc55763351af5f2e", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0", + "symfony/http-foundation": "^4.4 || ^5.0" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "symfony/phpunit-bridge": "^4.4 || ^5.0" + }, + "suggest": { + "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/symfony/psr-http-message-bridge/issues", + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.0.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-29T08:17:46+00:00" }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - } + { + "name": "symfony/service-contracts", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", + "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.0" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3737,130 +4488,222 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/master" + }, "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } ], - "time": "2020-09-07T11:33:47+00:00" - }, - { - "name": "symfony/var-exporter", - "version": "v5.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-exporter.git", - "reference": "fbc3507f23d263d75417e09a12d77c009f39676c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/fbc3507f23d263d75417e09a12d77c009f39676c", - "reference": "fbc3507f23d263d75417e09a12d77c009f39676c", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.15" - }, - "require-dev": { - "symfony/var-dumper": "^4.4.9|^5.0.9" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\VarExporter\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "time": "2020-09-07T11:33:47+00:00" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A blend of var_export() + serialize() to turn any serializable data structure to plain PHP code", - "homepage": "https://symfony.com", - "keywords": [ - "clone", - "construct", - "export", - "hydrate", - "instantiate", - "serialize" - ], - "support": { - "source": "https://github.com/symfony/var-exporter/tree/v5.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" + "name": "symfony/string", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed", + "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "~1.15" + }, + "require-dev": { + "symfony/error-handler": "^4.4|^5.0", + "symfony/http-client": "^4.4|^5.0", + "symfony/translation-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.4|^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "files": [ + "Resources/functions.php" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony String component", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v5.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-12-05T07:33:16+00:00" }, { - "url": "https://github.com/fabpot", - "type": "github" + "name": "symfony/var-exporter", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "fbc3507f23d263d75417e09a12d77c009f39676c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/fbc3507f23d263d75417e09a12d77c009f39676c", + "reference": "fbc3507f23d263d75417e09a12d77c009f39676c", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.15" + }, + "require-dev": { + "symfony/var-dumper": "^4.4.9|^5.0.9" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A blend of var_export() + serialize() to turn any serializable data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v5.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-28T21:31:18+00:00" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-10-28T21:31:18+00:00" - }, - { - "name": "tencentcloud/tencentcloud-sdk-php", - "version": "3.0.251", - "source": { - "type": "git", - "url": "https://github.com/TencentCloud/tencentcloud-sdk-php.git", - "reference": "a3b3054262e48776e8014d5e385a8932b0102f29" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/TencentCloud/tencentcloud-sdk-php/zipball/a3b3054262e48776e8014d5e385a8932b0102f29", - "reference": "a3b3054262e48776e8014d5e385a8932b0102f29", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "guzzlehttp/guzzle": "^6.3", - "guzzlehttp/psr7": "^1.4", - "php": ">=5.6.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/QcloudApi/QcloudApi.php" + "name": "tencentcloud/tencentcloud-sdk-php", + "version": "3.0.321", + "source": { + "type": "git", + "url": "https://github.com/TencentCloud/tencentcloud-sdk-php.git", + "reference": "6d8d68f8076ab986c211f3be573987ea66ff0435" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/TencentCloud/tencentcloud-sdk-php/zipball/6d8d68f8076ab986c211f3be573987ea66ff0435", + "reference": "6d8d68f8076ab986c211f3be573987ea66ff0435", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "guzzlehttp/guzzle": "^6.3 || ^7.0.1", + "guzzlehttp/psr7": "^1.4", + "php": ">=5.6.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/QcloudApi/QcloudApi.php" ], "psr-4": { "TencentCloud\\": "./src/TencentCloud" @@ -3880,20 +4723,83 @@ ], "description": "TencentCloudApi php sdk", "homepage": "https://github.com/TencentCloud/tencentcloud-sdk-php", - "time": "2020-09-15T00:59:07+00:00" + "support": { + "issues": "https://github.com/TencentCloud/tencentcloud-sdk-php/issues", + "source": "https://github.com/TencentCloud/tencentcloud-sdk-php/tree/3.0.321" + }, + "time": "2021-01-19T06:29:14+00:00" }, { - "name": "whichbrowser/parser", - "version": "v2.0.37", + "name": "webmozart/assert", + "version": "1.9.1", "source": { "type": "git", - "url": "https://github.com/WhichBrowser/Parser-PHP.git", - "reference": "9c6ad8eadc23294b1c66d92876c11f13c5d4cf48" + "url": "https://github.com/webmozart/assert.git", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WhichBrowser/Parser-PHP/zipball/9c6ad8eadc23294b1c66d92876c11f13c5d4cf48", - "reference": "9c6ad8eadc23294b1c66d92876c11f13c5d4cf48", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^5.3.3 || ^7.0 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<3.9.1" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^7.5.13" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozart/assert/issues", + "source": "https://github.com/webmozart/assert/tree/master" + }, + "time": "2020-07-08T17:02:28+00:00" + }, + { + "name": "whichbrowser/parser", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/WhichBrowser/Parser-PHP.git", + "reference": "da24adc4f4f26002673d236e69b91a10f2fd594c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/WhichBrowser/Parser-PHP/zipball/da24adc4f4f26002673d236e69b91a10f2fd594c", + "reference": "da24adc4f4f26002673d236e69b91a10f2fd594c", "shasum": "", "mirrors": [ { @@ -3907,12 +4813,13 @@ "psr/cache": "^1.0" }, "require-dev": { + "cache/array-adapter": "^1.1", "icomefromthenet/reverse-regex": "0.0.6.3", - "phpunit/php-code-coverage": "^2.2|^3.0", - "phpunit/phpunit": "^4.0|^5.0", - "satooshi/php-coveralls": "^1.0", - "squizlabs/php_codesniffer": "2.5.*", - "symfony/yaml": ">=2.8" + "php-coveralls/php-coveralls": "^2.0", + "phpunit/php-code-coverage": "^5.0 || ^7.0", + "phpunit/phpunit": "^6.0 || ^8.0", + "squizlabs/php_codesniffer": "^3.5", + "symfony/yaml": "~3.4 || ~4.0" }, "suggest": { "cache/array-adapter": "Allows testing of the caching functionality" @@ -3945,7 +4852,11 @@ "ua", "useragent" ], - "time": "2018-10-02T09:26:41+00:00" + "support": { + "issues": "https://github.com/WhichBrowser/Parser-PHP/issues", + "source": "https://github.com/WhichBrowser/Parser-PHP/tree/v2.1.1" + }, + "time": "2021-01-04T16:36:15+00:00" }, { "name": "workerman/gateway-worker", @@ -3985,6 +4896,10 @@ "communication", "distributed" ], + "support": { + "issues": "https://github.com/walkor/GatewayWorker/issues", + "source": "https://github.com/walkor/GatewayWorker/tree/v3.0.18" + }, "time": "2020-07-15T06:45:01+00:00" }, { @@ -4018,20 +4933,24 @@ "MIT" ], "homepage": "http://www.workerman.net", + "support": { + "issues": "https://github.com/walkor/GatewayClient/issues", + "source": "https://github.com/walkor/GatewayClient/tree/v3.0.13" + }, "time": "2018-09-15T03:03:50+00:00" }, { "name": "workerman/workerman", - "version": "v3.5.22", + "version": "v4.0.18", "source": { "type": "git", "url": "https://github.com/walkor/Workerman.git", - "reference": "488f108f9e446f31bac4d689bb9f9fe3705862cf" + "reference": "02930876526479c7e4123ef1dc8d23d509d40e72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/walkor/Workerman/zipball/488f108f9e446f31bac4d689bb9f9fe3705862cf", - "reference": "488f108f9e446f31bac4d689bb9f9fe3705862cf", + "url": "https://api.github.com/repos/walkor/Workerman/zipball/02930876526479c7e4123ef1dc8d23d509d40e72", + "reference": "02930876526479c7e4123ef1dc8d23d509d40e72", "shasum": "", "mirrors": [ { @@ -4070,20 +4989,27 @@ "asynchronous", "event-loop" ], - "time": "2019-09-06T03:42:47+00:00" + "support": { + "email": "walkor@workerman.net", + "forum": "http://wenda.workerman.net/", + "issues": "https://github.com/walkor/workerman/issues", + "source": "https://github.com/walkor/workerman", + "wiki": "http://doc.workerman.net/" + }, + "time": "2021-01-02T06:14:59+00:00" }, { "name": "xiaochong0302/ip2region", - "version": "v1.0.0", + "version": "v1.0.1", "source": { "type": "git", "url": "https://github.com/xiaochong0302/ip2region.git", - "reference": "3cb3c50fa9e2c49115e40252f6b651437712a4e9" + "reference": "d7ce99bd7d5f5a2f092e9dcd85b4739c9a1d6a85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/xiaochong0302/ip2region/zipball/3cb3c50fa9e2c49115e40252f6b651437712a4e9", - "reference": "3cb3c50fa9e2c49115e40252f6b651437712a4e9", + "url": "https://api.github.com/repos/xiaochong0302/ip2region/zipball/d7ce99bd7d5f5a2f092e9dcd85b4739c9a1d6a85", + "reference": "d7ce99bd7d5f5a2f092e9dcd85b4739c9a1d6a85", "shasum": "", "mirrors": [ { @@ -4115,20 +5041,24 @@ "keywords": [ "Ip2Region" ], - "time": "2019-08-18T14:57:02+00:00" + "support": { + "issues": "https://github.com/xiaochong0302/ip2region/issues", + "source": "https://github.com/xiaochong0302/ip2region/tree/v1.0.1" + }, + "time": "2021-01-14T03:00:28+00:00" }, { "name": "yansongda/pay", - "version": "v2.9.5", + "version": "v2.10.2", "source": { "type": "git", "url": "https://github.com/yansongda/pay.git", - "reference": "0372c600eee2476df1b59912608edbf297a6582b" + "reference": "8c258853b142c6d7589629b047ca5cb21232b509" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/yansongda/pay/zipball/0372c600eee2476df1b59912608edbf297a6582b", - "reference": "0372c600eee2476df1b59912608edbf297a6582b", + "url": "https://api.github.com/repos/yansongda/pay/zipball/8c258853b142c6d7589629b047ca5cb21232b509", + "reference": "8c258853b142c6d7589629b047ca5cb21232b509", "shasum": "", "mirrors": [ { @@ -4175,20 +5105,24 @@ "pay", "wechat" ], - "time": "2020-07-03T03:46:09+00:00" + "support": { + "issues": "https://github.com/yansongda/pay/issues", + "source": "https://github.com/yansongda/pay" + }, + "time": "2021-01-18T01:48:43+00:00" }, { "name": "yansongda/supports", - "version": "v2.1.14", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/yansongda/supports.git", - "reference": "c6bfcf6509288ab89fb9d1888e5154fe49869caf" + "reference": "de9a8d38b0461ddf9c12f27390dad9a40c9b4e3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/yansongda/supports/zipball/c6bfcf6509288ab89fb9d1888e5154fe49869caf", - "reference": "c6bfcf6509288ab89fb9d1888e5154fe49869caf", + "url": "https://api.github.com/repos/yansongda/supports/zipball/de9a8d38b0461ddf9c12f27390dad9a40c9b4e3b", + "reference": "de9a8d38b0461ddf9c12f27390dad9a40c9b4e3b", "shasum": "", "mirrors": [ { @@ -4198,7 +5132,7 @@ ] }, "require": { - "guzzlehttp/guzzle": "^6.2", + "guzzlehttp/guzzle": "^6.2 || ^7.0", "monolog/monolog": "^1.23 || ^2.0", "php": ">=7.1.3" }, @@ -4236,141 +5170,150 @@ "support", "throttle" ], - "time": "2020-06-18T12:14:05+00:00" + "support": { + "issues": "https://github.com/yansongda/supports/issues", + "source": "https://github.com/yansongda/supports" + }, + "time": "2020-10-14T08:17:18+00:00" } ], "packages-dev": [ - { - "name": "odan/phinx-migrations-generator", - "version": "5.3.2", - "source": { - "type": "git", - "url": "https://github.com/odan/phinx-migrations-generator.git", - "reference": "2d3620f8251838b53717f7a43a348de31e9d451c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/odan/phinx-migrations-generator/zipball/2d3620f8251838b53717f7a43a348de31e9d451c", - "reference": "2d3620f8251838b53717f7a43a348de31e9d451c", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-json": "*", - "ext-pdo": "*", - "php": "^7.2", - "riimu/kit-phpencoder": "^2.4", - "robmorgan/phinx": "^0.12", - "symfony/console": "^2.8 || ^3.0 || ^4.0 || ^5.0", - "symfony/polyfill-php73": "^1.18" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.16", - "overtrue/phplint": "^1.1 || ^2.0", - "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^8 || ^9", - "squizlabs/php_codesniffer": "^3.4" - }, - "bin": [ - "./bin/phinx-migrations" - ], - "type": "library", - "autoload": { - "psr-4": { - "Odan\\Migration\\": "src/Migration/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Migration generator for Phinx", - "homepage": "https://github.com/odan/phinx-migrations-generator", - "keywords": [ - "database", - "generator", - "migration", - "migrations", - "mysql", - "phinx" - ], - "support": { - "issues": "https://github.com/odan/phinx-migrations-generator/issues", - "source": "https://github.com/odan/phinx-migrations-generator/tree/5.3.2" - }, - "time": "2020-12-30T23:59:57+00:00" - }, - { - "name": "phalcon/ide-stubs", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/phalcon/ide-stubs.git", - "reference": "65144f2b0fad32b182ccb062b1efc1b4edea5d44" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phalcon/ide-stubs/zipball/65144f2b0fad32b182ccb062b1efc1b4edea5d44", - "reference": "65144f2b0fad32b182ccb062b1efc1b4edea5d44", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "notification-url": "https://packagist.jp/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Phalcon Team", - "email": "team@phalconphp.com", - "homepage": "https://phalconphp.com/en/team" - }, - { - "name": "Contributors", - "homepage": "https://github.com/phalcon/ide-stubs/graphs/contributors" - } - ], - "description": "The most complete Phalcon Framework IDE stubs library which enables autocompletion in modern IDEs.", - "homepage": "https://phalconphp.com", - "keywords": [ - "Devtools", - "Eclipse", - "autocomplete", - "ide", - "netbeans", - "phalcon", - "phpstorm", - "stub", - "stubs" - ], - "time": "2018-12-09T14:11:06+00:00" - }, { - "name": "riimu/kit-phpencoder", - "version": "v2.4.0", + "name": "odan/phinx-migrations-generator", + "version": "5.3.2", "source": { "type": "git", - "url": "https://github.com/Riimu/Kit-PHPEncoder.git", - "reference": "7e876d25019c3f6c23321ab5ac1a55c72fcd0933" + "url": "https://github.com/odan/phinx-migrations-generator.git", + "reference": "2d3620f8251838b53717f7a43a348de31e9d451c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Riimu/Kit-PHPEncoder/zipball/7e876d25019c3f6c23321ab5ac1a55c72fcd0933", - "reference": "7e876d25019c3f6c23321ab5ac1a55c72fcd0933", + "url": "https://api.github.com/repos/odan/phinx-migrations-generator/zipball/2d3620f8251838b53717f7a43a348de31e9d451c", + "reference": "2d3620f8251838b53717f7a43a348de31e9d451c", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-json": "*", + "ext-pdo": "*", + "php": "^7.2", + "riimu/kit-phpencoder": "^2.4", + "robmorgan/phinx": "^0.12", + "symfony/console": "^2.8 || ^3.0 || ^4.0 || ^5.0", + "symfony/polyfill-php73": "^1.18" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16", + "overtrue/phplint": "^1.1 || ^2.0", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^8 || ^9", + "squizlabs/php_codesniffer": "^3.4" + }, + "bin": [ + "./bin/phinx-migrations" + ], + "type": "library", + "autoload": { + "psr-4": { + "Odan\\Migration\\": "src/Migration/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Migration generator for Phinx", + "homepage": "https://github.com/odan/phinx-migrations-generator", + "keywords": [ + "database", + "generator", + "migration", + "migrations", + "mysql", + "phinx" + ], + "support": { + "issues": "https://github.com/odan/phinx-migrations-generator/issues", + "source": "https://github.com/odan/phinx-migrations-generator/tree/5.3.2" + }, + "time": "2020-12-30T23:59:57+00:00" + }, + { + "name": "phalcon/ide-stubs", + "version": "v3.4.3", + "source": { + "type": "git", + "url": "https://github.com/phalcon/ide-stubs.git", + "reference": "65144f2b0fad32b182ccb062b1efc1b4edea5d44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phalcon/ide-stubs/zipball/65144f2b0fad32b182ccb062b1efc1b4edea5d44", + "reference": "65144f2b0fad32b182ccb062b1efc1b4edea5d44", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Phalcon Team", + "email": "team@phalconphp.com", + "homepage": "https://phalconphp.com/en/team" + }, + { + "name": "Contributors", + "homepage": "https://github.com/phalcon/ide-stubs/graphs/contributors" + } + ], + "description": "The most complete Phalcon Framework IDE stubs library which enables autocompletion in modern IDEs.", + "homepage": "https://phalconphp.com", + "keywords": [ + "Devtools", + "Eclipse", + "autocomplete", + "ide", + "netbeans", + "phalcon", + "phpstorm", + "stub", + "stubs" + ], + "support": { + "forum": "https://forum.phalconphp.com/", + "issues": "https://github.com/phalcon/ide-stubs/issues", + "source": "https://github.com/phalcon/ide-stubs" + }, + "time": "2018-12-09T14:11:06+00:00" + }, + { + "name": "riimu/kit-phpencoder", + "version": "v2.4.1", + "source": { + "type": "git", + "url": "https://github.com/Riimu/Kit-PHPEncoder.git", + "reference": "ca6f004e1290aec7ef4bebf6c0807b30fcf981d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Riimu/Kit-PHPEncoder/zipball/ca6f004e1290aec7ef4bebf6c0807b30fcf981d7", + "reference": "ca6f004e1290aec7ef4bebf6c0807b30fcf981d7", "shasum": "", "mirrors": [ { @@ -4383,7 +5326,7 @@ "php": ">=5.6.0" }, "require-dev": { - "phpunit/phpunit": "^7.2 || ^6.5 || ^5.7" + "phpunit/phpunit": "^9.4 || ^6.5 || ^5.7" }, "suggest": { "ext-gmp": "To convert GMP numbers into PHP code" @@ -4409,19 +5352,21 @@ "homepage": "http://kit.riimu.net", "keywords": [ "code", - "encoder", - "export", - "generator", - "variable" + "encoder", + "export", + "generator", + "variable" ], - "time": "2018-07-03T12:46:23+00:00" + "support": { + "issues": "https://github.com/Riimu/Kit-PHPEncoder/issues", + "source": "https://github.com/Riimu/Kit-PHPEncoder/tree/v2.4.1" + }, + "time": "2020-11-29T16:53:17+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "joyqi/hyper-down": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -4432,5 +5377,5 @@ "ext-fileinfo": "*" }, "platform-dev": [], - "plugin-api-version": "2.0.0" + "plugin-api-version": "2.0.0" } From 6abca790bce8af6336fb9f4aad26a0a45746677c Mon Sep 17 00:00:00 2001 From: koogua Date: Thu, 18 Feb 2021 21:20:23 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dfile=5Ftranscode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Console/Tasks/CleanLogTask.php | 13 ++ app/Console/Tasks/LiveTeacherNoticeTask.php | 81 +++++++ app/Console/Tasks/MonitorTask.php | 180 +++++++++++++++ .../Admin/Controllers/SettingController.php | 26 +++ app/Http/Admin/Controllers/TestController.php | 17 ++ app/Http/Admin/Services/AuthNode.php | 6 + .../Admin/Views/setting/dingtalk_robot.volt | 55 +++++ app/Library/Benchmark.php | 27 +++ app/Library/Helper.php | 18 ++ app/Models/Task.php | 3 +- .../DingTalk/Notice/ConsultCreate.php | 32 +++ .../DingTalk/Notice/CustomService.php | 36 +++ app/Services/DingTalk/Notice/LiveTeacher.php | 26 +++ app/Services/DingTalk/Notice/OrderFinish.php | 27 +++ app/Services/DingTalkNotice.php | 214 ++++++++++++++++++ .../20210215024511_data_202102151130.php | 42 ++++ scheduler.php | 3 + 17 files changed, 805 insertions(+), 1 deletion(-) create mode 100644 app/Console/Tasks/LiveTeacherNoticeTask.php create mode 100644 app/Console/Tasks/MonitorTask.php create mode 100644 app/Http/Admin/Views/setting/dingtalk_robot.volt create mode 100644 app/Library/Benchmark.php create mode 100644 app/Services/DingTalk/Notice/ConsultCreate.php create mode 100644 app/Services/DingTalk/Notice/CustomService.php create mode 100644 app/Services/DingTalk/Notice/LiveTeacher.php create mode 100644 app/Services/DingTalk/Notice/OrderFinish.php create mode 100644 app/Services/DingTalkNotice.php create mode 100644 db/migrations/20210215024511_data_202102151130.php diff --git a/app/Console/Tasks/CleanLogTask.php b/app/Console/Tasks/CleanLogTask.php index e198d702..581d6163 100644 --- a/app/Console/Tasks/CleanLogTask.php +++ b/app/Console/Tasks/CleanLogTask.php @@ -26,6 +26,7 @@ class CleanLogTask extends Task $this->cleanOrderLog(); $this->cleanRefundLog(); $this->cleanPointLog(); + $this->cleanDingTalkLog(); $this->cleanNoticeLog(); $this->cleanOtherLog(); } @@ -234,6 +235,18 @@ class CleanLogTask extends Task $this->whitelist[] = $type; } + /** + * 清理钉钉日志 + */ + protected function cleanDingTalkLog() + { + $type = 'dingtalk'; + + $this->cleanLog($type, 7); + + $this->whitelist[] = $type; + } + /** * 清理通知日志 */ diff --git a/app/Console/Tasks/LiveTeacherNoticeTask.php b/app/Console/Tasks/LiveTeacherNoticeTask.php new file mode 100644 index 00000000..49e25ed7 --- /dev/null +++ b/app/Console/Tasks/LiveTeacherNoticeTask.php @@ -0,0 +1,81 @@ +findLives(); + + if ($lives->count() == 0) return; + + $redis = $this->getRedis(); + + $keyName = $this->getCacheKeyName(); + + foreach ($lives as $live) { + $redis->sAdd($keyName, $live->chapter_id); + } + + $redis->expire($keyName, 86400); + } + + /** + * 消费讲师提醒 + */ + public function consumeAction() + { + $redis = $this->getRedis(); + + $keyName = $this->getCacheKeyName(); + + $chapterIds = $redis->sMembers($keyName); + + if (count($chapterIds) == 0) return; + + $chapterRepo = new ChapterRepo(); + + $notice = new LiveTeacherNotice(); + + foreach ($chapterIds as $chapterId) { + + $live = $chapterRepo->findChapterLive($chapterId); + + if ($live->start_time - time() < 30 * 60) { + + $notice->handle($live); + + $redis->sRem($keyName, $chapterId); + } + } + } + + /** + * @return ResultsetInterface|Resultset|ChapterLiveModel[] + */ + protected function findLives() + { + $today = strtotime(date('Ymd')); + + return ChapterLiveModel::query() + ->betweenWhere('start_time', $today, $today + 86400) + ->execute(); + } + + protected function getCacheKeyName() + { + return 'live_teacher_notice'; + } + +} \ No newline at end of file diff --git a/app/Console/Tasks/MonitorTask.php b/app/Console/Tasks/MonitorTask.php new file mode 100644 index 00000000..89481454 --- /dev/null +++ b/app/Console/Tasks/MonitorTask.php @@ -0,0 +1,180 @@ + $this->checkCPU(), + 'disk' => $this->checkDisk(), + 'mysql' => $this->checkMysql(), + 'redis' => $this->checkRedis(), + 'xunsearch' => $this->checkXunSearch(), + 'websocket' => $this->checkWebSocket(), + ]; + + foreach ($items as $key => $value) { + if (empty($value)) { + unset($items[$key]); + } + } + + if (empty($items)) return; + + $notice = new DingTalkNotice(); + + $content = implode("\n", $items); + + $notice->atTechSupport($content); + } + + protected function checkCPU() + { + $coreCount = $this->getCpuCoreCount(); + + $cpu = ServerInfo::cpu(); + + if ($cpu[1] > $coreCount / 2) { + return sprintf("cpu负载超过%s", $cpu[1]); + } + } + + protected function checkDisk() + { + $disk = ServerInfo::disk(); + + if ($disk['percent'] > 80) { + return sprintf("disk空间超过%s%%", $disk['percent']); + } + } + + protected function checkMysql() + { + try { + + $benchmark = new Benchmark(); + + $benchmark->start(); + + $user = UserModel::findFirst(); + + $benchmark->stop(); + + $elapsedTime = $benchmark->getElapsedTime(); + + if ($user === false) { + return sprintf("mysql查询失败"); + } + + if ($elapsedTime > 1) { + return sprintf("mysql查询响应超过%s秒", round($elapsedTime, 2)); + } + + } catch (\Exception $e) { + return sprintf("mysql可能存在异常"); + } + } + + protected function checkRedis() + { + try { + + $benchmark = new Benchmark(); + + $benchmark->start(); + + $site = $this->getSettings('site'); + + $benchmark->stop(); + + $elapsedTime = $benchmark->getElapsedTime(); + + if (empty($site)) { + return sprintf("redis查询失败"); + } + + if ($elapsedTime > 1) { + return sprintf("redis查询响应超过%s秒", round($elapsedTime, 2)); + } + + } catch (\Exception $e) { + return sprintf("redis可能存在异常"); + } + } + + protected function checkXunSearch() + { + try { + + $benchmark = new Benchmark(); + + $benchmark->start(); + + $searcher = new UserSearcher(); + + $user = $searcher->search('id:10000'); + + $benchmark->stop(); + + $elapsedTime = $benchmark->getElapsedTime(); + + if (empty($user)) { + return sprintf("xunsearch搜索失败"); + } + + if ($elapsedTime > 1) { + return sprintf("xunsearch搜索响应超过%s秒", round($elapsedTime, 2)); + } + + } catch (\Exception $e) { + return sprintf("xunsearch可能存在异常"); + } + } + + protected function checkWebSocket() + { + try { + + $benchmark = new Benchmark(); + + $config = $this->getConfig(); + + Gateway::$registerAddress = $config->path('websocket.register_address'); + + $benchmark->start(); + + Gateway::isUidOnline(10000); + + $benchmark->stop(); + + $elapsedTime = $benchmark->getElapsedTime(); + + if ($elapsedTime > 1) { + return sprintf("websocket响应超过%s秒", round($elapsedTime, 2)); + } + + } catch (\Exception $e) { + return sprintf("websocket可能存在异常"); + } + } + + protected function getCpuCoreCount() + { + $cpuInfo = file_get_contents('/proc/cpuinfo'); + + preg_match_all('/^processor/m', $cpuInfo, $matches); + + return count($matches[0]); + } + +} \ No newline at end of file diff --git a/app/Http/Admin/Controllers/SettingController.php b/app/Http/Admin/Controllers/SettingController.php index 76cff636..c7734972 100644 --- a/app/Http/Admin/Controllers/SettingController.php +++ b/app/Http/Admin/Controllers/SettingController.php @@ -378,4 +378,30 @@ class SettingController extends Controller } } + /** + * @Route("/dingtalk/robot", name="admin.setting.dingtalk_robot") + */ + public function dingtalkRobotAction() + { + $section = 'dingtalk.robot'; + + $settingService = new SettingService(); + + if ($this->request->isPost()) { + + $data = $this->request->getPost(); + + $settingService->updatePointSettings($section, $data); + + return $this->jsonSuccess(['msg' => '更新配置成功']); + + } else { + + $robot = $settingService->getSettings($section); + + $this->view->pick('setting/dingtalk_robot'); + $this->view->setVar('robot', $robot); + } + } + } diff --git a/app/Http/Admin/Controllers/TestController.php b/app/Http/Admin/Controllers/TestController.php index 4db114d2..d159935d 100644 --- a/app/Http/Admin/Controllers/TestController.php +++ b/app/Http/Admin/Controllers/TestController.php @@ -6,6 +6,7 @@ use App\Http\Admin\Services\AlipayTest as AlipayTestService; use App\Http\Admin\Services\Setting as SettingService; use App\Http\Admin\Services\WxpayTest as WxpayTestService; use App\Services\Captcha as CaptchaService; +use App\Services\DingTalkNotice as DingTalkNoticeService; use App\Services\Live as LiveService; use App\Services\Mail\Test as TestMailService; use App\Services\MyStorage as StorageService; @@ -250,4 +251,20 @@ class TestController extends Controller return $this->jsonSuccess(['status' => $status]); } + /** + * @Post("/dingtalk/robot", name="admin.test.dingtalk_robot") + */ + public function dingTalkRobotAction() + { + $noticeService = new DingTalkNoticeService(); + + $result = $noticeService->test(); + + if ($result) { + return $this->jsonSuccess(['msg' => '发送消息成功,请到钉钉确认']); + } else { + return $this->jsonError(['msg' => '发送消息失败,请检查配置']); + } + } + } \ No newline at end of file diff --git a/app/Http/Admin/Services/AuthNode.php b/app/Http/Admin/Services/AuthNode.php index 20dedbb5..374aa629 100644 --- a/app/Http/Admin/Services/AuthNode.php +++ b/app/Http/Admin/Services/AuthNode.php @@ -800,6 +800,12 @@ class AuthNode extends Service 'type' => 'menu', 'route' => 'admin.setting.wechat_oa', ], + [ + 'id' => '5-1-15', + 'title' => '钉钉机器人', + 'type' => 'menu', + 'route' => 'admin.setting.dingtalk_robot', + ], [ 'id' => '5-1-14', 'title' => '积分设置', diff --git a/app/Http/Admin/Views/setting/dingtalk_robot.volt b/app/Http/Admin/Views/setting/dingtalk_robot.volt new file mode 100644 index 00000000..f243c6c0 --- /dev/null +++ b/app/Http/Admin/Views/setting/dingtalk_robot.volt @@ -0,0 +1,55 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + +
+
+ 钉钉机器人 +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + +
+
+
+ +
+
+ 通知测试 +
+
+ +
+ + +
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/app/Library/Benchmark.php b/app/Library/Benchmark.php new file mode 100644 index 00000000..e6943787 --- /dev/null +++ b/app/Library/Benchmark.php @@ -0,0 +1,27 @@ +startTime = microtime(true); + } + + public function stop() + { + $this->endTime = microtime(true); + } + + public function getElapsedTime() + { + return $this->endTime - $this->startTime; + } + +} \ No newline at end of file diff --git a/app/Library/Helper.php b/app/Library/Helper.php index af1d528a..47363e5c 100644 --- a/app/Library/Helper.php +++ b/app/Library/Helper.php @@ -35,6 +35,24 @@ function kg_substr($str, $start, $length, $suffix = '...') return $str == $result ? $str : $result . $suffix; } +/** + * 占位替换 + * + * @param string $str + * @param array $data + * @return string + */ +function kg_ph_replace($str, $data = []) +{ + if (empty($data)) return $str; + + foreach ($data as $key => $value) { + $str = str_replace('{' . $key . '}', $value, $str); + } + + return $str; +} + /** * uniqid封装 * diff --git a/app/Models/Task.php b/app/Models/Task.php index 58fb19fc..ad9f6953 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -14,10 +14,11 @@ class Task extends Model const TYPE_LUCKY_GIFT_DELIVER = 4; // 抽奖礼品派发 const TYPE_NOTICE_ACCOUNT_LOGIN = 11; // 帐号登录通知 - const TYPE_NOTICE_LIVE_BEGIN = 12; // 直播开始通知 + const TYPE_NOTICE_LIVE_BEGIN = 12; // 直播学员通知 const TYPE_NOTICE_ORDER_FINISH = 13; // 订单完成通知 const TYPE_NOTICE_REFUND_FINISH = 14; // 退款完成通知 const TYPE_NOTICE_CONSULT_REPLY = 15; // 咨询回复通知 + const TYPE_NOTICE_LIVE_TEACHER = 16; // 直播讲师通知 /** * 优先级 diff --git a/app/Services/DingTalk/Notice/ConsultCreate.php b/app/Services/DingTalk/Notice/ConsultCreate.php new file mode 100644 index 00000000..d88d3b24 --- /dev/null +++ b/app/Services/DingTalk/Notice/ConsultCreate.php @@ -0,0 +1,32 @@ +findById($consult->owner_id); + + $courseRepo = new CourseRepo(); + + $course = $courseRepo->findById($consult->course_id); + + $content = kg_ph_replace("{user.name} 对课程:{course.title} 发起了咨询:\n{consult.question}", [ + 'user.name' => $user->name, + 'course.title' => $course->title, + 'consult.question' => $consult->question, + ]); + + $this->atCourseTeacher($course->id, $content); + } + +} \ No newline at end of file diff --git a/app/Services/DingTalk/Notice/CustomService.php b/app/Services/DingTalk/Notice/CustomService.php new file mode 100644 index 00000000..78b870ff --- /dev/null +++ b/app/Services/DingTalk/Notice/CustomService.php @@ -0,0 +1,36 @@ +sender_id}"; + + $cache = $this->getCache(); + + $content = $cache->get($keyName); + + if ($content) return; + + $cache->save($keyName, 1, 3600); + + $userRepo = new UserRepo(); + + $sender = $userRepo->findById($message->sender_id); + + $content = kg_ph_replace("{user} 通过在线客服给你发送了消息:{message}", [ + 'user' => $sender->name, + 'message' => $message->content, + ]); + + $this->atCustomService($content); + } + +} \ No newline at end of file diff --git a/app/Services/DingTalk/Notice/LiveTeacher.php b/app/Services/DingTalk/Notice/LiveTeacher.php new file mode 100644 index 00000000..1e4ce7f8 --- /dev/null +++ b/app/Services/DingTalk/Notice/LiveTeacher.php @@ -0,0 +1,26 @@ +findById($live->course_id); + + $content = kg_ph_replace("课程:{course.title} 计划于 {live.start_time} 开播,不要错过直播时间哦!", [ + 'course.title' => $course->title, + 'live.start_time' => date('Y-m-d H:i', $live->start_time), + ]); + + $this->atCourseTeacher($course->id, $content); + } + +} \ No newline at end of file diff --git a/app/Services/DingTalk/Notice/OrderFinish.php b/app/Services/DingTalk/Notice/OrderFinish.php new file mode 100644 index 00000000..cc360b57 --- /dev/null +++ b/app/Services/DingTalk/Notice/OrderFinish.php @@ -0,0 +1,27 @@ +findById($order->owner_id); + + $text = kg_ph_replace("开单啦,{user.name} 同学完成了订单!\n订单名称:{order.subject}\n订单金额:¥{order.amount}", [ + 'user.name' => $user->name, + 'order.subject' => $order->subject, + 'order.amount' => $order->amount, + ]); + + $this->send(['text' => $text]); + } + +} \ No newline at end of file diff --git a/app/Services/DingTalkNotice.php b/app/Services/DingTalkNotice.php new file mode 100644 index 00000000..fad0c1f0 --- /dev/null +++ b/app/Services/DingTalkNotice.php @@ -0,0 +1,214 @@ +settings = $this->getSettings('dingtalk.robot'); + + $this->logger = $this->getLogger('dingtalk'); + } + + /** + * 测试消息 + * + * @return bool + */ + public function test() + { + $params = [ + 'msgtype' => 'text', + 'text' => ['content' => '我是一条测试消息啦!'], + ]; + + return $this->send($params); + } + + /** + * 给技术人员发消息 + * + * @param string $content + * @return bool + */ + public function atTechSupport($content) + { + $atMobiles = $this->parseAtMobiles($this->settings['ts_mobiles']); + $atContent = $this->buildAtContent($content, $atMobiles); + + $params = [ + 'msgtype' => 'text', + 'text' => ['content' => $atContent], + 'at' => ['atMobiles' => $atMobiles], + ]; + + return $this->send($params); + } + + /** + * 给客服人员发消息 + * + * @param string $content + * @return bool + */ + public function atCustomService($content) + { + $atMobiles = $this->parseAtMobiles($this->settings['cs_mobiles']); + $atContent = $this->buildAtContent($content, $atMobiles); + + $params = [ + 'msgtype' => 'text', + 'text' => ['content' => $atContent], + 'at' => ['atMobiles' => $atMobiles], + ]; + + return $this->send($params); + } + + /** + * 给课程讲师发消息 + * + * @param int $courseId + * @param string $content + * @return bool + */ + public function atCourseTeacher($courseId, $content) + { + $courseRepo = new CourseRepo(); + + $course = $courseRepo->findById($courseId); + + $accountRepo = new AccountRepo(); + + $account = $accountRepo->findById($course->teacher_id); + + if (empty($account->phone)) { + return false; + } + + $atMobiles = $account->phone; + + $atContent = $this->buildAtContent($content, $atMobiles); + + $params = [ + 'msgtype' => 'text', + 'text' => ['content' => $atContent], + 'at' => ['atMobiles' => $atMobiles], + ]; + + return $this->send($params); + } + + /** + * 发送消息 + * + * @param array $params + * @return bool + */ + public function send($params) + { + if (isset($params['msgtype'])) { + $params['msgtype'] = 'text'; + } + + $webHook = "https://oapi.dingtalk.com/robot/send?access_token=%s×tamp=%s&sign=%s"; + + $appSecret = $this->settings['app_secret']; + $appToken = $this->settings['app_token']; + + $timestamp = time() * 1000; + $data = sprintf("%s\n%s", $timestamp, $appSecret); + $sign = urlencode(base64_encode(hash_hmac('sha256', $data, $appSecret, true))); + $postUrl = sprintf($webHook, $appToken, $timestamp, $sign); + + try { + + $client = new HttpClient(); + + $response = $client->post($postUrl, ['json' => $params]); + + $content = $response->getBody()->getContents(); + + $content = json_decode($content, true); + + $this->logger->debug('Send Message Request ' . kg_json_encode($params)); + + $this->logger->debug('Send Message Response ' . kg_json_encode($content)); + + $result = $content['errcode'] == 0; + + if ($result == false) { + $this->logger->error('Send Message Failed ' . kg_json_encode($content)); + } + + } catch (\Exception $e) { + + $this->logger->error('Send Message Exception ' . kg_json_encode([ + 'file' => $e->getFile(), + 'line' => $e->getLine(), + 'message' => $e->getMessage(), + ])); + + $result = false; + } + + return $result; + } + + /** + * @param string $mobiles + * @return array + */ + protected function parseAtMobiles($mobiles) + { + if (empty($mobiles)) { + return []; + } + + $mobiles = explode(',', $mobiles); + + return array_map(function ($mobile) { + return trim($mobile); + }, $mobiles); + } + + /** + * @param string $content + * @param array $mobiles + * @return string + */ + protected function buildAtContent($content, $mobiles = []) + { + if (count($mobiles) == 0) { + return $content; + } + + $result = ''; + + foreach ($mobiles as $mobile) { + $result .= sprintf('@%s ', $mobile); + } + + $result .= $content; + + return $result; + } + +} \ No newline at end of file diff --git a/db/migrations/20210215024511_data_202102151130.php b/db/migrations/20210215024511_data_202102151130.php new file mode 100644 index 00000000..f5fd6419 --- /dev/null +++ b/db/migrations/20210215024511_data_202102151130.php @@ -0,0 +1,42 @@ + 'dingtalk.robot', + 'item_key' => 'app_secret', + 'item_value' => '', + ], + [ + 'section' => 'dingtalk.robot', + 'item_key' => 'app_token', + 'item_value' => '', + ], + [ + 'section' => 'dingtalk.robot', + 'item_key' => 'ts_mobiles', + 'item_value' => '', + ], + [ + 'section' => 'dingtalk.robot', + 'item_key' => 'cs_mobiles', + 'item_value' => '', + ], + ]; + + $this->table('kg_setting')->insert($rows)->save(); + } + + public function down() + { + $this->getQueryBuilder() + ->delete('kg_setting') + ->where(['section' => 'dingtalk.robot']) + ->execute(); + } + +} diff --git a/scheduler.php b/scheduler.php index 666bb7e4..000900f3 100644 --- a/scheduler.php +++ b/scheduler.php @@ -25,6 +25,9 @@ $scheduler->php($script, $bin, ['--task' => 'vod_event', '--action' => 'main']) $scheduler->php($script, $bin, ['--task' => 'close_trade', '--action' => 'main']) ->at('*/13 * * * *'); +$scheduler->php($script, $bin, ['--task' => 'monitor', '--action' => 'main']) + ->at('*/12 * * * *'); + $scheduler->php($script, $bin, ['--task' => 'point_gift_deliver', '--action' => 'main']) ->at('*/11 * * * *'); From d798a5b609cad2d45a14c7abbe626e6006996044 Mon Sep 17 00:00:00 2001 From: koogua Date: Mon, 22 Feb 2021 11:31:21 +0800 Subject: [PATCH 03/10] =?UTF-8?q?dingtalk=E9=80=9A=E7=9F=A5=E9=98=B6?= =?UTF-8?q?=E6=AE=B5=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Console/Tasks/DeliverTask.php | 8 +-- app/Console/Tasks/NoticeTask.php | 54 ++++++++++++-- app/Console/Tasks/OptimizeTableTask.php | 71 +++++++++++++++++++ app/Console/Tasks/PointGiftDeliverTask.php | 11 ++- app/Console/Tasks/RefundTask.php | 11 +-- ...{MonitorTask.php => ServerMonitorTask.php} | 30 +++++--- ...ticeTask.php => TeacherLiveNoticeTask.php} | 24 +++---- .../Admin/Views/setting/dingtalk_robot.volt | 7 ++ app/Http/Home/Controllers/ImController.php | 4 +- app/Http/Home/Services/ImMessageTrait.php | 20 +++++- app/Models/Task.php | 21 +++++- app/Repos/ChapterLive.php | 25 +++++++ .../DingTalk/Notice/ConsultCreate.php | 37 +++++++++- .../DingTalk/Notice/CustomService.php | 41 ++++++++--- app/Services/DingTalk/Notice/LiveTeacher.php | 29 +++++++- app/Services/DingTalk/Notice/OrderFinish.php | 27 ------- app/Services/DingTalk/Notice/PointRedeem.php | 47 ++++++++++++ .../DingTalk/Notice/ServerMonitor.php | 36 ++++++++++ app/Services/Logic/Consult/ConsultCreate.php | 12 ++++ app/Services/Logic/Notice/AccountLogin.php | 1 + app/Services/Logic/Notice/ConsultReply.php | 1 + app/Services/Logic/Notice/LiveBegin.php | 1 + .../20210215024511_data_202102151130.php | 5 ++ .../20210215034511_schema_202102151230.php | 28 ++++++++ public/static/home/js/im.cs.js | 4 +- scheduler.php | 23 ++++-- 26 files changed, 475 insertions(+), 103 deletions(-) create mode 100644 app/Console/Tasks/OptimizeTableTask.php rename app/Console/Tasks/{MonitorTask.php => ServerMonitorTask.php} (84%) rename app/Console/Tasks/{LiveTeacherNoticeTask.php => TeacherLiveNoticeTask.php} (67%) delete mode 100644 app/Services/DingTalk/Notice/OrderFinish.php create mode 100644 app/Services/DingTalk/Notice/PointRedeem.php create mode 100644 app/Services/DingTalk/Notice/ServerMonitor.php create mode 100644 db/migrations/20210215034511_schema_202102151230.php diff --git a/app/Console/Tasks/DeliverTask.php b/app/Console/Tasks/DeliverTask.php index d41a22b7..e15007da 100644 --- a/app/Console/Tasks/DeliverTask.php +++ b/app/Console/Tasks/DeliverTask.php @@ -21,17 +21,13 @@ use Phalcon\Mvc\Model\ResultsetInterface; class DeliverTask extends Task { - const TRY_COUNT = 3; - public function mainAction() { $logger = $this->getLogger('order'); $tasks = $this->findTasks(30); - if ($tasks->count() == 0) { - return; - } + if ($tasks->count() == 0) return; $orderRepo = new OrderRepo(); @@ -84,7 +80,7 @@ class DeliverTask extends Task $task->try_count += 1; $task->priority += 1; - if ($task->try_count > self::TRY_COUNT) { + if ($task->try_count > $task->max_try_count) { $task->status = TaskModel::STATUS_FAILED; } diff --git a/app/Console/Tasks/NoticeTask.php b/app/Console/Tasks/NoticeTask.php index 7d17318d..17613ae7 100644 --- a/app/Console/Tasks/NoticeTask.php +++ b/app/Console/Tasks/NoticeTask.php @@ -3,6 +3,10 @@ namespace App\Console\Tasks; use App\Models\Task as TaskModel; +use App\Services\DingTalk\Notice\ConsultCreate as ConsultCreateNotice; +use App\Services\DingTalk\Notice\CustomService as CustomServiceNotice; +use App\Services\DingTalk\Notice\ServerMonitor as ServerMonitorNotice; +use App\Services\DingTalk\Notice\TeacherLive as TeacherLiveNotice; use App\Services\Logic\Notice\AccountLogin as AccountLoginNotice; use App\Services\Logic\Notice\ConsultReply as ConsultReplyNotice; use App\Services\Logic\Notice\LiveBegin as LiveBeginNotice; @@ -14,8 +18,6 @@ use Phalcon\Mvc\Model\ResultsetInterface; class NoticeTask extends Task { - const TRY_COUNT = 3; - public function mainAction() { $logger = $this->getLogger('notice'); @@ -46,6 +48,18 @@ class NoticeTask extends Task case TaskModel::TYPE_NOTICE_CONSULT_REPLY: $this->handleConsultReplyNotice($task); break; + case TaskModel::TYPE_NOTICE_CONSULT_CREATE: + $this->handleConsultCreateNotice($task); + break; + case TaskModel::TYPE_NOTICE_TEACHER_LIVE: + $this->handleTeacherLiveNotice($task); + break; + case TaskModel::TYPE_NOTICE_SERVER_MONITOR: + $this->handleServerMonitorNotice($task); + break; + case TaskModel::TYPE_NOTICE_CUSTOM_SERVICE: + $this->handleCustomServiceNotice($task); + break; } $task->status = TaskModel::STATUS_FINISHED; @@ -57,7 +71,7 @@ class NoticeTask extends Task $task->try_count += 1; $task->priority += 1; - if ($task->try_count > self::TRY_COUNT) { + if ($task->try_count >= $task->max_try_count) { $task->status = TaskModel::STATUS_FAILED; } @@ -108,11 +122,39 @@ class NoticeTask extends Task return $notice->handleTask($task); } + protected function handleConsultCreateNotice(TaskModel $task) + { + $notice = new ConsultCreateNotice(); + + return $notice->handleTask($task); + } + + protected function handleTeacherLiveNotice(TaskModel $task) + { + $notice = new TeacherLiveNotice(); + + return $notice->handleTask($task); + } + + protected function handleServerMonitorNotice(TaskModel $task) + { + $notice = new ServerMonitorNotice(); + + return $notice->handleTask($task); + } + + protected function handleCustomServiceNotice(TaskModel $task) + { + $notice = new CustomServiceNotice(); + + return $notice->handleTask($task); + } + /** * @param int $limit * @return ResultsetInterface|Resultset|TaskModel[] */ - protected function findTasks($limit = 100) + protected function findTasks($limit = 300) { $itemTypes = [ TaskModel::TYPE_NOTICE_ACCOUNT_LOGIN, @@ -120,6 +162,10 @@ class NoticeTask extends Task TaskModel::TYPE_NOTICE_ORDER_FINISH, TaskModel::TYPE_NOTICE_REFUND_FINISH, TaskModel::TYPE_NOTICE_CONSULT_REPLY, + TaskModel::TYPE_NOTICE_CONSULT_CREATE, + TaskModel::TYPE_NOTICE_TEACHER_LIVE, + TaskModel::TYPE_NOTICE_SERVER_MONITOR, + TaskModel::TYPE_NOTICE_CUSTOM_SERVICE, ]; $status = TaskModel::STATUS_PENDING; diff --git a/app/Console/Tasks/OptimizeTableTask.php b/app/Console/Tasks/OptimizeTableTask.php new file mode 100644 index 00000000..7143c0b7 --- /dev/null +++ b/app/Console/Tasks/OptimizeTableTask.php @@ -0,0 +1,71 @@ +optimizeImMessageTable(); + $this->optimizeLearningTable(); + $this->optimizeTaskTable(); + } + + protected function optimizeImMessageTable() + { + $count = ImMessageModel::count(); + + if ($count < 1000000) return; + + $messageModel = new ImMessageModel(); + + $tableName = $messageModel->getSource(); + + $this->db->delete($tableName, "create_time < :create_time", [ + 'create_time' => strtotime('-6 months'), + ]); + + $this->db->execute("OPTIMIZE TABLE {$tableName}"); + } + + protected function optimizeLearningTable() + { + $count = LearningModel::count(); + + if ($count < 1000000) return; + + $learningModel = new LearningModel(); + + $tableName = $learningModel->getSource(); + + $this->db->delete($tableName, "create_time < :create_time", [ + 'create_time' => strtotime('-6 months'), + ]); + + $this->db->execute("OPTIMIZE TABLE {$tableName}"); + } + + protected function optimizeTaskTable() + { + $count = TaskModel::count(); + + if ($count < 1000000) return; + + $taskModel = new TaskModel(); + + $tableName = $taskModel->getSource(); + + $this->db->delete($tableName, "create_time < :create_time AND status > :status", [ + 'create_time' => strtotime('-6 months'), + 'status' => TaskModel::STATUS_PENDING, + ]); + + $this->db->execute("OPTIMIZE TABLE {$tableName}"); + } + +} \ No newline at end of file diff --git a/app/Console/Tasks/PointGiftDeliverTask.php b/app/Console/Tasks/PointGiftDeliverTask.php index 0f8baac9..1af243e7 100644 --- a/app/Console/Tasks/PointGiftDeliverTask.php +++ b/app/Console/Tasks/PointGiftDeliverTask.php @@ -13,6 +13,7 @@ use App\Repos\ImGroup as ImGroupRepo; use App\Repos\ImGroupUser as ImGroupUserRepo; use App\Repos\PointGift as PointGiftRepo; use App\Repos\PointRedeem as PointRedeemRepo; +use App\Services\DingTalk\Notice\PointRedeem as PointRedeemNotice; use App\Services\Logic\Point\PointHistory as PointHistoryService; use Phalcon\Mvc\Model\Resultset; use Phalcon\Mvc\Model\ResultsetInterface; @@ -20,17 +21,13 @@ use Phalcon\Mvc\Model\ResultsetInterface; class PointGiftDeliverTask extends Task { - const TRY_COUNT = 3; - public function mainAction() { $logger = $this->getLogger('point'); $tasks = $this->findTasks(30); - if ($tasks->count() == 0) { - return; - } + if ($tasks->count() == 0) return; $redeemRepo = new PointRedeemRepo(); @@ -77,7 +74,7 @@ class PointGiftDeliverTask extends Task $task->try_count += 1; $task->priority += 1; - if ($task->try_count > self::TRY_COUNT) { + if ($task->try_count > $task->max_try_count) { $task->status = TaskModel::STATUS_FAILED; } @@ -167,7 +164,9 @@ class PointGiftDeliverTask extends Task protected function handleGoodsRedeem(PointRedeemModel $redeem) { + $notice = new PointRedeemNotice(); + $notice->createTask($redeem); } protected function handleCashRedeem(PointRedeemModel $redeem) diff --git a/app/Console/Tasks/RefundTask.php b/app/Console/Tasks/RefundTask.php index 4abc568e..996dde4b 100644 --- a/app/Console/Tasks/RefundTask.php +++ b/app/Console/Tasks/RefundTask.php @@ -20,20 +20,13 @@ use Phalcon\Mvc\Model\ResultsetInterface; class RefundTask extends Task { - /** - * 重试次数 - */ - const TRY_COUNT = 3; - public function mainAction() { $logger = $this->getLogger('refund'); $tasks = $this->findTasks(30); - if ($tasks->count() == 0) { - return; - } + if ($tasks->count() == 0) return; $tradeRepo = new TradeRepo(); $orderRepo = new OrderRepo(); @@ -103,7 +96,7 @@ class RefundTask extends Task $task->try_count += 1; $task->priority += 1; - if ($task->try_count > self::TRY_COUNT) { + if ($task->try_count > $task->max_try_count) { $task->status = TaskModel::STATUS_FAILED; } diff --git a/app/Console/Tasks/MonitorTask.php b/app/Console/Tasks/ServerMonitorTask.php similarity index 84% rename from app/Console/Tasks/MonitorTask.php rename to app/Console/Tasks/ServerMonitorTask.php index 89481454..7c2f4486 100644 --- a/app/Console/Tasks/MonitorTask.php +++ b/app/Console/Tasks/ServerMonitorTask.php @@ -5,15 +5,19 @@ namespace App\Console\Tasks; use App\Library\Benchmark; use App\Library\Utils\ServerInfo; use App\Models\User as UserModel; -use App\Services\DingTalkNotice; +use App\Services\DingTalk\Notice\ServerMonitor as ServerMonitorNotice; use App\Services\Search\UserSearcher; use GatewayClient\Gateway; -class MonitorTask extends Task +class ServerMonitorTask extends Task { public function mainAction() { + $robot = $this->getSettings('dingtalk.robot'); + + if ($robot['enabled'] == 0) return; + $items = [ 'cpu' => $this->checkCPU(), 'disk' => $this->checkDisk(), @@ -31,20 +35,20 @@ class MonitorTask extends Task if (empty($items)) return; - $notice = new DingTalkNotice(); - $content = implode("\n", $items); - $notice->atTechSupport($content); + $notice = new ServerMonitorNotice(); + + $notice->createTask($content); } protected function checkCPU() { - $coreCount = $this->getCpuCoreCount(); + $coreCount = $this->getCpuCount(); $cpu = ServerInfo::cpu(); - if ($cpu[1] > $coreCount / 2) { + if ($cpu[1] > $coreCount * 0.8) { return sprintf("cpu负载超过%s", $cpu[1]); } } @@ -168,13 +172,19 @@ class MonitorTask extends Task } } - protected function getCpuCoreCount() + protected function getCpuCount() { $cpuInfo = file_get_contents('/proc/cpuinfo'); - preg_match_all('/^processor/m', $cpuInfo, $matches); + preg_match("/^cpu cores\s:\s(\d+)/m", $cpuInfo, $matches); - return count($matches[0]); + $coreCount = intval($matches[1]); + + preg_match_all("/^processor/m", $cpuInfo, $matches); + + $processorCount = count($matches[0]); + + return $coreCount * $processorCount; } } \ No newline at end of file diff --git a/app/Console/Tasks/LiveTeacherNoticeTask.php b/app/Console/Tasks/TeacherLiveNoticeTask.php similarity index 67% rename from app/Console/Tasks/LiveTeacherNoticeTask.php rename to app/Console/Tasks/TeacherLiveNoticeTask.php index 49e25ed7..fac00d68 100644 --- a/app/Console/Tasks/LiveTeacherNoticeTask.php +++ b/app/Console/Tasks/TeacherLiveNoticeTask.php @@ -3,12 +3,12 @@ namespace App\Console\Tasks; use App\Models\ChapterLive as ChapterLiveModel; -use App\Repos\Chapter as ChapterRepo; -use App\Services\DingTalk\Notice\LiveTeacher as LiveTeacherNotice; +use App\Repos\ChapterLive as ChapterLiveRepo; +use App\Services\DingTalk\Notice\TeacherLive as TeacherLiveNotice; use Phalcon\Mvc\Model\Resultset; use Phalcon\Mvc\Model\ResultsetInterface; -class LiveTeacherNoticeTask extends Task +class TeacherLiveNoticeTask extends Task { /** @@ -40,23 +40,23 @@ class LiveTeacherNoticeTask extends Task $keyName = $this->getCacheKeyName(); - $chapterIds = $redis->sMembers($keyName); + $liveIds = $redis->sMembers($keyName); - if (count($chapterIds) == 0) return; + if (count($liveIds) == 0) return; - $chapterRepo = new ChapterRepo(); + $liveRepo = new ChapterLiveRepo(); - $notice = new LiveTeacherNotice(); + $notice = new TeacherLiveNotice(); - foreach ($chapterIds as $chapterId) { + foreach ($liveIds as $liveId) { - $live = $chapterRepo->findChapterLive($chapterId); + $live = $liveRepo->findById($liveId); if ($live->start_time - time() < 30 * 60) { - $notice->handle($live); + $notice->createTask($live); - $redis->sRem($keyName, $chapterId); + $redis->sRem($keyName, $liveId); } } } @@ -75,7 +75,7 @@ class LiveTeacherNoticeTask extends Task protected function getCacheKeyName() { - return 'live_teacher_notice'; + return 'teacher_live_notice_task'; } } \ No newline at end of file diff --git a/app/Http/Admin/Views/setting/dingtalk_robot.volt b/app/Http/Admin/Views/setting/dingtalk_robot.volt index f243c6c0..9d62e7f4 100644 --- a/app/Http/Admin/Views/setting/dingtalk_robot.volt +++ b/app/Http/Admin/Views/setting/dingtalk_robot.volt @@ -6,6 +6,13 @@
钉钉机器人
+
+ +
+ + +
+
diff --git a/app/Http/Home/Controllers/ImController.php b/app/Http/Home/Controllers/ImController.php index 7461363e..133ba5fa 100644 --- a/app/Http/Home/Controllers/ImController.php +++ b/app/Http/Home/Controllers/ImController.php @@ -205,14 +205,14 @@ class ImController extends Controller /** * @Post("/msg/cs/send", name="home.im.send_cs_msg") */ - public function sendCsMessageAction() + public function sendCustomMessageAction() { $from = $this->request->getPost('from', 'string'); $to = $this->request->getPost('to', 'string'); $service = new ImService(); - $service->sendCsMessage($from, $to); + $service->sendCustomMessage($from, $to); return $this->jsonSuccess(); } diff --git a/app/Http/Home/Services/ImMessageTrait.php b/app/Http/Home/Services/ImMessageTrait.php index 5a4842bb..07b33bd7 100644 --- a/app/Http/Home/Services/ImMessageTrait.php +++ b/app/Http/Home/Services/ImMessageTrait.php @@ -11,6 +11,7 @@ use App\Models\ImMessage as ImMessageModel; use App\Repos\ImFriendUser as ImFriendUserRepo; use App\Repos\ImMessage as ImMessageRepo; use App\Repos\ImUser as ImUserRepo; +use App\Services\DingTalk\Notice\CustomService as CustomServiceNotice; use App\Validators\ImFriendUser as ImFriendUserValidator; use App\Validators\ImGroup as ImGroupValidator; use App\Validators\ImGroupUser as ImGroupUserValidator; @@ -22,7 +23,7 @@ use GatewayClient\Gateway; * layim中普通聊天和自定义聊天中接收方用户名使用的字段不一样,也够坑爹的 * 普通聊天username,自定义聊天name */ -Trait ImMessageTrait +trait ImMessageTrait { public function getChatMessages() @@ -166,9 +167,11 @@ Trait ImMessageTrait } $this->eventsManager->fire('ImMessage:afterCreate', $this, $imMessage); + + return $imMessage; } - public function sendCsMessage($from, $to) + public function sendCustomMessage($from, $to) { $validator = new ImMessageValidator(); @@ -214,7 +217,11 @@ Trait ImMessageTrait unset($to['name']); - $this->sendChatMessage($from, $to); + $message = $this->sendChatMessage($from, $to); + + $this->handleCustomServiceNotice($message); + + return $message; } public function pullUnreadFriendMessages($id) @@ -334,4 +341,11 @@ Trait ImMessageTrait $group->update(); } + protected function handleCustomServiceNotice(ImMessageModel $message) + { + $notice = new CustomServiceNotice(); + + $notice->createTask($message); + } + } \ No newline at end of file diff --git a/app/Models/Task.php b/app/Models/Task.php index ad9f6953..10501f83 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -13,12 +13,24 @@ class Task extends Model const TYPE_POINT_GIFT_DELIVER = 3; // 积分礼品派发 const TYPE_LUCKY_GIFT_DELIVER = 4; // 抽奖礼品派发 + /** + * 针对外部用户 + */ const TYPE_NOTICE_ACCOUNT_LOGIN = 11; // 帐号登录通知 const TYPE_NOTICE_LIVE_BEGIN = 12; // 直播学员通知 const TYPE_NOTICE_ORDER_FINISH = 13; // 订单完成通知 const TYPE_NOTICE_REFUND_FINISH = 14; // 退款完成通知 const TYPE_NOTICE_CONSULT_REPLY = 15; // 咨询回复通知 - const TYPE_NOTICE_LIVE_TEACHER = 16; // 直播讲师通知 + + /** + * 针对内部人员 + */ + const TYPE_NOTICE_CONSULT_CREATE = 31; // 咨询创建通知 + const TYPE_NOTICE_TEACHER_LIVE = 32; // 直播讲师通知 + const TYPE_NOTICE_SERVER_MONITOR = 33; // 服务监控通知 + const TYPE_NOTICE_CUSTOM_SERVICE = 34; // 客服消息通知 + const TYPE_NOTICE_POINT_REDEEM = 35; // 积分兑换通知 + const TYPE_NOTICE_LUCKY_REDEEM = 36; // 抽奖兑换通知 /** * 优先级 @@ -84,6 +96,13 @@ class Task extends Model */ public $try_count = 0; + /** + * 最大重试次数 + * + * @var int + */ + public $max_try_count = 3; + /** * 创建时间 * diff --git a/app/Repos/ChapterLive.php b/app/Repos/ChapterLive.php index 6319a384..74d83587 100644 --- a/app/Repos/ChapterLive.php +++ b/app/Repos/ChapterLive.php @@ -5,6 +5,7 @@ namespace App\Repos; use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder; use App\Models\Chapter as ChapterModel; use App\Models\ChapterLive as ChapterLiveModel; +use Phalcon\Mvc\Model; class ChapterLive extends Repository { @@ -54,4 +55,28 @@ class ChapterLive extends Repository return $pager->paginate(); } + /** + * @param int $id + * @return ChapterLiveModel|Model|bool + */ + public function findById($id) + { + return ChapterLiveModel::findFirst([ + 'conditions' => 'id = :id:', + 'bind' => ['id' => $id], + ]); + } + + /** + * @param int $chapterId + * @return ChapterLiveModel|Model|bool + */ + public function findByChapterId($chapterId) + { + return ChapterLiveModel::findFirst([ + 'conditions' => 'chapter_id = :chapter_id:', + 'bind' => ['chapter_id' => $chapterId], + ]); + } + } diff --git a/app/Services/DingTalk/Notice/ConsultCreate.php b/app/Services/DingTalk/Notice/ConsultCreate.php index d88d3b24..7bb9abf3 100644 --- a/app/Services/DingTalk/Notice/ConsultCreate.php +++ b/app/Services/DingTalk/Notice/ConsultCreate.php @@ -3,6 +3,8 @@ namespace App\Services\DingTalk\Notice; use App\Models\Consult as ConsultModel; +use App\Models\Task as TaskModel; +use App\Repos\Consult as ConsultRepo; use App\Repos\Course as CourseRepo; use App\Repos\User as UserRepo; use App\Services\DingTalkNotice; @@ -10,8 +12,12 @@ use App\Services\DingTalkNotice; class ConsultCreate extends DingTalkNotice { - public function handle(ConsultModel $consult) + public function handleTask(TaskModel $task) { + $consultRepo = new ConsultRepo(); + + $consult = $consultRepo->findById($task->item_id); + $userRepo = new UserRepo(); $user = $userRepo->findById($consult->owner_id); @@ -26,7 +32,34 @@ class ConsultCreate extends DingTalkNotice 'consult.question' => $consult->question, ]); - $this->atCourseTeacher($course->id, $content); + return $this->atCourseTeacher($course->id, $content); + } + + public function createTask(ConsultModel $consult) + { + $keyName = "dingtalk_consult_create_notice:{$consult->owner_id}"; + + $cache = $this->getCache(); + + $content = $cache->get($keyName); + + if ($content) return; + + $cache->save($keyName, 1, 3600); + + $task = new TaskModel(); + + $itemInfo = [ + 'consult' => ['id' => $consult->id], + ]; + + $task->item_id = $consult->id; + $task->item_info = $itemInfo; + $task->item_type = TaskModel::TYPE_NOTICE_CONSULT_CREATE; + $task->priority = TaskModel::PRIORITY_LOW; + $task->status = TaskModel::STATUS_PENDING; + + $task->create(); } } \ No newline at end of file diff --git a/app/Services/DingTalk/Notice/CustomService.php b/app/Services/DingTalk/Notice/CustomService.php index 78b870ff..a57483cb 100644 --- a/app/Services/DingTalk/Notice/CustomService.php +++ b/app/Services/DingTalk/Notice/CustomService.php @@ -3,15 +3,35 @@ namespace App\Services\DingTalk\Notice; use App\Models\ImMessage as ImMessageModel; +use App\Models\Task as TaskModel; +use App\Repos\ImMessage as ImMessageRepo; use App\Repos\User as UserRepo; use App\Services\DingTalkNotice; class CustomService extends DingTalkNotice { - public function handle(ImMessageModel $message) + public function handleTask(TaskModel $task) { - $keyName = "dingtalk_cs_notice:{$message->sender_id}"; + $messageRepo = new ImMessageRepo(); + + $message = $messageRepo->findById($task->item_id); + + $userRepo = new UserRepo(); + + $sender = $userRepo->findById($message->sender_id); + + $content = kg_ph_replace("{user.name} 通过在线客服给你发送了消息:{message.content}", [ + 'user.name' => $sender->name, + 'message.content' => $message->content, + ]); + + return $this->atCustomService($content); + } + + public function createTask(ImMessageModel $message) + { + $keyName = "dingtalk_custom_service_notice:{$message->sender_id}"; $cache = $this->getCache(); @@ -21,16 +41,19 @@ class CustomService extends DingTalkNotice $cache->save($keyName, 1, 3600); - $userRepo = new UserRepo(); + $task = new TaskModel(); - $sender = $userRepo->findById($message->sender_id); + $itemInfo = [ + 'im_message' => ['id' => $message->id], + ]; - $content = kg_ph_replace("{user} 通过在线客服给你发送了消息:{message}", [ - 'user' => $sender->name, - 'message' => $message->content, - ]); + $task->item_id = $message->id; + $task->item_info = $itemInfo; + $task->item_type = TaskModel::TYPE_NOTICE_CUSTOM_SERVICE; + $task->priority = TaskModel::PRIORITY_MIDDLE; + $task->status = TaskModel::STATUS_PENDING; - $this->atCustomService($content); + $task->create(); } } \ No newline at end of file diff --git a/app/Services/DingTalk/Notice/LiveTeacher.php b/app/Services/DingTalk/Notice/LiveTeacher.php index 1e4ce7f8..db20b0cb 100644 --- a/app/Services/DingTalk/Notice/LiveTeacher.php +++ b/app/Services/DingTalk/Notice/LiveTeacher.php @@ -3,14 +3,20 @@ namespace App\Services\DingTalk\Notice; use App\Models\ChapterLive as ChapterLiveModel; +use App\Models\Task as TaskModel; +use App\Repos\ChapterLive as ChapterLiveRepo; use App\Repos\Course as CourseRepo; use App\Services\DingTalkNotice; -class LiveTeacher extends DingTalkNotice +class TeacherLive extends DingTalkNotice { - public function handle(ChapterLiveModel $live) + public function handleTask(TaskModel $task) { + $liveRepo = new ChapterLiveRepo(); + + $live = $liveRepo->findById($task->item_id); + $courseRepo = new CourseRepo(); $course = $courseRepo->findById($live->course_id); @@ -20,7 +26,24 @@ class LiveTeacher extends DingTalkNotice 'live.start_time' => date('Y-m-d H:i', $live->start_time), ]); - $this->atCourseTeacher($course->id, $content); + return $this->atCourseTeacher($course->id, $content); + } + + public function createTask(ChapterLiveModel $live) + { + $task = new TaskModel(); + + $itemInfo = [ + 'live' => ['id' => $live->id], + ]; + + $task->item_id = $live->id; + $task->item_info = $itemInfo; + $task->item_type = TaskModel::TYPE_NOTICE_TEACHER_LIVE; + $task->priority = TaskModel::PRIORITY_LOW; + $task->status = TaskModel::STATUS_PENDING; + + $task->create(); } } \ No newline at end of file diff --git a/app/Services/DingTalk/Notice/OrderFinish.php b/app/Services/DingTalk/Notice/OrderFinish.php deleted file mode 100644 index cc360b57..00000000 --- a/app/Services/DingTalk/Notice/OrderFinish.php +++ /dev/null @@ -1,27 +0,0 @@ -findById($order->owner_id); - - $text = kg_ph_replace("开单啦,{user.name} 同学完成了订单!\n订单名称:{order.subject}\n订单金额:¥{order.amount}", [ - 'user.name' => $user->name, - 'order.subject' => $order->subject, - 'order.amount' => $order->amount, - ]); - - $this->send(['text' => $text]); - } - -} \ No newline at end of file diff --git a/app/Services/DingTalk/Notice/PointRedeem.php b/app/Services/DingTalk/Notice/PointRedeem.php new file mode 100644 index 00000000..791db8b1 --- /dev/null +++ b/app/Services/DingTalk/Notice/PointRedeem.php @@ -0,0 +1,47 @@ +findById($task->item_id); + + $content = kg_ph_replace("{user.name} 兑换了商品 {gift.name},不要忘记发货哦!", [ + 'user.name' => $redeem->user_name, + 'gift.name' => $redeem->gift_name, + ]); + + return $this->atCustomService($content); + } + + public function createTask(PointRedeemModel $redeem) + { + if ($redeem->gift_type != PointGiftModel::TYPE_GOODS) return; + + $task = new TaskModel(); + + $itemInfo = [ + 'point_redeem' => ['id' => $redeem->id], + ]; + + $task->item_id = $redeem->id; + $task->item_info = $itemInfo; + $task->item_type = TaskModel::TYPE_NOTICE_POINT_REDEEM; + $task->priority = TaskModel::PRIORITY_MIDDLE; + $task->status = TaskModel::STATUS_PENDING; + + $task->create(); + } + +} \ No newline at end of file diff --git a/app/Services/DingTalk/Notice/ServerMonitor.php b/app/Services/DingTalk/Notice/ServerMonitor.php new file mode 100644 index 00000000..3901bafc --- /dev/null +++ b/app/Services/DingTalk/Notice/ServerMonitor.php @@ -0,0 +1,36 @@ +item_info['content']; + + return $notice->atTechSupport($content); + } + + public function createTask($content) + { + $task = new TaskModel(); + + $itemInfo = ['content' => $content]; + + $task->item_id = time(); + $task->item_info = $itemInfo; + $task->item_type = TaskModel::TYPE_NOTICE_SERVER_MONITOR; + $task->priority = TaskModel::PRIORITY_HIGH; + $task->status = TaskModel::STATUS_PENDING; + $task->max_try_count = 1; + + $task->create(); + } + +} \ No newline at end of file diff --git a/app/Services/Logic/Consult/ConsultCreate.php b/app/Services/Logic/Consult/ConsultCreate.php index 369fd19a..2ec411dd 100644 --- a/app/Services/Logic/Consult/ConsultCreate.php +++ b/app/Services/Logic/Consult/ConsultCreate.php @@ -6,6 +6,7 @@ use App\Models\Chapter as ChapterModel; use App\Models\Consult as ConsultModel; use App\Models\Course as CourseModel; use App\Models\User as UserModel; +use App\Services\DingTalk\Notice\ConsultCreate as ConsultCreateNotice; use App\Services\Logic\ChapterTrait; use App\Services\Logic\CourseTrait; use App\Services\Logic\Service; @@ -75,6 +76,8 @@ class ConsultCreate extends Service $this->incrUserDailyConsultCount($user); + $this->handleConsultCreateNotice($consult); + return $consult; } @@ -111,6 +114,8 @@ class ConsultCreate extends Service $this->incrUserDailyConsultCount($user); + $this->handleConsultCreateNotice($consult); + return $consult; } @@ -150,4 +155,11 @@ class ConsultCreate extends Service $this->eventsManager->fire('UserDailyCounter:incrConsultCount', $this, $user); } + protected function handleConsultCreateNotice(ConsultModel $consult) + { + $notice = new ConsultCreateNotice(); + + $notice->createTask($consult); + } + } diff --git a/app/Services/Logic/Notice/AccountLogin.php b/app/Services/Logic/Notice/AccountLogin.php index 6ae4b18f..9f4fdd06 100644 --- a/app/Services/Logic/Notice/AccountLogin.php +++ b/app/Services/Logic/Notice/AccountLogin.php @@ -54,6 +54,7 @@ class AccountLogin extends LogicService $task->item_type = TaskModel::TYPE_NOTICE_ACCOUNT_LOGIN; $task->priority = TaskModel::PRIORITY_LOW; $task->status = TaskModel::STATUS_PENDING; + $task->max_try_count = 1; $task->create(); } diff --git a/app/Services/Logic/Notice/ConsultReply.php b/app/Services/Logic/Notice/ConsultReply.php index 3b77f7c1..34cfaebc 100644 --- a/app/Services/Logic/Notice/ConsultReply.php +++ b/app/Services/Logic/Notice/ConsultReply.php @@ -86,6 +86,7 @@ class ConsultReply extends LogicService $task->item_type = TaskModel::TYPE_NOTICE_CONSULT_REPLY; $task->priority = TaskModel::PRIORITY_LOW; $task->status = TaskModel::STATUS_PENDING; + $task->max_try_count = 1; $task->create(); } diff --git a/app/Services/Logic/Notice/LiveBegin.php b/app/Services/Logic/Notice/LiveBegin.php index f125c56c..a0818d54 100644 --- a/app/Services/Logic/Notice/LiveBegin.php +++ b/app/Services/Logic/Notice/LiveBegin.php @@ -92,6 +92,7 @@ class LiveBegin extends LogicService $task->item_type = TaskModel::TYPE_NOTICE_LIVE_BEGIN; $task->priority = TaskModel::PRIORITY_LOW; $task->status = TaskModel::STATUS_PENDING; + $task->max_try_count = 1; $task->create(); } diff --git a/db/migrations/20210215024511_data_202102151130.php b/db/migrations/20210215024511_data_202102151130.php index f5fd6419..e2d0fde5 100644 --- a/db/migrations/20210215024511_data_202102151130.php +++ b/db/migrations/20210215024511_data_202102151130.php @@ -6,6 +6,11 @@ class Data202102151130 extends Phinx\Migration\AbstractMigration public function up() { $rows = [ + [ + 'section' => 'dingtalk.robot', + 'item_key' => 'enabled', + 'item_value' => '0', + ], [ 'section' => 'dingtalk.robot', 'item_key' => 'app_secret', diff --git a/db/migrations/20210215034511_schema_202102151230.php b/db/migrations/20210215034511_schema_202102151230.php new file mode 100644 index 00000000..77b94e12 --- /dev/null +++ b/db/migrations/20210215034511_schema_202102151230.php @@ -0,0 +1,28 @@ +table('kg_task') + ->addColumn('max_try_count', 'integer', [ + 'null' => false, + 'default' => '0', + 'limit' => MysqlAdapter::INT_REGULAR, + 'signed' => false, + 'comment' => '最大尝试数', + 'after' => 'try_count', + ])->save(); + } + + public function down() + { + $this->table('kg_task') + ->removeColumn('max_try_count') + ->save(); + } + +} diff --git a/public/static/home/js/im.cs.js b/public/static/home/js/im.cs.js index 06c7727d..f86c831f 100644 --- a/public/static/home/js/im.cs.js +++ b/public/static/home/js/im.cs.js @@ -64,7 +64,7 @@ layui.use(['jquery', 'layim'], function () { }); layim.on('sendMessage', function (res) { - sendCsMessage(res); + sendCustomMessage(res); }); showWelcomeMessage(csUser); @@ -77,7 +77,7 @@ layui.use(['jquery', 'layim'], function () { }); } - function sendCsMessage(res) { + function sendCustomMessage(res) { $.ajax({ type: 'POST', url: '/im/msg/cs/send', diff --git a/scheduler.php b/scheduler.php index 000900f3..253ad168 100644 --- a/scheduler.php +++ b/scheduler.php @@ -16,21 +16,24 @@ $scheduler->php($script, $bin, ['--task' => 'deliver', '--action' => 'main']) $scheduler->php($script, $bin, ['--task' => 'notice', '--action' => 'main']) ->at('*/3 * * * *'); -$scheduler->php($script, $bin, ['--task' => 'sync_learning', '--action' => 'main']) - ->at('*/7 * * * *'); - $scheduler->php($script, $bin, ['--task' => 'vod_event', '--action' => 'main']) ->at('*/5 * * * *'); -$scheduler->php($script, $bin, ['--task' => 'close_trade', '--action' => 'main']) - ->at('*/13 * * * *'); +$scheduler->php($script, $bin, ['--task' => 'sync_learning', '--action' => 'main']) + ->at('*/7 * * * *'); -$scheduler->php($script, $bin, ['--task' => 'monitor', '--action' => 'main']) - ->at('*/12 * * * *'); +$scheduler->php($script, $bin, ['--task' => 'teacher_live_notice', '--action' => 'consume']) + ->at('*/10 * * * *'); $scheduler->php($script, $bin, ['--task' => 'point_gift_deliver', '--action' => 'main']) ->at('*/11 * * * *'); +$scheduler->php($script, $bin, ['--task' => 'server_monitor', '--action' => 'main']) + ->at('*/12 * * * *'); + +$scheduler->php($script, $bin, ['--task' => 'close_trade', '--action' => 'main']) + ->at('*/13 * * * *'); + $scheduler->php($script, $bin, ['--task' => 'close_order', '--action' => 'main']) ->hourly(3); @@ -61,4 +64,10 @@ $scheduler->php($script, $bin, ['--task' => 'revoke_vip', '--action' => 'main']) $scheduler->php($script, $bin, ['--task' => 'sitemap', '--action' => 'main']) ->daily(4, 3); +$scheduler->php($script, $bin, ['--task' => 'teacher_live_notice', '--action' => 'provide']) + ->daily(4, 7); + +$scheduler->php($script, $bin, ['--task' => 'optimize_table', '--action' => 'main']) + ->weekly(6, 5, 3); + $scheduler->run(); \ No newline at end of file From 7acfaf17a96319f78933289845befa4ef588b8d6 Mon Sep 17 00:00:00 2001 From: koogua Date: Mon, 22 Feb 2021 11:31:21 +0800 Subject: [PATCH 04/10] =?UTF-8?q?dingtalk=E9=80=9A=E7=9F=A5=E9=98=B6?= =?UTF-8?q?=E6=AE=B5=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Console/Tasks/DeliverTask.php | 8 +- app/Console/Tasks/NoticeTask.php | 54 ++++- app/Console/Tasks/OptimizeTableTask.php | 71 +++++++ app/Console/Tasks/PointGiftDeliverTask.php | 11 +- app/Console/Tasks/RefundTask.php | 11 +- app/Console/Tasks/ServerMonitorTask.php | 190 ++++++++++++++++++ app/Console/Tasks/TeacherLiveNoticeTask.php | 81 ++++++++ .../Admin/Views/setting/dingtalk_robot.volt | 62 ++++++ app/Http/Home/Controllers/ImController.php | 4 +- app/Http/Home/Services/ImMessageTrait.php | 20 +- app/Models/Task.php | 20 ++ app/Repos/ChapterLive.php | 25 +++ .../DingTalk/Notice/ConsultCreate.php | 65 ++++++ .../DingTalk/Notice/CustomService.php | 59 ++++++ app/Services/DingTalk/Notice/LiveTeacher.php | 49 +++++ app/Services/DingTalk/Notice/PointRedeem.php | 47 +++++ .../DingTalk/Notice/ServerMonitor.php | 36 ++++ app/Services/Logic/Consult/ConsultCreate.php | 12 ++ app/Services/Logic/Notice/AccountLogin.php | 1 + app/Services/Logic/Notice/ConsultReply.php | 1 + app/Services/Logic/Notice/LiveBegin.php | 1 + .../20210215024511_data_202102151130.php | 47 +++++ .../20210215034511_schema_202102151230.php | 28 +++ public/static/home/js/im.cs.js | 4 +- scheduler.php | 22 +- 25 files changed, 892 insertions(+), 37 deletions(-) create mode 100644 app/Console/Tasks/OptimizeTableTask.php create mode 100644 app/Console/Tasks/ServerMonitorTask.php create mode 100644 app/Console/Tasks/TeacherLiveNoticeTask.php create mode 100644 app/Http/Admin/Views/setting/dingtalk_robot.volt create mode 100644 app/Services/DingTalk/Notice/ConsultCreate.php create mode 100644 app/Services/DingTalk/Notice/CustomService.php create mode 100644 app/Services/DingTalk/Notice/LiveTeacher.php create mode 100644 app/Services/DingTalk/Notice/PointRedeem.php create mode 100644 app/Services/DingTalk/Notice/ServerMonitor.php create mode 100644 db/migrations/20210215024511_data_202102151130.php create mode 100644 db/migrations/20210215034511_schema_202102151230.php diff --git a/app/Console/Tasks/DeliverTask.php b/app/Console/Tasks/DeliverTask.php index d41a22b7..e15007da 100644 --- a/app/Console/Tasks/DeliverTask.php +++ b/app/Console/Tasks/DeliverTask.php @@ -21,17 +21,13 @@ use Phalcon\Mvc\Model\ResultsetInterface; class DeliverTask extends Task { - const TRY_COUNT = 3; - public function mainAction() { $logger = $this->getLogger('order'); $tasks = $this->findTasks(30); - if ($tasks->count() == 0) { - return; - } + if ($tasks->count() == 0) return; $orderRepo = new OrderRepo(); @@ -84,7 +80,7 @@ class DeliverTask extends Task $task->try_count += 1; $task->priority += 1; - if ($task->try_count > self::TRY_COUNT) { + if ($task->try_count > $task->max_try_count) { $task->status = TaskModel::STATUS_FAILED; } diff --git a/app/Console/Tasks/NoticeTask.php b/app/Console/Tasks/NoticeTask.php index 7d17318d..17613ae7 100644 --- a/app/Console/Tasks/NoticeTask.php +++ b/app/Console/Tasks/NoticeTask.php @@ -3,6 +3,10 @@ namespace App\Console\Tasks; use App\Models\Task as TaskModel; +use App\Services\DingTalk\Notice\ConsultCreate as ConsultCreateNotice; +use App\Services\DingTalk\Notice\CustomService as CustomServiceNotice; +use App\Services\DingTalk\Notice\ServerMonitor as ServerMonitorNotice; +use App\Services\DingTalk\Notice\TeacherLive as TeacherLiveNotice; use App\Services\Logic\Notice\AccountLogin as AccountLoginNotice; use App\Services\Logic\Notice\ConsultReply as ConsultReplyNotice; use App\Services\Logic\Notice\LiveBegin as LiveBeginNotice; @@ -14,8 +18,6 @@ use Phalcon\Mvc\Model\ResultsetInterface; class NoticeTask extends Task { - const TRY_COUNT = 3; - public function mainAction() { $logger = $this->getLogger('notice'); @@ -46,6 +48,18 @@ class NoticeTask extends Task case TaskModel::TYPE_NOTICE_CONSULT_REPLY: $this->handleConsultReplyNotice($task); break; + case TaskModel::TYPE_NOTICE_CONSULT_CREATE: + $this->handleConsultCreateNotice($task); + break; + case TaskModel::TYPE_NOTICE_TEACHER_LIVE: + $this->handleTeacherLiveNotice($task); + break; + case TaskModel::TYPE_NOTICE_SERVER_MONITOR: + $this->handleServerMonitorNotice($task); + break; + case TaskModel::TYPE_NOTICE_CUSTOM_SERVICE: + $this->handleCustomServiceNotice($task); + break; } $task->status = TaskModel::STATUS_FINISHED; @@ -57,7 +71,7 @@ class NoticeTask extends Task $task->try_count += 1; $task->priority += 1; - if ($task->try_count > self::TRY_COUNT) { + if ($task->try_count >= $task->max_try_count) { $task->status = TaskModel::STATUS_FAILED; } @@ -108,11 +122,39 @@ class NoticeTask extends Task return $notice->handleTask($task); } + protected function handleConsultCreateNotice(TaskModel $task) + { + $notice = new ConsultCreateNotice(); + + return $notice->handleTask($task); + } + + protected function handleTeacherLiveNotice(TaskModel $task) + { + $notice = new TeacherLiveNotice(); + + return $notice->handleTask($task); + } + + protected function handleServerMonitorNotice(TaskModel $task) + { + $notice = new ServerMonitorNotice(); + + return $notice->handleTask($task); + } + + protected function handleCustomServiceNotice(TaskModel $task) + { + $notice = new CustomServiceNotice(); + + return $notice->handleTask($task); + } + /** * @param int $limit * @return ResultsetInterface|Resultset|TaskModel[] */ - protected function findTasks($limit = 100) + protected function findTasks($limit = 300) { $itemTypes = [ TaskModel::TYPE_NOTICE_ACCOUNT_LOGIN, @@ -120,6 +162,10 @@ class NoticeTask extends Task TaskModel::TYPE_NOTICE_ORDER_FINISH, TaskModel::TYPE_NOTICE_REFUND_FINISH, TaskModel::TYPE_NOTICE_CONSULT_REPLY, + TaskModel::TYPE_NOTICE_CONSULT_CREATE, + TaskModel::TYPE_NOTICE_TEACHER_LIVE, + TaskModel::TYPE_NOTICE_SERVER_MONITOR, + TaskModel::TYPE_NOTICE_CUSTOM_SERVICE, ]; $status = TaskModel::STATUS_PENDING; diff --git a/app/Console/Tasks/OptimizeTableTask.php b/app/Console/Tasks/OptimizeTableTask.php new file mode 100644 index 00000000..7143c0b7 --- /dev/null +++ b/app/Console/Tasks/OptimizeTableTask.php @@ -0,0 +1,71 @@ +optimizeImMessageTable(); + $this->optimizeLearningTable(); + $this->optimizeTaskTable(); + } + + protected function optimizeImMessageTable() + { + $count = ImMessageModel::count(); + + if ($count < 1000000) return; + + $messageModel = new ImMessageModel(); + + $tableName = $messageModel->getSource(); + + $this->db->delete($tableName, "create_time < :create_time", [ + 'create_time' => strtotime('-6 months'), + ]); + + $this->db->execute("OPTIMIZE TABLE {$tableName}"); + } + + protected function optimizeLearningTable() + { + $count = LearningModel::count(); + + if ($count < 1000000) return; + + $learningModel = new LearningModel(); + + $tableName = $learningModel->getSource(); + + $this->db->delete($tableName, "create_time < :create_time", [ + 'create_time' => strtotime('-6 months'), + ]); + + $this->db->execute("OPTIMIZE TABLE {$tableName}"); + } + + protected function optimizeTaskTable() + { + $count = TaskModel::count(); + + if ($count < 1000000) return; + + $taskModel = new TaskModel(); + + $tableName = $taskModel->getSource(); + + $this->db->delete($tableName, "create_time < :create_time AND status > :status", [ + 'create_time' => strtotime('-6 months'), + 'status' => TaskModel::STATUS_PENDING, + ]); + + $this->db->execute("OPTIMIZE TABLE {$tableName}"); + } + +} \ No newline at end of file diff --git a/app/Console/Tasks/PointGiftDeliverTask.php b/app/Console/Tasks/PointGiftDeliverTask.php index 0f8baac9..1af243e7 100644 --- a/app/Console/Tasks/PointGiftDeliverTask.php +++ b/app/Console/Tasks/PointGiftDeliverTask.php @@ -13,6 +13,7 @@ use App\Repos\ImGroup as ImGroupRepo; use App\Repos\ImGroupUser as ImGroupUserRepo; use App\Repos\PointGift as PointGiftRepo; use App\Repos\PointRedeem as PointRedeemRepo; +use App\Services\DingTalk\Notice\PointRedeem as PointRedeemNotice; use App\Services\Logic\Point\PointHistory as PointHistoryService; use Phalcon\Mvc\Model\Resultset; use Phalcon\Mvc\Model\ResultsetInterface; @@ -20,17 +21,13 @@ use Phalcon\Mvc\Model\ResultsetInterface; class PointGiftDeliverTask extends Task { - const TRY_COUNT = 3; - public function mainAction() { $logger = $this->getLogger('point'); $tasks = $this->findTasks(30); - if ($tasks->count() == 0) { - return; - } + if ($tasks->count() == 0) return; $redeemRepo = new PointRedeemRepo(); @@ -77,7 +74,7 @@ class PointGiftDeliverTask extends Task $task->try_count += 1; $task->priority += 1; - if ($task->try_count > self::TRY_COUNT) { + if ($task->try_count > $task->max_try_count) { $task->status = TaskModel::STATUS_FAILED; } @@ -167,7 +164,9 @@ class PointGiftDeliverTask extends Task protected function handleGoodsRedeem(PointRedeemModel $redeem) { + $notice = new PointRedeemNotice(); + $notice->createTask($redeem); } protected function handleCashRedeem(PointRedeemModel $redeem) diff --git a/app/Console/Tasks/RefundTask.php b/app/Console/Tasks/RefundTask.php index 41e04a51..9689542c 100644 --- a/app/Console/Tasks/RefundTask.php +++ b/app/Console/Tasks/RefundTask.php @@ -20,20 +20,13 @@ use Phalcon\Mvc\Model\ResultsetInterface; class RefundTask extends Task { - /** - * 重试次数 - */ - const TRY_COUNT = 3; - public function mainAction() { $logger = $this->getLogger('refund'); $tasks = $this->findTasks(30); - if ($tasks->count() == 0) { - return; - } + if ($tasks->count() == 0) return; $tradeRepo = new TradeRepo(); $orderRepo = new OrderRepo(); @@ -96,7 +89,7 @@ class RefundTask extends Task $task->try_count += 1; $task->priority += 1; - if ($task->try_count > self::TRY_COUNT) { + if ($task->try_count > $task->max_try_count) { $task->status = TaskModel::STATUS_FAILED; } diff --git a/app/Console/Tasks/ServerMonitorTask.php b/app/Console/Tasks/ServerMonitorTask.php new file mode 100644 index 00000000..7c2f4486 --- /dev/null +++ b/app/Console/Tasks/ServerMonitorTask.php @@ -0,0 +1,190 @@ +getSettings('dingtalk.robot'); + + if ($robot['enabled'] == 0) return; + + $items = [ + 'cpu' => $this->checkCPU(), + 'disk' => $this->checkDisk(), + 'mysql' => $this->checkMysql(), + 'redis' => $this->checkRedis(), + 'xunsearch' => $this->checkXunSearch(), + 'websocket' => $this->checkWebSocket(), + ]; + + foreach ($items as $key => $value) { + if (empty($value)) { + unset($items[$key]); + } + } + + if (empty($items)) return; + + $content = implode("\n", $items); + + $notice = new ServerMonitorNotice(); + + $notice->createTask($content); + } + + protected function checkCPU() + { + $coreCount = $this->getCpuCount(); + + $cpu = ServerInfo::cpu(); + + if ($cpu[1] > $coreCount * 0.8) { + return sprintf("cpu负载超过%s", $cpu[1]); + } + } + + protected function checkDisk() + { + $disk = ServerInfo::disk(); + + if ($disk['percent'] > 80) { + return sprintf("disk空间超过%s%%", $disk['percent']); + } + } + + protected function checkMysql() + { + try { + + $benchmark = new Benchmark(); + + $benchmark->start(); + + $user = UserModel::findFirst(); + + $benchmark->stop(); + + $elapsedTime = $benchmark->getElapsedTime(); + + if ($user === false) { + return sprintf("mysql查询失败"); + } + + if ($elapsedTime > 1) { + return sprintf("mysql查询响应超过%s秒", round($elapsedTime, 2)); + } + + } catch (\Exception $e) { + return sprintf("mysql可能存在异常"); + } + } + + protected function checkRedis() + { + try { + + $benchmark = new Benchmark(); + + $benchmark->start(); + + $site = $this->getSettings('site'); + + $benchmark->stop(); + + $elapsedTime = $benchmark->getElapsedTime(); + + if (empty($site)) { + return sprintf("redis查询失败"); + } + + if ($elapsedTime > 1) { + return sprintf("redis查询响应超过%s秒", round($elapsedTime, 2)); + } + + } catch (\Exception $e) { + return sprintf("redis可能存在异常"); + } + } + + protected function checkXunSearch() + { + try { + + $benchmark = new Benchmark(); + + $benchmark->start(); + + $searcher = new UserSearcher(); + + $user = $searcher->search('id:10000'); + + $benchmark->stop(); + + $elapsedTime = $benchmark->getElapsedTime(); + + if (empty($user)) { + return sprintf("xunsearch搜索失败"); + } + + if ($elapsedTime > 1) { + return sprintf("xunsearch搜索响应超过%s秒", round($elapsedTime, 2)); + } + + } catch (\Exception $e) { + return sprintf("xunsearch可能存在异常"); + } + } + + protected function checkWebSocket() + { + try { + + $benchmark = new Benchmark(); + + $config = $this->getConfig(); + + Gateway::$registerAddress = $config->path('websocket.register_address'); + + $benchmark->start(); + + Gateway::isUidOnline(10000); + + $benchmark->stop(); + + $elapsedTime = $benchmark->getElapsedTime(); + + if ($elapsedTime > 1) { + return sprintf("websocket响应超过%s秒", round($elapsedTime, 2)); + } + + } catch (\Exception $e) { + return sprintf("websocket可能存在异常"); + } + } + + protected function getCpuCount() + { + $cpuInfo = file_get_contents('/proc/cpuinfo'); + + preg_match("/^cpu cores\s:\s(\d+)/m", $cpuInfo, $matches); + + $coreCount = intval($matches[1]); + + preg_match_all("/^processor/m", $cpuInfo, $matches); + + $processorCount = count($matches[0]); + + return $coreCount * $processorCount; + } + +} \ No newline at end of file diff --git a/app/Console/Tasks/TeacherLiveNoticeTask.php b/app/Console/Tasks/TeacherLiveNoticeTask.php new file mode 100644 index 00000000..fac00d68 --- /dev/null +++ b/app/Console/Tasks/TeacherLiveNoticeTask.php @@ -0,0 +1,81 @@ +findLives(); + + if ($lives->count() == 0) return; + + $redis = $this->getRedis(); + + $keyName = $this->getCacheKeyName(); + + foreach ($lives as $live) { + $redis->sAdd($keyName, $live->chapter_id); + } + + $redis->expire($keyName, 86400); + } + + /** + * 消费讲师提醒 + */ + public function consumeAction() + { + $redis = $this->getRedis(); + + $keyName = $this->getCacheKeyName(); + + $liveIds = $redis->sMembers($keyName); + + if (count($liveIds) == 0) return; + + $liveRepo = new ChapterLiveRepo(); + + $notice = new TeacherLiveNotice(); + + foreach ($liveIds as $liveId) { + + $live = $liveRepo->findById($liveId); + + if ($live->start_time - time() < 30 * 60) { + + $notice->createTask($live); + + $redis->sRem($keyName, $liveId); + } + } + } + + /** + * @return ResultsetInterface|Resultset|ChapterLiveModel[] + */ + protected function findLives() + { + $today = strtotime(date('Ymd')); + + return ChapterLiveModel::query() + ->betweenWhere('start_time', $today, $today + 86400) + ->execute(); + } + + protected function getCacheKeyName() + { + return 'teacher_live_notice_task'; + } + +} \ No newline at end of file diff --git a/app/Http/Admin/Views/setting/dingtalk_robot.volt b/app/Http/Admin/Views/setting/dingtalk_robot.volt new file mode 100644 index 00000000..9d62e7f4 --- /dev/null +++ b/app/Http/Admin/Views/setting/dingtalk_robot.volt @@ -0,0 +1,62 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + +
+
+ 钉钉机器人 +
+
+ +
+ + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + +
+
+
+ +
+
+ 通知测试 +
+
+ +
+ + +
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/app/Http/Home/Controllers/ImController.php b/app/Http/Home/Controllers/ImController.php index 7461363e..133ba5fa 100644 --- a/app/Http/Home/Controllers/ImController.php +++ b/app/Http/Home/Controllers/ImController.php @@ -205,14 +205,14 @@ class ImController extends Controller /** * @Post("/msg/cs/send", name="home.im.send_cs_msg") */ - public function sendCsMessageAction() + public function sendCustomMessageAction() { $from = $this->request->getPost('from', 'string'); $to = $this->request->getPost('to', 'string'); $service = new ImService(); - $service->sendCsMessage($from, $to); + $service->sendCustomMessage($from, $to); return $this->jsonSuccess(); } diff --git a/app/Http/Home/Services/ImMessageTrait.php b/app/Http/Home/Services/ImMessageTrait.php index 5a4842bb..07b33bd7 100644 --- a/app/Http/Home/Services/ImMessageTrait.php +++ b/app/Http/Home/Services/ImMessageTrait.php @@ -11,6 +11,7 @@ use App\Models\ImMessage as ImMessageModel; use App\Repos\ImFriendUser as ImFriendUserRepo; use App\Repos\ImMessage as ImMessageRepo; use App\Repos\ImUser as ImUserRepo; +use App\Services\DingTalk\Notice\CustomService as CustomServiceNotice; use App\Validators\ImFriendUser as ImFriendUserValidator; use App\Validators\ImGroup as ImGroupValidator; use App\Validators\ImGroupUser as ImGroupUserValidator; @@ -22,7 +23,7 @@ use GatewayClient\Gateway; * layim中普通聊天和自定义聊天中接收方用户名使用的字段不一样,也够坑爹的 * 普通聊天username,自定义聊天name */ -Trait ImMessageTrait +trait ImMessageTrait { public function getChatMessages() @@ -166,9 +167,11 @@ Trait ImMessageTrait } $this->eventsManager->fire('ImMessage:afterCreate', $this, $imMessage); + + return $imMessage; } - public function sendCsMessage($from, $to) + public function sendCustomMessage($from, $to) { $validator = new ImMessageValidator(); @@ -214,7 +217,11 @@ Trait ImMessageTrait unset($to['name']); - $this->sendChatMessage($from, $to); + $message = $this->sendChatMessage($from, $to); + + $this->handleCustomServiceNotice($message); + + return $message; } public function pullUnreadFriendMessages($id) @@ -334,4 +341,11 @@ Trait ImMessageTrait $group->update(); } + protected function handleCustomServiceNotice(ImMessageModel $message) + { + $notice = new CustomServiceNotice(); + + $notice->createTask($message); + } + } \ No newline at end of file diff --git a/app/Models/Task.php b/app/Models/Task.php index 77839de6..de8cb067 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -13,12 +13,25 @@ class Task extends Model const TYPE_POINT_GIFT_DELIVER = 3; // 积分礼品派发 const TYPE_LUCKY_GIFT_DELIVER = 4; // 抽奖礼品派发 + /** + * 针对外部用户 + */ const TYPE_NOTICE_ACCOUNT_LOGIN = 11; // 帐号登录通知 const TYPE_NOTICE_LIVE_BEGIN = 12; // 直播开始通知 const TYPE_NOTICE_ORDER_FINISH = 13; // 订单完成通知 const TYPE_NOTICE_REFUND_FINISH = 14; // 退款完成通知 const TYPE_NOTICE_CONSULT_REPLY = 15; // 咨询回复通知 + /** + * 针对内部人员 + */ + const TYPE_NOTICE_CONSULT_CREATE = 31; // 咨询创建通知 + const TYPE_NOTICE_TEACHER_LIVE = 32; // 直播讲师通知 + const TYPE_NOTICE_SERVER_MONITOR = 33; // 服务监控通知 + const TYPE_NOTICE_CUSTOM_SERVICE = 34; // 客服消息通知 + const TYPE_NOTICE_POINT_REDEEM = 35; // 积分兑换通知 + const TYPE_NOTICE_LUCKY_REDEEM = 36; // 抽奖兑换通知 + /** * 优先级 */ @@ -83,6 +96,13 @@ class Task extends Model */ public $try_count = 0; + /** + * 最大重试次数 + * + * @var int + */ + public $max_try_count = 3; + /** * 创建时间 * diff --git a/app/Repos/ChapterLive.php b/app/Repos/ChapterLive.php index 6319a384..74d83587 100644 --- a/app/Repos/ChapterLive.php +++ b/app/Repos/ChapterLive.php @@ -5,6 +5,7 @@ namespace App\Repos; use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder; use App\Models\Chapter as ChapterModel; use App\Models\ChapterLive as ChapterLiveModel; +use Phalcon\Mvc\Model; class ChapterLive extends Repository { @@ -54,4 +55,28 @@ class ChapterLive extends Repository return $pager->paginate(); } + /** + * @param int $id + * @return ChapterLiveModel|Model|bool + */ + public function findById($id) + { + return ChapterLiveModel::findFirst([ + 'conditions' => 'id = :id:', + 'bind' => ['id' => $id], + ]); + } + + /** + * @param int $chapterId + * @return ChapterLiveModel|Model|bool + */ + public function findByChapterId($chapterId) + { + return ChapterLiveModel::findFirst([ + 'conditions' => 'chapter_id = :chapter_id:', + 'bind' => ['chapter_id' => $chapterId], + ]); + } + } diff --git a/app/Services/DingTalk/Notice/ConsultCreate.php b/app/Services/DingTalk/Notice/ConsultCreate.php new file mode 100644 index 00000000..7bb9abf3 --- /dev/null +++ b/app/Services/DingTalk/Notice/ConsultCreate.php @@ -0,0 +1,65 @@ +findById($task->item_id); + + $userRepo = new UserRepo(); + + $user = $userRepo->findById($consult->owner_id); + + $courseRepo = new CourseRepo(); + + $course = $courseRepo->findById($consult->course_id); + + $content = kg_ph_replace("{user.name} 对课程:{course.title} 发起了咨询:\n{consult.question}", [ + 'user.name' => $user->name, + 'course.title' => $course->title, + 'consult.question' => $consult->question, + ]); + + return $this->atCourseTeacher($course->id, $content); + } + + public function createTask(ConsultModel $consult) + { + $keyName = "dingtalk_consult_create_notice:{$consult->owner_id}"; + + $cache = $this->getCache(); + + $content = $cache->get($keyName); + + if ($content) return; + + $cache->save($keyName, 1, 3600); + + $task = new TaskModel(); + + $itemInfo = [ + 'consult' => ['id' => $consult->id], + ]; + + $task->item_id = $consult->id; + $task->item_info = $itemInfo; + $task->item_type = TaskModel::TYPE_NOTICE_CONSULT_CREATE; + $task->priority = TaskModel::PRIORITY_LOW; + $task->status = TaskModel::STATUS_PENDING; + + $task->create(); + } + +} \ No newline at end of file diff --git a/app/Services/DingTalk/Notice/CustomService.php b/app/Services/DingTalk/Notice/CustomService.php new file mode 100644 index 00000000..a57483cb --- /dev/null +++ b/app/Services/DingTalk/Notice/CustomService.php @@ -0,0 +1,59 @@ +findById($task->item_id); + + $userRepo = new UserRepo(); + + $sender = $userRepo->findById($message->sender_id); + + $content = kg_ph_replace("{user.name} 通过在线客服给你发送了消息:{message.content}", [ + 'user.name' => $sender->name, + 'message.content' => $message->content, + ]); + + return $this->atCustomService($content); + } + + public function createTask(ImMessageModel $message) + { + $keyName = "dingtalk_custom_service_notice:{$message->sender_id}"; + + $cache = $this->getCache(); + + $content = $cache->get($keyName); + + if ($content) return; + + $cache->save($keyName, 1, 3600); + + $task = new TaskModel(); + + $itemInfo = [ + 'im_message' => ['id' => $message->id], + ]; + + $task->item_id = $message->id; + $task->item_info = $itemInfo; + $task->item_type = TaskModel::TYPE_NOTICE_CUSTOM_SERVICE; + $task->priority = TaskModel::PRIORITY_MIDDLE; + $task->status = TaskModel::STATUS_PENDING; + + $task->create(); + } + +} \ No newline at end of file diff --git a/app/Services/DingTalk/Notice/LiveTeacher.php b/app/Services/DingTalk/Notice/LiveTeacher.php new file mode 100644 index 00000000..db20b0cb --- /dev/null +++ b/app/Services/DingTalk/Notice/LiveTeacher.php @@ -0,0 +1,49 @@ +findById($task->item_id); + + $courseRepo = new CourseRepo(); + + $course = $courseRepo->findById($live->course_id); + + $content = kg_ph_replace("课程:{course.title} 计划于 {live.start_time} 开播,不要错过直播时间哦!", [ + 'course.title' => $course->title, + 'live.start_time' => date('Y-m-d H:i', $live->start_time), + ]); + + return $this->atCourseTeacher($course->id, $content); + } + + public function createTask(ChapterLiveModel $live) + { + $task = new TaskModel(); + + $itemInfo = [ + 'live' => ['id' => $live->id], + ]; + + $task->item_id = $live->id; + $task->item_info = $itemInfo; + $task->item_type = TaskModel::TYPE_NOTICE_TEACHER_LIVE; + $task->priority = TaskModel::PRIORITY_LOW; + $task->status = TaskModel::STATUS_PENDING; + + $task->create(); + } + +} \ No newline at end of file diff --git a/app/Services/DingTalk/Notice/PointRedeem.php b/app/Services/DingTalk/Notice/PointRedeem.php new file mode 100644 index 00000000..791db8b1 --- /dev/null +++ b/app/Services/DingTalk/Notice/PointRedeem.php @@ -0,0 +1,47 @@ +findById($task->item_id); + + $content = kg_ph_replace("{user.name} 兑换了商品 {gift.name},不要忘记发货哦!", [ + 'user.name' => $redeem->user_name, + 'gift.name' => $redeem->gift_name, + ]); + + return $this->atCustomService($content); + } + + public function createTask(PointRedeemModel $redeem) + { + if ($redeem->gift_type != PointGiftModel::TYPE_GOODS) return; + + $task = new TaskModel(); + + $itemInfo = [ + 'point_redeem' => ['id' => $redeem->id], + ]; + + $task->item_id = $redeem->id; + $task->item_info = $itemInfo; + $task->item_type = TaskModel::TYPE_NOTICE_POINT_REDEEM; + $task->priority = TaskModel::PRIORITY_MIDDLE; + $task->status = TaskModel::STATUS_PENDING; + + $task->create(); + } + +} \ No newline at end of file diff --git a/app/Services/DingTalk/Notice/ServerMonitor.php b/app/Services/DingTalk/Notice/ServerMonitor.php new file mode 100644 index 00000000..3901bafc --- /dev/null +++ b/app/Services/DingTalk/Notice/ServerMonitor.php @@ -0,0 +1,36 @@ +item_info['content']; + + return $notice->atTechSupport($content); + } + + public function createTask($content) + { + $task = new TaskModel(); + + $itemInfo = ['content' => $content]; + + $task->item_id = time(); + $task->item_info = $itemInfo; + $task->item_type = TaskModel::TYPE_NOTICE_SERVER_MONITOR; + $task->priority = TaskModel::PRIORITY_HIGH; + $task->status = TaskModel::STATUS_PENDING; + $task->max_try_count = 1; + + $task->create(); + } + +} \ No newline at end of file diff --git a/app/Services/Logic/Consult/ConsultCreate.php b/app/Services/Logic/Consult/ConsultCreate.php index 369fd19a..2ec411dd 100644 --- a/app/Services/Logic/Consult/ConsultCreate.php +++ b/app/Services/Logic/Consult/ConsultCreate.php @@ -6,6 +6,7 @@ use App\Models\Chapter as ChapterModel; use App\Models\Consult as ConsultModel; use App\Models\Course as CourseModel; use App\Models\User as UserModel; +use App\Services\DingTalk\Notice\ConsultCreate as ConsultCreateNotice; use App\Services\Logic\ChapterTrait; use App\Services\Logic\CourseTrait; use App\Services\Logic\Service; @@ -75,6 +76,8 @@ class ConsultCreate extends Service $this->incrUserDailyConsultCount($user); + $this->handleConsultCreateNotice($consult); + return $consult; } @@ -111,6 +114,8 @@ class ConsultCreate extends Service $this->incrUserDailyConsultCount($user); + $this->handleConsultCreateNotice($consult); + return $consult; } @@ -150,4 +155,11 @@ class ConsultCreate extends Service $this->eventsManager->fire('UserDailyCounter:incrConsultCount', $this, $user); } + protected function handleConsultCreateNotice(ConsultModel $consult) + { + $notice = new ConsultCreateNotice(); + + $notice->createTask($consult); + } + } diff --git a/app/Services/Logic/Notice/AccountLogin.php b/app/Services/Logic/Notice/AccountLogin.php index 6ae4b18f..9f4fdd06 100644 --- a/app/Services/Logic/Notice/AccountLogin.php +++ b/app/Services/Logic/Notice/AccountLogin.php @@ -54,6 +54,7 @@ class AccountLogin extends LogicService $task->item_type = TaskModel::TYPE_NOTICE_ACCOUNT_LOGIN; $task->priority = TaskModel::PRIORITY_LOW; $task->status = TaskModel::STATUS_PENDING; + $task->max_try_count = 1; $task->create(); } diff --git a/app/Services/Logic/Notice/ConsultReply.php b/app/Services/Logic/Notice/ConsultReply.php index 3b77f7c1..34cfaebc 100644 --- a/app/Services/Logic/Notice/ConsultReply.php +++ b/app/Services/Logic/Notice/ConsultReply.php @@ -86,6 +86,7 @@ class ConsultReply extends LogicService $task->item_type = TaskModel::TYPE_NOTICE_CONSULT_REPLY; $task->priority = TaskModel::PRIORITY_LOW; $task->status = TaskModel::STATUS_PENDING; + $task->max_try_count = 1; $task->create(); } diff --git a/app/Services/Logic/Notice/LiveBegin.php b/app/Services/Logic/Notice/LiveBegin.php index f125c56c..a0818d54 100644 --- a/app/Services/Logic/Notice/LiveBegin.php +++ b/app/Services/Logic/Notice/LiveBegin.php @@ -92,6 +92,7 @@ class LiveBegin extends LogicService $task->item_type = TaskModel::TYPE_NOTICE_LIVE_BEGIN; $task->priority = TaskModel::PRIORITY_LOW; $task->status = TaskModel::STATUS_PENDING; + $task->max_try_count = 1; $task->create(); } diff --git a/db/migrations/20210215024511_data_202102151130.php b/db/migrations/20210215024511_data_202102151130.php new file mode 100644 index 00000000..e2d0fde5 --- /dev/null +++ b/db/migrations/20210215024511_data_202102151130.php @@ -0,0 +1,47 @@ + 'dingtalk.robot', + 'item_key' => 'enabled', + 'item_value' => '0', + ], + [ + 'section' => 'dingtalk.robot', + 'item_key' => 'app_secret', + 'item_value' => '', + ], + [ + 'section' => 'dingtalk.robot', + 'item_key' => 'app_token', + 'item_value' => '', + ], + [ + 'section' => 'dingtalk.robot', + 'item_key' => 'ts_mobiles', + 'item_value' => '', + ], + [ + 'section' => 'dingtalk.robot', + 'item_key' => 'cs_mobiles', + 'item_value' => '', + ], + ]; + + $this->table('kg_setting')->insert($rows)->save(); + } + + public function down() + { + $this->getQueryBuilder() + ->delete('kg_setting') + ->where(['section' => 'dingtalk.robot']) + ->execute(); + } + +} diff --git a/db/migrations/20210215034511_schema_202102151230.php b/db/migrations/20210215034511_schema_202102151230.php new file mode 100644 index 00000000..77b94e12 --- /dev/null +++ b/db/migrations/20210215034511_schema_202102151230.php @@ -0,0 +1,28 @@ +table('kg_task') + ->addColumn('max_try_count', 'integer', [ + 'null' => false, + 'default' => '0', + 'limit' => MysqlAdapter::INT_REGULAR, + 'signed' => false, + 'comment' => '最大尝试数', + 'after' => 'try_count', + ])->save(); + } + + public function down() + { + $this->table('kg_task') + ->removeColumn('max_try_count') + ->save(); + } + +} diff --git a/public/static/home/js/im.cs.js b/public/static/home/js/im.cs.js index 06c7727d..f86c831f 100644 --- a/public/static/home/js/im.cs.js +++ b/public/static/home/js/im.cs.js @@ -64,7 +64,7 @@ layui.use(['jquery', 'layim'], function () { }); layim.on('sendMessage', function (res) { - sendCsMessage(res); + sendCustomMessage(res); }); showWelcomeMessage(csUser); @@ -77,7 +77,7 @@ layui.use(['jquery', 'layim'], function () { }); } - function sendCsMessage(res) { + function sendCustomMessage(res) { $.ajax({ type: 'POST', url: '/im/msg/cs/send', diff --git a/scheduler.php b/scheduler.php index 666bb7e4..253ad168 100644 --- a/scheduler.php +++ b/scheduler.php @@ -16,18 +16,24 @@ $scheduler->php($script, $bin, ['--task' => 'deliver', '--action' => 'main']) $scheduler->php($script, $bin, ['--task' => 'notice', '--action' => 'main']) ->at('*/3 * * * *'); -$scheduler->php($script, $bin, ['--task' => 'sync_learning', '--action' => 'main']) - ->at('*/7 * * * *'); - $scheduler->php($script, $bin, ['--task' => 'vod_event', '--action' => 'main']) ->at('*/5 * * * *'); -$scheduler->php($script, $bin, ['--task' => 'close_trade', '--action' => 'main']) - ->at('*/13 * * * *'); +$scheduler->php($script, $bin, ['--task' => 'sync_learning', '--action' => 'main']) + ->at('*/7 * * * *'); + +$scheduler->php($script, $bin, ['--task' => 'teacher_live_notice', '--action' => 'consume']) + ->at('*/10 * * * *'); $scheduler->php($script, $bin, ['--task' => 'point_gift_deliver', '--action' => 'main']) ->at('*/11 * * * *'); +$scheduler->php($script, $bin, ['--task' => 'server_monitor', '--action' => 'main']) + ->at('*/12 * * * *'); + +$scheduler->php($script, $bin, ['--task' => 'close_trade', '--action' => 'main']) + ->at('*/13 * * * *'); + $scheduler->php($script, $bin, ['--task' => 'close_order', '--action' => 'main']) ->hourly(3); @@ -58,4 +64,10 @@ $scheduler->php($script, $bin, ['--task' => 'revoke_vip', '--action' => 'main']) $scheduler->php($script, $bin, ['--task' => 'sitemap', '--action' => 'main']) ->daily(4, 3); +$scheduler->php($script, $bin, ['--task' => 'teacher_live_notice', '--action' => 'provide']) + ->daily(4, 7); + +$scheduler->php($script, $bin, ['--task' => 'optimize_table', '--action' => 'main']) + ->weekly(6, 5, 3); + $scheduler->run(); \ No newline at end of file From 054bccadfb5fd104915b06f7bd50871d030f87cc Mon Sep 17 00:00:00 2001 From: koogua Date: Fri, 19 Feb 2021 16:12:52 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E6=9B=BF=E6=8D=A2layui-verify=E4=B8=BAla?= =?UTF-8?q?y-verify?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Admin/Views/setting/captcha.volt | 4 ++-- app/Http/Admin/Views/setting/im_cs.volt | 2 +- app/Http/Admin/Views/setting/live_notify.volt | 10 +++++----- app/Http/Admin/Views/setting/live_pull.volt | 2 +- app/Http/Admin/Views/setting/live_push.volt | 2 +- app/Http/Admin/Views/setting/secret.volt | 6 +++--- app/Http/Admin/Views/setting/sms.volt | 6 +++--- app/Http/Admin/Views/setting/storage.volt | 4 ++-- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/app/Http/Admin/Views/setting/captcha.volt b/app/Http/Admin/Views/setting/captcha.volt index 888c7937..1119fc25 100644 --- a/app/Http/Admin/Views/setting/captcha.volt +++ b/app/Http/Admin/Views/setting/captcha.volt @@ -9,13 +9,13 @@
- +
- +
diff --git a/app/Http/Admin/Views/setting/im_cs.volt b/app/Http/Admin/Views/setting/im_cs.volt index 156633c5..cf4a7eaa 100644 --- a/app/Http/Admin/Views/setting/im_cs.volt +++ b/app/Http/Admin/Views/setting/im_cs.volt @@ -9,7 +9,7 @@
- +
diff --git a/app/Http/Admin/Views/setting/live_notify.volt b/app/Http/Admin/Views/setting/live_notify.volt index bb973c3f..69f66d76 100644 --- a/app/Http/Admin/Views/setting/live_notify.volt +++ b/app/Http/Admin/Views/setting/live_notify.volt @@ -8,31 +8,31 @@
- +
- +
- +
- +
- +
diff --git a/app/Http/Admin/Views/setting/live_pull.volt b/app/Http/Admin/Views/setting/live_pull.volt index d8cc833c..75637516 100644 --- a/app/Http/Admin/Views/setting/live_pull.volt +++ b/app/Http/Admin/Views/setting/live_pull.volt @@ -15,7 +15,7 @@
- +
diff --git a/app/Http/Admin/Views/setting/live_push.volt b/app/Http/Admin/Views/setting/live_push.volt index 6550b759..ed4cf1a3 100644 --- a/app/Http/Admin/Views/setting/live_push.volt +++ b/app/Http/Admin/Views/setting/live_push.volt @@ -7,7 +7,7 @@
- +
diff --git a/app/Http/Admin/Views/setting/secret.volt b/app/Http/Admin/Views/setting/secret.volt index 0e42d8da..8b09d864 100644 --- a/app/Http/Admin/Views/setting/secret.volt +++ b/app/Http/Admin/Views/setting/secret.volt @@ -9,19 +9,19 @@
- +
- +
- +
diff --git a/app/Http/Admin/Views/setting/sms.volt b/app/Http/Admin/Views/setting/sms.volt index 05a2acda..b0f337a8 100644 --- a/app/Http/Admin/Views/setting/sms.volt +++ b/app/Http/Admin/Views/setting/sms.volt @@ -11,19 +11,19 @@
- +
- +
- +
diff --git a/app/Http/Admin/Views/setting/storage.volt b/app/Http/Admin/Views/setting/storage.volt index 9b1d2d6e..f6874821 100644 --- a/app/Http/Admin/Views/setting/storage.volt +++ b/app/Http/Admin/Views/setting/storage.volt @@ -9,13 +9,13 @@
- +
- +
From 2a0a039da63a63bb79b503880b994027fa6bfb01 Mon Sep 17 00:00:00 2001 From: koogua Date: Tue, 23 Feb 2021 20:36:37 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E5=90=88=E5=B9=B6dingtalk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Admin/Views/setting/dingtalk_robot.volt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Http/Admin/Views/setting/dingtalk_robot.volt b/app/Http/Admin/Views/setting/dingtalk_robot.volt index 9d62e7f4..acc1ae96 100644 --- a/app/Http/Admin/Views/setting/dingtalk_robot.volt +++ b/app/Http/Admin/Views/setting/dingtalk_robot.volt @@ -16,25 +16,25 @@
- +
- +
- +
- +
From 156b28b79ead0d5495b988dadde27e14e22c5e07 Mon Sep 17 00:00:00 2001 From: koogua Date: Thu, 25 Feb 2021 20:57:39 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E6=9F=A5=E6=BC=8F=E8=A1=A5=E7=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 21 +++++++ app/Console/Tasks/NoticeTask.php | 18 +++--- app/Console/Tasks/ServerMonitorTask.php | 58 ++++++++++++++----- .../Admin/Controllers/CourseController.php | 4 ++ .../Admin/Controllers/ImGroupController.php | 25 ++++---- .../Admin/Controllers/OrderController.php | 6 ++ .../Controllers/PointHistoryController.php | 40 +++++++++++++ .../Admin/Controllers/RefundController.php | 4 ++ .../Admin/Controllers/StudentController.php | 4 ++ .../Admin/Controllers/TopicController.php | 8 +++ .../Admin/Controllers/TradeController.php | 6 ++ app/Http/Admin/Controllers/UserController.php | 14 +++-- app/Http/Admin/Services/AuthNode.php | 22 +++++-- app/Http/Admin/Services/Course.php | 10 ++++ app/Http/Admin/Services/ImGroup.php | 5 ++ app/Http/Admin/Services/Order.php | 11 ++++ app/Http/Admin/Services/PointHistory.php | 32 ++++++++++ app/Http/Admin/Services/Refund.php | 5 ++ app/Http/Admin/Services/Student.php | 46 +++++++++++---- app/Http/Admin/Services/Trade.php | 11 ++++ app/Http/Admin/Services/User.php | 7 ++- app/Http/Admin/Views/audit/list.volt | 7 +++ app/Http/Admin/Views/consult/list.volt | 9 ++- app/Http/Admin/Views/course/list.volt | 11 ++++ app/Http/Admin/Views/course/search.volt | 13 ++--- app/Http/Admin/Views/help/list.volt | 7 +++ app/Http/Admin/Views/im/group/add.volt | 2 +- app/Http/Admin/Views/im/group/edit.volt | 2 +- app/Http/Admin/Views/im/group/list.volt | 21 +++++-- app/Http/Admin/Views/im/group/search.volt | 8 +-- app/Http/Admin/Views/macros/point.volt | 10 +++- app/Http/Admin/Views/order/list.volt | 7 +++ app/Http/Admin/Views/order/search.volt | 16 ++--- app/Http/Admin/Views/package/list.volt | 11 ++++ app/Http/Admin/Views/page/list.volt | 7 +++ app/Http/Admin/Views/point/history/list.volt | 55 ++++++++++++++++++ .../Admin/Views/point/history/search.volt | 38 ++++++++++++ app/Http/Admin/Views/point/redeem/list.volt | 19 +++--- app/Http/Admin/Views/refund/list.volt | 7 +++ app/Http/Admin/Views/refund/search.volt | 9 +-- app/Http/Admin/Views/review/list.volt | 7 +++ app/Http/Admin/Views/role/list.volt | 7 +++ .../Admin/Views/setting/dingtalk_robot.volt | 2 +- app/Http/Admin/Views/slide/list.volt | 7 +++ app/Http/Admin/Views/student/list.volt | 21 +++++-- app/Http/Admin/Views/student/search.volt | 7 +-- app/Http/Admin/Views/topic/list.volt | 11 ++++ app/Http/Admin/Views/topic/search.volt | 44 ++++++++++++++ app/Http/Admin/Views/trade/list.volt | 7 +++ app/Http/Admin/Views/trade/search.volt | 12 ++-- app/Http/Admin/Views/user/add.volt | 2 +- app/Http/Admin/Views/user/edit.volt | 2 +- app/Http/Admin/Views/user/list.volt | 11 ++++ app/Http/Admin/Views/user/search.volt | 7 ++- .../Home/Controllers/ImGroupController.php | 10 ++-- .../Controllers/PointRedeemController.php | 2 +- .../Controllers/UserConsoleController.php | 4 -- app/Http/Home/Services/ImFriendTrait.php | 10 +++- app/Http/Home/Views/course/show_catalog.volt | 40 +++++++------ app/Http/Home/Views/course/show_meta.volt | 4 +- .../Home/Views/im/group/active_users.volt | 2 +- app/Http/Home/Views/im/group/list.volt | 2 +- app/Http/Home/Views/im/group/pager.volt | 2 +- app/Http/Home/Views/im/group/show.volt | 6 +- app/Http/Home/Views/im/group/show_owner.volt | 2 +- app/Http/Home/Views/im/index_groups.volt | 2 +- app/Http/Home/Views/macros/course_user.volt | 15 +++++ app/Http/Home/Views/partials/header.volt | 3 - app/Http/Home/Views/search/group.volt | 2 +- app/Http/Home/Views/user/console/courses.volt | 3 +- app/Http/Home/Views/user/console/friends.volt | 2 +- .../Views/user/console/groups_joined.volt | 2 +- app/Http/Home/Views/user/console/menu.volt | 25 ++++---- .../Views/user/console/point_history.volt | 2 +- .../Views/user/console/point_redeems.volt | 2 +- app/Http/Home/Views/user/groups.volt | 2 +- app/Library/AppInfo.php | 2 +- app/Library/Utils/ServerInfo.php | 10 ++-- app/Models/CourseRating.php | 8 +-- app/Models/CourseUser.php | 2 +- app/Repos/Course.php | 1 + app/Repos/ImFriendGroup.php | 2 +- app/Repos/Topic.php | 4 ++ .../DingTalk/Notice/ConsultCreate.php | 6 +- .../DingTalk/Notice/CustomService.php | 6 +- app/Services/DingTalk/Notice/LiveTeacher.php | 6 +- app/Services/DingTalk/Notice/PointRedeem.php | 6 +- .../DingTalk/Notice/ServerMonitor.php | 6 +- app/Services/DingTalkNotice.php | 49 ++++++++++------ app/Services/Logic/User/CourseList.php | 1 + app/Validators/ImFriendGroup.php | 4 +- .../20210215024511_data_202102151130.php | 23 ++++++++ 92 files changed, 824 insertions(+), 219 deletions(-) create mode 100644 app/Http/Admin/Controllers/PointHistoryController.php create mode 100644 app/Http/Admin/Services/PointHistory.php create mode 100644 app/Http/Admin/Views/point/history/list.volt create mode 100644 app/Http/Admin/Views/point/history/search.volt create mode 100644 app/Http/Admin/Views/topic/search.volt create mode 100644 app/Http/Home/Views/macros/course_user.volt diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d08a790..6cb084df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,24 @@ +### [v1.2.7](https://gitee.com/koogua/course-tencent-cloud/releases/v1.2.7)(2021-02-26) + +### 新增 + +- 钉钉机器人群消息通知 +- demo分支重置演示帐号计划任务 +- 添加学员自动加入相关课程群组 +- 后台查看积分记录 + +### 更新 + +- 路由重命名 admin.group -> admin.im_group +- 路由重命名 home.group -> home.im_group +- 样式重命名 sidebar-teacher-card -> sidebar-user-card +- 去除顶部积分导航 +- 用户中心部分样式调整 +- 后台部分导航调整 +- 不能删除课程教师问题 +- 积分模块可通过后台控制是否启用 +- 解除好友关系后好友数量未递减 + ### [v1.2.6](https://gitee.com/koogua/course-tencent-cloud/releases/v1.2.6)(2021-02-20) ### 新增 diff --git a/app/Console/Tasks/NoticeTask.php b/app/Console/Tasks/NoticeTask.php index 17613ae7..8d3abe45 100644 --- a/app/Console/Tasks/NoticeTask.php +++ b/app/Console/Tasks/NoticeTask.php @@ -91,63 +91,63 @@ class NoticeTask extends Task { $notice = new AccountLoginNotice(); - return $notice->handleTask($task); + $notice->handleTask($task); } protected function handleLiveBeginNotice(TaskModel $task) { $notice = new LiveBeginNotice(); - return $notice->handleTask($task); + $notice->handleTask($task); } protected function handleOrderFinishNotice(TaskModel $task) { $notice = new OrderFinishNotice(); - return $notice->handleTask($task); + $notice->handleTask($task); } protected function handleRefundFinishNotice(TaskModel $task) { $notice = new RefundFinishNotice(); - return $notice->handleTask($task); + $notice->handleTask($task); } protected function handleConsultReplyNotice(TaskModel $task) { $notice = new ConsultReplyNotice(); - return $notice->handleTask($task); + $notice->handleTask($task); } protected function handleConsultCreateNotice(TaskModel $task) { $notice = new ConsultCreateNotice(); - return $notice->handleTask($task); + $notice->handleTask($task); } protected function handleTeacherLiveNotice(TaskModel $task) { $notice = new TeacherLiveNotice(); - return $notice->handleTask($task); + $notice->handleTask($task); } protected function handleServerMonitorNotice(TaskModel $task) { $notice = new ServerMonitorNotice(); - return $notice->handleTask($task); + $notice->handleTask($task); } protected function handleCustomServiceNotice(TaskModel $task) { $notice = new CustomServiceNotice(); - return $notice->handleTask($task); + $notice->handleTask($task); } /** diff --git a/app/Console/Tasks/ServerMonitorTask.php b/app/Console/Tasks/ServerMonitorTask.php index 7c2f4486..7eff21ca 100644 --- a/app/Console/Tasks/ServerMonitorTask.php +++ b/app/Console/Tasks/ServerMonitorTask.php @@ -3,7 +3,6 @@ namespace App\Console\Tasks; use App\Library\Benchmark; -use App\Library\Utils\ServerInfo; use App\Models\User as UserModel; use App\Services\DingTalk\Notice\ServerMonitor as ServerMonitorNotice; use App\Services\Search\UserSearcher; @@ -19,12 +18,13 @@ class ServerMonitorTask extends Task if ($robot['enabled'] == 0) return; $items = [ - 'cpu' => $this->checkCPU(), + 'cpu' => $this->checkCpu(), + 'memory' => $this->checkMemory(), 'disk' => $this->checkDisk(), 'mysql' => $this->checkMysql(), 'redis' => $this->checkRedis(), - 'xunsearch' => $this->checkXunSearch(), - 'websocket' => $this->checkWebSocket(), + 'xunsearch' => $this->checkXunsearch(), + 'websocket' => $this->checkWebsocket(), ]; foreach ($items as $key => $value) { @@ -42,23 +42,53 @@ class ServerMonitorTask extends Task $notice->createTask($content); } - protected function checkCPU() + protected function checkCpu() { - $coreCount = $this->getCpuCount(); + $cpuCount = $this->getCpuCount(); - $cpu = ServerInfo::cpu(); + $load = sys_getloadavg(); - if ($cpu[1] > $coreCount * 0.8) { - return sprintf("cpu负载超过%s", $cpu[1]); + if ($load[1] > $cpuCount * 0.8) { + return sprintf("cpu负载超过%s", $load[1]); + } + } + + protected function checkMemory() + { + $memInfo = file_get_contents('/proc/meminfo'); + + $total = null; + + if (preg_match('/MemTotal\:\s+(\d+) kB/', $memInfo, $totalMatches)) { + $total = $totalMatches[1]; + } + + if ($total === null) return; + + $available = null; + + if (preg_match('/MemAvailable\:\s+(\d+) kB/', $memInfo, $avaMatches)) { + $available = $avaMatches[1]; + } + + if ($available === null) return; + + $left = 100 * ($available / $total); + + if ($left < 20) { + return sprintf("memory剩余不足%s%%", round($left)); } } protected function checkDisk() { - $disk = ServerInfo::disk(); + $free = disk_free_space('/'); + $total = disk_total_space('/'); - if ($disk['percent'] > 80) { - return sprintf("disk空间超过%s%%", $disk['percent']); + $left = 100 * $free / $total; + + if ($left < 20) { + return sprintf("disk剩余不足%s%%", round($left)); } } @@ -116,7 +146,7 @@ class ServerMonitorTask extends Task } } - protected function checkXunSearch() + protected function checkXunsearch() { try { @@ -145,7 +175,7 @@ class ServerMonitorTask extends Task } } - protected function checkWebSocket() + protected function checkWebsocket() { try { diff --git a/app/Http/Admin/Controllers/CourseController.php b/app/Http/Admin/Controllers/CourseController.php index 587e3e89..9b927b52 100644 --- a/app/Http/Admin/Controllers/CourseController.php +++ b/app/Http/Admin/Controllers/CourseController.php @@ -33,9 +33,13 @@ class CourseController extends Controller $xmCategories = $courseService->getXmCategories(0); $xmTeachers = $courseService->getXmTeachers(0); + $modelTypes = $courseService->getModelTypes(); + $levelTypes = $courseService->getLevelTypes(); $this->view->setVar('xm_categories', $xmCategories); $this->view->setVar('xm_teachers', $xmTeachers); + $this->view->setVar('model_types', $modelTypes); + $this->view->setVar('level_types', $levelTypes); } /** diff --git a/app/Http/Admin/Controllers/ImGroupController.php b/app/Http/Admin/Controllers/ImGroupController.php index 7be26303..e1f73991 100644 --- a/app/Http/Admin/Controllers/ImGroupController.php +++ b/app/Http/Admin/Controllers/ImGroupController.php @@ -11,7 +11,7 @@ class ImGroupController extends Controller { /** - * @Get("/list", name="admin.group.list") + * @Get("/list", name="admin.im_group.list") */ public function listAction() { @@ -25,15 +25,20 @@ class ImGroupController extends Controller } /** - * @Get("/search", name="admin.group.search") + * @Get("/search", name="admin.im_group.search") */ public function searchAction() { + $groupService = new ImGroupService(); + + $types = $groupService->getGroupTypes(); + $this->view->pick('im/group/search'); + $this->view->setVar('types', $types); } /** - * @Get("/add", name="admin.group.add") + * @Get("/add", name="admin.im_group.add") */ public function addAction() { @@ -41,7 +46,7 @@ class ImGroupController extends Controller } /** - * @Get("/{id:[0-9]+}/edit", name="admin.group.edit") + * @Get("/{id:[0-9]+}/edit", name="admin.im_group.edit") */ public function editAction($id) { @@ -55,7 +60,7 @@ class ImGroupController extends Controller } /** - * @Post("/create", name="admin.group.create") + * @Post("/create", name="admin.im_group.create") */ public function createAction() { @@ -64,7 +69,7 @@ class ImGroupController extends Controller $group = $groupService->createGroup(); $location = $this->url->get([ - 'for' => 'admin.group.edit', + 'for' => 'admin.im_group.edit', 'id' => $group->id, ]); @@ -77,7 +82,7 @@ class ImGroupController extends Controller } /** - * @Post("/{id:[0-9]+}/update", name="admin.group.update") + * @Post("/{id:[0-9]+}/update", name="admin.im_group.update") */ public function updateAction($id) { @@ -85,7 +90,7 @@ class ImGroupController extends Controller $groupService->updateGroup($id); - $location = $this->url->get(['for' => 'admin.group.list']); + $location = $this->url->get(['for' => 'admin.im_group.list']); $content = [ 'location' => $location, @@ -96,7 +101,7 @@ class ImGroupController extends Controller } /** - * @Post("/{id:[0-9]+}/delete", name="admin.group.delete") + * @Post("/{id:[0-9]+}/delete", name="admin.im_group.delete") */ public function deleteAction($id) { @@ -115,7 +120,7 @@ class ImGroupController extends Controller } /** - * @Post("/{id:[0-9]+}/restore", name="admin.group.restore") + * @Post("/{id:[0-9]+}/restore", name="admin.im_group.restore") */ public function restoreAction($id) { diff --git a/app/Http/Admin/Controllers/OrderController.php b/app/Http/Admin/Controllers/OrderController.php index 54597b42..c243e430 100644 --- a/app/Http/Admin/Controllers/OrderController.php +++ b/app/Http/Admin/Controllers/OrderController.php @@ -15,7 +15,13 @@ class OrderController extends Controller */ public function searchAction() { + $orderService = new OrderService(); + $itemTypes = $orderService->getItemTypes(); + $statusTypes = $orderService->getStatusTypes(); + + $this->view->setVar('item_types', $itemTypes); + $this->view->setVar('status_types', $statusTypes); } /** diff --git a/app/Http/Admin/Controllers/PointHistoryController.php b/app/Http/Admin/Controllers/PointHistoryController.php new file mode 100644 index 00000000..cce0f88c --- /dev/null +++ b/app/Http/Admin/Controllers/PointHistoryController.php @@ -0,0 +1,40 @@ +getEventTypes(); + + $this->view->pick('point/history/search'); + $this->view->setVar('event_types', $eventTypes); + } + + /** + * @Get("/list", name="admin.point_history.list") + */ + public function listAction() + { + $historyService = new PointHistoryService(); + + $pager = $historyService->getHistories(); + + $this->view->pick('point/history/list'); + + $this->view->setVar('pager', $pager); + } + +} \ No newline at end of file diff --git a/app/Http/Admin/Controllers/RefundController.php b/app/Http/Admin/Controllers/RefundController.php index 7271f416..3799e23e 100644 --- a/app/Http/Admin/Controllers/RefundController.php +++ b/app/Http/Admin/Controllers/RefundController.php @@ -15,7 +15,11 @@ class RefundController extends Controller */ public function searchAction() { + $refundService = new RefundService(); + $statusTypes = $refundService->getStatusTypes(); + + $this->view->setVar('status_types', $statusTypes); } /** diff --git a/app/Http/Admin/Controllers/StudentController.php b/app/Http/Admin/Controllers/StudentController.php index 9b2707fb..e72a01a3 100644 --- a/app/Http/Admin/Controllers/StudentController.php +++ b/app/Http/Admin/Controllers/StudentController.php @@ -15,7 +15,11 @@ class StudentController extends Controller */ public function searchAction() { + $studentService = new StudentService(); + $sourceTypes = $studentService->getSourceTypes(); + + $this->view->setVar('source_types', $sourceTypes); } /** diff --git a/app/Http/Admin/Controllers/TopicController.php b/app/Http/Admin/Controllers/TopicController.php index 02d08f30..087580e7 100644 --- a/app/Http/Admin/Controllers/TopicController.php +++ b/app/Http/Admin/Controllers/TopicController.php @@ -22,6 +22,14 @@ class TopicController extends Controller $this->view->setVar('pager', $pager); } + /** + * @Get("/search", name="admin.topic.search") + */ + public function searchAction() + { + + } + /** * @Get("/add", name="admin.topic.add") */ diff --git a/app/Http/Admin/Controllers/TradeController.php b/app/Http/Admin/Controllers/TradeController.php index b4781320..2600351f 100644 --- a/app/Http/Admin/Controllers/TradeController.php +++ b/app/Http/Admin/Controllers/TradeController.php @@ -15,7 +15,13 @@ class TradeController extends Controller */ public function searchAction() { + $tradeService = new TradeService(); + $channelTypes = $tradeService->getChannelTypes(); + $statusTypes = $tradeService->getStatusTypes(); + + $this->view->setVar('channel_types', $channelTypes); + $this->view->setVar('status_types', $statusTypes); } /** diff --git a/app/Http/Admin/Controllers/UserController.php b/app/Http/Admin/Controllers/UserController.php index d1482164..5d106768 100644 --- a/app/Http/Admin/Controllers/UserController.php +++ b/app/Http/Admin/Controllers/UserController.php @@ -18,9 +18,11 @@ class UserController extends Controller { $userService = new UserService(); - $roles = $userService->getRoles(); + $eduRoleTypes = $userService->getEduRoleTypes(); + $adminRoles = $userService->getAdminRoles(); - $this->view->setVar('roles', $roles); + $this->view->setVar('edu_role_types', $eduRoleTypes); + $this->view->setVar('admin_roles', $adminRoles); } /** @@ -42,9 +44,9 @@ class UserController extends Controller { $userService = new UserService(); - $roles = $userService->getRoles(); + $adminRoles = $userService->getAdminRoles(); - $this->view->setVar('roles', $roles); + $this->view->setVar('admin_roles', $adminRoles); } /** @@ -81,7 +83,7 @@ class UserController extends Controller $user = $userService->getUser($id); $account = $userService->getAccount($id); - $roles = $userService->getRoles(); + $adminRoles = $userService->getAdminRoles(); if ($user->admin_role == RoleModel::ROLE_ROOT) { $this->response->redirect(['for' => 'admin.user.list']); @@ -89,7 +91,7 @@ class UserController extends Controller $this->view->setVar('user', $user); $this->view->setVar('account', $account); - $this->view->setVar('roles', $roles); + $this->view->setVar('admin_roles', $adminRoles); } /** diff --git a/app/Http/Admin/Services/AuthNode.php b/app/Http/Admin/Services/AuthNode.php index 374aa629..a0978c90 100644 --- a/app/Http/Admin/Services/AuthNode.php +++ b/app/Http/Admin/Services/AuthNode.php @@ -149,6 +149,12 @@ class AuthNode extends Service 'type' => 'menu', 'route' => 'admin.topic.list', ], + [ + 'id' => '1-4-5', + 'title' => '搜索话题', + 'type' => 'menu', + 'route' => 'admin.topic.search', + ], [ 'id' => '1-4-2', 'title' => '添加话题', @@ -349,31 +355,31 @@ class AuthNode extends Service 'id' => '2-4-1', 'title' => '群组列表', 'type' => 'menu', - 'route' => 'admin.group.list', + 'route' => 'admin.im_group.list', ], [ 'id' => '2-4-2', 'title' => '搜索群组', 'type' => 'menu', - 'route' => 'admin.group.search', + 'route' => 'admin.im_group.search', ], [ 'id' => '2-4-3', 'title' => '添加群组', 'type' => 'menu', - 'route' => 'admin.group.add', + 'route' => 'admin.im_group.add', ], [ 'id' => '2-4-4', 'title' => '编辑群组', 'type' => 'button', - 'route' => 'admin.group.edit', + 'route' => 'admin.im_group.edit', ], [ 'id' => '2-4-5', 'title' => '删除群组', 'type' => 'button', - 'route' => 'admin.group.delete', + 'route' => 'admin.im_group.delete', ], ], ], @@ -493,6 +499,12 @@ class AuthNode extends Service 'type' => 'menu', 'route' => 'admin.point_redeem.list', ], + [ + 'id' => '2-8-6', + 'title' => '积分记录', + 'type' => 'menu', + 'route' => 'admin.point_history.list', + ], [ 'id' => '2-8-3', 'title' => '添加礼品', diff --git a/app/Http/Admin/Services/Course.php b/app/Http/Admin/Services/Course.php index 1767f553..1768f428 100644 --- a/app/Http/Admin/Services/Course.php +++ b/app/Http/Admin/Services/Course.php @@ -232,6 +232,16 @@ class Course extends Service return $course; } + public function getModelTypes() + { + return CourseModel::modelTypes(); + } + + public function getLevelTypes() + { + return CourseModel::levelTypes(); + } + public function getStudyExpiryOptions() { return CourseModel::studyExpiryOptions(); diff --git a/app/Http/Admin/Services/ImGroup.php b/app/Http/Admin/Services/ImGroup.php index a24cd560..9f4af997 100644 --- a/app/Http/Admin/Services/ImGroup.php +++ b/app/Http/Admin/Services/ImGroup.php @@ -14,6 +14,11 @@ use App\Validators\ImGroup as ImGroupValidator; class ImGroup extends Service { + public function getGroupTypes() + { + return ImGroupModel::types(); + } + public function getGroups() { $pagerQuery = new PagerQuery(); diff --git a/app/Http/Admin/Services/Order.php b/app/Http/Admin/Services/Order.php index d43adf42..05ebb525 100644 --- a/app/Http/Admin/Services/Order.php +++ b/app/Http/Admin/Services/Order.php @@ -4,6 +4,7 @@ namespace App\Http\Admin\Services; use App\Builders\OrderList as OrderListBuilder; use App\Library\Paginator\Query as PaginateQuery; +use App\Models\Order as OrderModel; use App\Repos\Account as AccountRepo; use App\Repos\Order as OrderRepo; use App\Repos\User as UserRepo; @@ -12,6 +13,16 @@ use App\Validators\Order as OrderValidator; class Order extends Service { + public function getItemTypes() + { + return OrderModel::itemTypes(); + } + + public function getStatusTypes() + { + return OrderModel::statusTypes(); + } + public function getOrders() { $pageQuery = new PaginateQuery(); diff --git a/app/Http/Admin/Services/PointHistory.php b/app/Http/Admin/Services/PointHistory.php new file mode 100644 index 00000000..83b0bc99 --- /dev/null +++ b/app/Http/Admin/Services/PointHistory.php @@ -0,0 +1,32 @@ +getParams(); + + $sort = $pagerQuery->getSort(); + $page = $pagerQuery->getPage(); + $limit = $pagerQuery->getLimit(); + + $historyRepo = new PointHistoryRepo(); + + return $historyRepo->paginate($params, $sort, $page, $limit); + } + + public function getEventTypes() + { + return PointHistoryModel::eventTypes(); + } + +} \ No newline at end of file diff --git a/app/Http/Admin/Services/Refund.php b/app/Http/Admin/Services/Refund.php index 89efeb70..2617f4fa 100644 --- a/app/Http/Admin/Services/Refund.php +++ b/app/Http/Admin/Services/Refund.php @@ -16,6 +16,11 @@ use App\Validators\Refund as RefundValidator; class Refund extends Service { + public function getStatusTypes() + { + return RefundModel::statusTypes(); + } + public function getRefunds() { $pageQuery = new PaginateQuery(); diff --git a/app/Http/Admin/Services/Student.php b/app/Http/Admin/Services/Student.php index 9ecceade..2e8b9b4f 100644 --- a/app/Http/Admin/Services/Student.php +++ b/app/Http/Admin/Services/Student.php @@ -7,9 +7,11 @@ use App\Builders\LearningList as LearningListBuilder; use App\Library\Paginator\Query as PagerQuery; use App\Models\Course as CourseModel; use App\Models\CourseUser as CourseUserModel; +use App\Models\ImGroupUser as ImGroupUserModel; use App\Models\User as UserModel; use App\Repos\Course as CourseRepo; use App\Repos\CourseUser as CourseUserRepo; +use App\Repos\ImGroupUser as ImGroupUserRepo; use App\Repos\Learning as LearningRepo; use App\Repos\User as UserRepo; use App\Validators\CourseUser as CourseUserValidator; @@ -17,6 +19,11 @@ use App\Validators\CourseUser as CourseUserValidator; class Student extends Service { + public function getSourceTypes() + { + return CourseUserModel::sourceTypes(); + } + public function getCourse($id) { $repo = new CourseRepo(); @@ -100,9 +107,13 @@ class Student extends Service $courseUser->create($data); - $this->incrCourseUserCount($course); + $course->user_count += 1; + $course->update(); - $this->incrUserCourseCount($user); + $user->course_count += 1; + $user->update(); + + $this->handleImGroupUser($course, $user); return $courseUser; } @@ -126,18 +137,33 @@ class Student extends Service return $relation; } - protected function incrCourseUserCount(CourseModel $course) + protected function handleImGroupUser(CourseModel $course, UserModel $user) { - $course->user_count += 1; + $courseRepo = new CourseRepo(); - $course->update(); - } + $imGroup = $courseRepo->findImGroup($course->id); - protected function incrUserCourseCount(UserModel $user) - { - $user->course_count += 1; + $userRepo = new UserRepo(); - $user->update(); + $imUser = $userRepo->findImUser($user->id); + + $imGroupUserRepo = new ImGroupUserRepo(); + + $imGroupUser = $imGroupUserRepo->findGroupUser($imGroup->id, $user->id); + + if ($imGroupUser) return; + + $imGroupUser = new ImGroupUserModel(); + + $imGroupUser->group_id = $imGroup->id; + $imGroupUser->user_id = $imUser->id; + $imGroupUser->create(); + + $imUser->group_count += 1; + $imUser->update(); + + $imGroup->user_count += 1; + $imGroup->update(); } protected function findOrFail($id) diff --git a/app/Http/Admin/Services/Trade.php b/app/Http/Admin/Services/Trade.php index 7205ce6c..9b818a81 100644 --- a/app/Http/Admin/Services/Trade.php +++ b/app/Http/Admin/Services/Trade.php @@ -5,6 +5,7 @@ namespace App\Http\Admin\Services; use App\Builders\TradeList as TradeListBuilder; use App\Library\Paginator\Query as PaginateQuery; use App\Models\Refund as RefundModel; +use App\Models\Trade as TradeModel; use App\Repos\Account as AccountRepo; use App\Repos\Order as OrderRepo; use App\Repos\Trade as TradeRepo; @@ -14,6 +15,16 @@ use App\Validators\Trade as TradeValidator; class Trade extends Service { + public function getChannelTypes() + { + return TradeModel::channelTypes(); + } + + public function getStatusTypes() + { + return TradeModel::statusTypes(); + } + public function getTrades() { $pageQuery = new PaginateQuery(); diff --git a/app/Http/Admin/Services/User.php b/app/Http/Admin/Services/User.php index 91d2a06c..539fcb32 100644 --- a/app/Http/Admin/Services/User.php +++ b/app/Http/Admin/Services/User.php @@ -18,7 +18,12 @@ use App\Validators\User as UserValidator; class User extends Service { - public function getRoles() + public function getEduRoleTypes() + { + return UserModel::eduRoleTypes(); + } + + public function getAdminRoles() { $roleRepo = new RoleRepo(); diff --git a/app/Http/Admin/Views/audit/list.volt b/app/Http/Admin/Views/audit/list.volt index 6c43fbb5..b1b739d7 100644 --- a/app/Http/Admin/Views/audit/list.volt +++ b/app/Http/Admin/Views/audit/list.volt @@ -2,12 +2,19 @@ {% block content %} + {% set search_url = url({'for':'admin.audit.search'}) %} + diff --git a/app/Http/Admin/Views/consult/list.volt b/app/Http/Admin/Views/consult/list.volt index 21a74f8d..65f0f5ee 100644 --- a/app/Http/Admin/Views/consult/list.volt +++ b/app/Http/Admin/Views/consult/list.volt @@ -4,10 +4,12 @@ {%- macro private_info(value) %} {% if value == 1 %} - + 私密 {% endif %} {%- endmacro %} + {% set search_url = url({'for':'admin.consult.search'}) %} +
@@ -18,6 +20,11 @@ 咨询管理
+
diff --git a/app/Http/Admin/Views/course/list.volt b/app/Http/Admin/Views/course/list.volt index ed9d18dc..9af90372 100644 --- a/app/Http/Admin/Views/course/list.volt +++ b/app/Http/Admin/Views/course/list.volt @@ -44,12 +44,23 @@ {% endif %} {%- endmacro %} + {% set add_url = url({'for':'admin.course.add'}) %} + {% set search_url = url({'for':'admin.course.search'}) %} +
diff --git a/app/Http/Admin/Views/course/search.volt b/app/Http/Admin/Views/course/search.volt index 1076d9a4..23a444dc 100644 --- a/app/Http/Admin/Views/course/search.volt +++ b/app/Http/Admin/Views/course/search.volt @@ -33,18 +33,17 @@
- - - + {% for value,title in model_types %} + + {% endfor %}
- - - - + {% for value,title in level_types %} + + {% endfor %}
diff --git a/app/Http/Admin/Views/help/list.volt b/app/Http/Admin/Views/help/list.volt index f7926df5..6f942096 100644 --- a/app/Http/Admin/Views/help/list.volt +++ b/app/Http/Admin/Views/help/list.volt @@ -2,12 +2,19 @@ {% block content %} + {% set add_url = url({'for':'admin.help.add'}) %} +
diff --git a/app/Http/Admin/Views/im/group/add.volt b/app/Http/Admin/Views/im/group/add.volt index 28c8724b..1e55374f 100644 --- a/app/Http/Admin/Views/im/group/add.volt +++ b/app/Http/Admin/Views/im/group/add.volt @@ -2,7 +2,7 @@ {% block content %} - +
添加群组
diff --git a/app/Http/Admin/Views/im/group/edit.volt b/app/Http/Admin/Views/im/group/edit.volt index 1a3b7cb1..7cb6a8b3 100644 --- a/app/Http/Admin/Views/im/group/edit.volt +++ b/app/Http/Admin/Views/im/group/edit.volt @@ -2,7 +2,7 @@ {% block content %} - +
编辑群组
diff --git a/app/Http/Admin/Views/im/group/list.volt b/app/Http/Admin/Views/im/group/list.volt index 7934d5b4..89ecddfb 100644 --- a/app/Http/Admin/Views/im/group/list.volt +++ b/app/Http/Admin/Views/im/group/list.volt @@ -22,12 +22,23 @@ {% endif %} {%- endmacro %} + {% set add_url = url({'for':'admin.im_group.add'}) %} + {% set search_url = url({'for':'admin.im_group.search'}) %} +
@@ -51,11 +62,11 @@ {% for item in pager.items %} - {% set preview_url = url({'for':'home.group.show','id':item.id}) %} - {% set edit_url = url({'for':'admin.group.edit','id':item.id}) %} - {% set update_url = url({'for':'admin.group.update','id':item.id}) %} - {% set delete_url = url({'for':'admin.group.delete','id':item.id}) %} - {% set restore_url = url({'for':'admin.group.restore','id':item.id}) %} + {% set preview_url = url({'for':'home.im_group.show','id':item.id}) %} + {% set edit_url = url({'for':'admin.im_group.edit','id':item.id}) %} + {% set update_url = url({'for':'admin.im_group.update','id':item.id}) %} + {% set delete_url = url({'for':'admin.im_group.delete','id':item.id}) %} + {% set restore_url = url({'for':'admin.im_group.restore','id':item.id}) %} diff --git a/app/Http/Admin/Views/im/group/search.volt b/app/Http/Admin/Views/im/group/search.volt index 9ce882e2..5fe743a6 100644 --- a/app/Http/Admin/Views/im/group/search.volt +++ b/app/Http/Admin/Views/im/group/search.volt @@ -2,7 +2,7 @@ {% block content %} - +
搜索群组
@@ -33,9 +33,9 @@
- - - + {% for value,title in types %} + + {% endfor %}
diff --git a/app/Http/Admin/Views/macros/point.volt b/app/Http/Admin/Views/macros/point.volt index 8b2d6093..06aced06 100644 --- a/app/Http/Admin/Views/macros/point.volt +++ b/app/Http/Admin/Views/macros/point.volt @@ -18,6 +18,14 @@ {% endif %} {%- endmacro %} +{%- macro event_point_info(value) %} + {% if value > 0 %} + +{{ value }} + {% else %} + {{ value }} + {% endif %} +{%- endmacro %} + {%- macro event_type_info(value) %} {% if value == 1 %} 订单消费 @@ -38,7 +46,7 @@ {% endif %} {%- endmacro %} -{%- macro event_detail_info(history) %} +{%- macro event_item_info(history) %} {% set event_info = history.event_info %} {% if history.event_type == 1 %}

{{ event_info.order.subject }}

diff --git a/app/Http/Admin/Views/order/list.volt b/app/Http/Admin/Views/order/list.volt index 8b6a39b3..4ec3802f 100644 --- a/app/Http/Admin/Views/order/list.volt +++ b/app/Http/Admin/Views/order/list.volt @@ -4,12 +4,19 @@ {{ partial('order/macro') }} + {% set search_url = url({'for':'admin.order.search'}) %} +
{{ item.id }} {{ item.name }} {{ type_info(item.type) }}
diff --git a/app/Http/Admin/Views/order/search.volt b/app/Http/Admin/Views/order/search.volt index 627fbc31..1f266a06 100644 --- a/app/Http/Admin/Views/order/search.volt +++ b/app/Http/Admin/Views/order/search.volt @@ -21,21 +21,17 @@
- - - - - + {% for value,title in item_types %} + + {% endfor %}
- - - - - + {% for value,title in status_types %} + + {% endfor %}
diff --git a/app/Http/Admin/Views/package/list.volt b/app/Http/Admin/Views/package/list.volt index e23a17d8..1c94d2f6 100644 --- a/app/Http/Admin/Views/package/list.volt +++ b/app/Http/Admin/Views/package/list.volt @@ -2,12 +2,23 @@ {% block content %} + {% set add_url = url({'for':'admin.package.add'}) %} + {% set search_url = url({'for':'admin.package.search'}) %} +
diff --git a/app/Http/Admin/Views/page/list.volt b/app/Http/Admin/Views/page/list.volt index 5e7a5062..607f17f2 100644 --- a/app/Http/Admin/Views/page/list.volt +++ b/app/Http/Admin/Views/page/list.volt @@ -2,12 +2,19 @@ {% block content %} + {% set add_url = url({'for':'admin.page.add'}) %} +
diff --git a/app/Http/Admin/Views/point/history/list.volt b/app/Http/Admin/Views/point/history/list.volt new file mode 100644 index 00000000..145ecffa --- /dev/null +++ b/app/Http/Admin/Views/point/history/list.volt @@ -0,0 +1,55 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + {{ partial('macros/point') }} + + {% set search_url = url({'for':'admin.point_history.search'}) %} + + + +
+ + + + + + + + + + + + + + + + + + {% for item in pager.items %} + {% set user_filter_url = url({'for':'admin.point_history.list'},{'user_id':item.user_id}) %} + + + + + + + + {% endfor %} + +
用户积分来源详情时间
{{ item.user_name }}({{ item.user_id }}){{ event_point_info(item.event_point) }}{{ event_type_info(item.event_type) }}{{ event_item_info(item) }}{{ date('Y-m-d H:i:s',item.create_time) }}
+ + {{ partial('partials/pager') }} + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/point/history/search.volt b/app/Http/Admin/Views/point/history/search.volt new file mode 100644 index 00000000..4717481b --- /dev/null +++ b/app/Http/Admin/Views/point/history/search.volt @@ -0,0 +1,38 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + +
+ 搜索积分 +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ {% for value,title in event_types %} + + {% endfor %} +
+
+
+ +
+ + +
+
+ + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/point/redeem/list.volt b/app/Http/Admin/Views/point/redeem/list.volt index c86b4b1b..30e7633b 100644 --- a/app/Http/Admin/Views/point/redeem/list.volt +++ b/app/Http/Admin/Views/point/redeem/list.volt @@ -43,9 +43,10 @@ {% set gift_url = url({'for':'home.point_gift.show','id':item.gift_id}) %} -

{{ item.gift_name }}({{ item.gift_id }}){{ gift_type_info(item.gift_type) }}

-

用户名称:{{ item.user_name }} ({{ item.user_id }}) 联系方式: - +

{{ item.gift_name }}({{ item.gift_id }}){{ gift_type_info(item.gift_type) }}

+

+ 用户名称:{{ item.user_name }}({{ item.user_id }}) + 联系方式:查看

{{ item.gift_point }} @@ -67,6 +68,12 @@ {% endblock %} +{% block include_js %} + + {{ js_include('admin/js/contact.js') }} + +{% endblock %} + {% block inline_js %} -{% endblock %} - -{% block include_js %} - - {{ js_include('admin/js/contact.js') }} - {% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/refund/list.volt b/app/Http/Admin/Views/refund/list.volt index 972409cd..ced2cf7e 100644 --- a/app/Http/Admin/Views/refund/list.volt +++ b/app/Http/Admin/Views/refund/list.volt @@ -4,12 +4,19 @@ {{ partial('refund/macro') }} + {% set search_url = url({'for':'admin.refund.search'}) %} + diff --git a/app/Http/Admin/Views/refund/search.volt b/app/Http/Admin/Views/refund/search.volt index 0db3df64..eab5c260 100644 --- a/app/Http/Admin/Views/refund/search.volt +++ b/app/Http/Admin/Views/refund/search.volt @@ -21,12 +21,9 @@
- - - - - - + {% for value,title in status_types %} + + {% endfor %}
diff --git a/app/Http/Admin/Views/review/list.volt b/app/Http/Admin/Views/review/list.volt index 3e61817e..5ae6b73d 100644 --- a/app/Http/Admin/Views/review/list.volt +++ b/app/Http/Admin/Views/review/list.volt @@ -2,6 +2,8 @@ {% block content %} + {% set search_url = url({'for':'admin.consult.search'}) %} +
@@ -12,6 +14,11 @@ 评价管理
+
diff --git a/app/Http/Admin/Views/role/list.volt b/app/Http/Admin/Views/role/list.volt index ab2dceab..f4aea8e1 100644 --- a/app/Http/Admin/Views/role/list.volt +++ b/app/Http/Admin/Views/role/list.volt @@ -10,12 +10,19 @@ {% endif %} {%- endmacro %} + {% set add_url = url({'for':'admin.role.add'}) %} +
diff --git a/app/Http/Admin/Views/setting/dingtalk_robot.volt b/app/Http/Admin/Views/setting/dingtalk_robot.volt index acc1ae96..76bb4ab9 100644 --- a/app/Http/Admin/Views/setting/dingtalk_robot.volt +++ b/app/Http/Admin/Views/setting/dingtalk_robot.volt @@ -20,7 +20,7 @@
- +
diff --git a/app/Http/Admin/Views/slide/list.volt b/app/Http/Admin/Views/slide/list.volt index 919d8c0c..d40d6a45 100644 --- a/app/Http/Admin/Views/slide/list.volt +++ b/app/Http/Admin/Views/slide/list.volt @@ -12,12 +12,19 @@ {% endif %} {%- endmacro %} + {% set add_url = url({'for':'admin.slide.add'}) %} +
diff --git a/app/Http/Admin/Views/student/list.volt b/app/Http/Admin/Views/student/list.volt index 16d92f20..c8554604 100644 --- a/app/Http/Admin/Views/student/list.volt +++ b/app/Http/Admin/Views/student/list.volt @@ -8,9 +8,9 @@ {% elseif value == 2 %} 付费 {% elseif value == 3 %} - 导入 + 畅学 {% elseif value == 4 %} - 会员 + 导入 {% elseif value == 5 %} 积分 {% elseif value == 6 %} @@ -18,6 +18,9 @@ {% endif %} {%- endmacro %} + {% set add_url = url({'for':'admin.student.add'}) %} + {% set search_url = url({'for':'admin.student.search'}) %} +
@@ -42,7 +53,7 @@ - + @@ -55,8 +66,8 @@ {% set edit_url = url({'for':'admin.student.edit'},{'relation_id':item.id}) %}
基本信息 学习情况成员来源来源类型 有效期限 操作
-

课程:{{ item.course.title }}({{ item.course.id }})

-

学员:{{ item.user.name }}({{ item.user.id }})

+

课程:{{ item.course.title }}({{ item.course.id }})

+

学员:{{ item.user.name }}({{ item.user.id }})

进度:{{ item.progress }}%

diff --git a/app/Http/Admin/Views/student/search.volt b/app/Http/Admin/Views/student/search.volt index 673da0d3..55fdb461 100644 --- a/app/Http/Admin/Views/student/search.volt +++ b/app/Http/Admin/Views/student/search.volt @@ -23,10 +23,9 @@
- - - - + {% for value,title in source_types %} + + {% endfor %}
diff --git a/app/Http/Admin/Views/topic/list.volt b/app/Http/Admin/Views/topic/list.volt index 295d1484..10290a79 100644 --- a/app/Http/Admin/Views/topic/list.volt +++ b/app/Http/Admin/Views/topic/list.volt @@ -2,12 +2,23 @@ {% block content %} + {% set add_url = url({'for':'admin.topic.add'}) %} + {% set search_url = url({'for':'admin.topic.search'}) %} + diff --git a/app/Http/Admin/Views/topic/search.volt b/app/Http/Admin/Views/topic/search.volt new file mode 100644 index 00000000..7a4c97c5 --- /dev/null +++ b/app/Http/Admin/Views/topic/search.volt @@ -0,0 +1,44 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + +
+ 搜索话题 +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+ + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/trade/list.volt b/app/Http/Admin/Views/trade/list.volt index 92832022..a8177d81 100644 --- a/app/Http/Admin/Views/trade/list.volt +++ b/app/Http/Admin/Views/trade/list.volt @@ -4,12 +4,19 @@ {{ partial('trade/macro') }} + {% set search_url = url({'for':'admin.trade.search'}) %} +
diff --git a/app/Http/Admin/Views/trade/search.volt b/app/Http/Admin/Views/trade/search.volt index 8f8c9a1b..d8bc32f2 100644 --- a/app/Http/Admin/Views/trade/search.volt +++ b/app/Http/Admin/Views/trade/search.volt @@ -21,17 +21,17 @@
- - + {% for value,title in channel_types %} + + {% endfor %}
- - - - + {% for value,title in status_types %} + + {% endfor %}
diff --git a/app/Http/Admin/Views/user/add.volt b/app/Http/Admin/Views/user/add.volt index ab83b88c..c88e85bf 100644 --- a/app/Http/Admin/Views/user/add.volt +++ b/app/Http/Admin/Views/user/add.volt @@ -30,7 +30,7 @@
- {% for role in roles %} + {% for role in admin_roles %} {% if role.id > 1 %} {% endif %} diff --git a/app/Http/Admin/Views/user/edit.volt b/app/Http/Admin/Views/user/edit.volt index 1cd4a31f..5cd94fe7 100644 --- a/app/Http/Admin/Views/user/edit.volt +++ b/app/Http/Admin/Views/user/edit.volt @@ -38,7 +38,7 @@
- {% for role in roles %} + {% for role in admin_roles %} {% if role.id > 1 %} {% endif %} diff --git a/app/Http/Admin/Views/user/list.volt b/app/Http/Admin/Views/user/list.volt index 19eac204..8d164110 100644 --- a/app/Http/Admin/Views/user/list.volt +++ b/app/Http/Admin/Views/user/list.volt @@ -35,12 +35,23 @@ {% endif %} {%- endmacro %} + {% set add_url = url({'for':'admin.user.add'}) %} + {% set search_url = url({'for':'admin.user.search'}) %} +
diff --git a/app/Http/Admin/Views/user/search.volt b/app/Http/Admin/Views/user/search.volt index 3327191a..323adbf6 100644 --- a/app/Http/Admin/Views/user/search.volt +++ b/app/Http/Admin/Views/user/search.volt @@ -21,14 +21,15 @@
- - + {% for value,title in edu_role_types %} + + {% endfor %}
- {% for item in roles %} + {% for item in admin_roles %} {% endfor %}
diff --git a/app/Http/Home/Controllers/ImGroupController.php b/app/Http/Home/Controllers/ImGroupController.php index bde92ad8..cae102d2 100644 --- a/app/Http/Home/Controllers/ImGroupController.php +++ b/app/Http/Home/Controllers/ImGroupController.php @@ -12,7 +12,7 @@ class ImGroupController extends Controller { /** - * @Get("/list", name="home.group.list") + * @Get("/list", name="home.im_group.list") */ public function listAction() { @@ -22,7 +22,7 @@ class ImGroupController extends Controller } /** - * @Get("/pager", name="home.group.pager") + * @Get("/pager", name="home.im_group.pager") */ public function pagerAction() { @@ -38,7 +38,7 @@ class ImGroupController extends Controller } /** - * @Get("/{id:[0-9]+}", name="home.group.show") + * @Get("/{id:[0-9]+}", name="home.im_group.show") */ public function showAction($id) { @@ -53,7 +53,7 @@ class ImGroupController extends Controller } /** - * @Get("/{id:[0-9]+}/users", name="home.group.users") + * @Get("/{id:[0-9]+}/users", name="home.im_group.users") */ public function usersAction($id) { @@ -69,7 +69,7 @@ class ImGroupController extends Controller } /** - * @Get("/{id:[0-9]+}/users/active", name="home.group.active_users") + * @Get("/{id:[0-9]+}/users/active", name="home.im_group.active_users") */ public function activeUsersAction($id) { diff --git a/app/Http/Home/Controllers/PointRedeemController.php b/app/Http/Home/Controllers/PointRedeemController.php index 37b99430..1292a3b6 100644 --- a/app/Http/Home/Controllers/PointRedeemController.php +++ b/app/Http/Home/Controllers/PointRedeemController.php @@ -19,7 +19,7 @@ class PointRedeemController extends Controller $service->handle(); - return $this->jsonSuccess(['msg' => '兑换成功']); + return $this->jsonSuccess(['msg' => '兑换请求提交成功']); } } diff --git a/app/Http/Home/Controllers/UserConsoleController.php b/app/Http/Home/Controllers/UserConsoleController.php index 16f22f8f..de6a035f 100644 --- a/app/Http/Home/Controllers/UserConsoleController.php +++ b/app/Http/Home/Controllers/UserConsoleController.php @@ -44,10 +44,6 @@ class UserConsoleController extends Controller public function initialize() { parent::initialize(); - - $wechatOA = $this->getSettings('wechat.oa'); - - $this->view->setVar('wechat_oa', $wechatOA); } /** diff --git a/app/Http/Home/Services/ImFriendTrait.php b/app/Http/Home/Services/ImFriendTrait.php index 5731397b..4dd492fb 100644 --- a/app/Http/Home/Services/ImFriendTrait.php +++ b/app/Http/Home/Services/ImFriendTrait.php @@ -58,7 +58,7 @@ Trait ImFriendTrait $validator = new ImFriendUserValidator(); - $validator->checkGroup($groupId); + $group = $validator->checkGroup($groupId); $validator = new ImNoticeValidator(); @@ -81,7 +81,7 @@ Trait ImFriendTrait $friendUserModel->create([ 'user_id' => $user->id, 'friend_id' => $sender->id, - 'group_id' => $groupId, + 'group_id' => $group->id, ]); $this->incrUserFriendCount($user); @@ -147,7 +147,9 @@ Trait ImFriendTrait public function quitFriend($id) { - $user = $this->getLoginUser(); + $loginUser = $this->getLoginUser(); + + $user = $this->getImUser($loginUser->id); $validator = new ImFriendUserValidator(); @@ -156,6 +158,8 @@ Trait ImFriendTrait $friendUser = $validator->checkFriendUser($user->id, $friend->id); $friendUser->delete(); + + $this->decrUserFriendCount($user); } protected function handleApplyFriendNotice(ImUserModel $sender, ImUserModel $receiver, ImFriendGroupModel $group, $remark) diff --git a/app/Http/Home/Views/course/show_catalog.volt b/app/Http/Home/Views/course/show_catalog.volt index 445f8feb..b53dc928 100644 --- a/app/Http/Home/Views/course/show_catalog.volt +++ b/app/Http/Home/Views/course/show_catalog.volt @@ -55,23 +55,25 @@ {% endif %} {%- endmacro %} -
- {% for chapter in chapters %} -
-

{{ chapter.title }}

-
-
    - {% for lesson in chapter.children %} - {% if lesson.model == 1 %} -
  • {{ vod_lesson_info(lesson) }}
  • - {% elseif lesson.model == 2 %} -
  • {{ live_lesson_info(lesson) }}
  • - {% elseif lesson.model == 3 %} -
  • {{ read_lesson_info(lesson) }}
  • - {% endif %} - {% endfor %} -
+{% if chapters %} +
+ {% for chapter in chapters %} +
+

{{ chapter.title }}

+
+
    + {% for lesson in chapter.children %} + {% if lesson.model == 1 %} +
  • {{ vod_lesson_info(lesson) }}
  • + {% elseif lesson.model == 2 %} +
  • {{ live_lesson_info(lesson) }}
  • + {% elseif lesson.model == 3 %} +
  • {{ read_lesson_info(lesson) }}
  • + {% endif %} + {% endfor %} +
+
-
- {% endfor %} -
\ No newline at end of file + {% endfor %} +
+{% endif %} \ No newline at end of file diff --git a/app/Http/Home/Views/course/show_meta.volt b/app/Http/Home/Views/course/show_meta.volt index 6355000c..c668df67 100644 --- a/app/Http/Home/Views/course/show_meta.volt +++ b/app/Http/Home/Views/course/show_meta.volt @@ -34,7 +34,9 @@ {%- macro meta_price_info(course) %}

- 原始价格{{ '¥%0.2f'|format(course.origin_price) }} + {% if course.origin_price > 0 %} + 原始价格{{ '¥%0.2f'|format(course.origin_price) }} + {% endif %} {% if course.market_price > 0 %} 优惠价格{{ '¥%0.2f'|format(course.market_price) }} {% else %} diff --git a/app/Http/Home/Views/im/group/active_users.volt b/app/Http/Home/Views/im/group/active_users.volt index 565d0eea..bb215a52 100644 --- a/app/Http/Home/Views/im/group/active_users.volt +++ b/app/Http/Home/Views/im/group/active_users.volt @@ -5,7 +5,7 @@ {% for user in users %} {% set user_url = url({'for':'home.user.show','id':user.id}) %} {% set user.title = user.title ? user.title : '暂露头角' %} -

标题:{{ item.course.title }} {{ model_info(item.course.model) }}

-

期限:{{ date('Y-m-d',item.expiry_time) }}

+

来源:{{ source_type_info(item.source_type) }}  期限:{{ date('Y-m-d',item.expiry_time) }}

用时:{{ item.duration|duration }}

diff --git a/app/Http/Home/Views/user/console/friends.volt b/app/Http/Home/Views/user/console/friends.volt index 8dcd4f61..b1cc764a 100644 --- a/app/Http/Home/Views/user/console/friends.volt +++ b/app/Http/Home/Views/user/console/friends.volt @@ -12,7 +12,7 @@ 我的好友 {% if pager.total_pages > 0 %} - +
diff --git a/app/Http/Home/Views/user/console/groups_joined.volt b/app/Http/Home/Views/user/console/groups_joined.volt index 677041c4..624da3e9 100644 --- a/app/Http/Home/Views/user/console/groups_joined.volt +++ b/app/Http/Home/Views/user/console/groups_joined.volt @@ -16,7 +16,7 @@ {% for item in pager.items %} - {% set show_url = url({'for':'home.group.show','id':item.id}) %} + {% set show_url = url({'for':'home.im_group.show','id':item.id}) %} {% set owner_url = url({'for':'home.user.show','id':item.owner.id}) %} {% set delete_url = url({'for':'home.im.quit_group','id':item.id}) %} diff --git a/app/Http/Home/Views/user/console/menu.volt b/app/Http/Home/Views/user/console/menu.volt index 619692fe..97b6aca5 100644 --- a/app/Http/Home/Views/user/console/menu.volt +++ b/app/Http/Home/Views/user/console/menu.volt @@ -7,6 +7,9 @@ {% endif %} {%- endmacro %} +{% set wechat_oa_enabled = setting('wechat.oa','enabled') %} +{% set point_enabled = setting('point','enabled') %} +
{{ auth_user.name }} @@ -36,16 +39,18 @@
-
-
积分中心
-
- +{% if point_enabled == 1 %} +
+
积分中心
+
-
+{% endif %}
聊天设置
@@ -64,7 +69,7 @@
  • 个人信息
  • 收货地址
  • 帐号安全
  • - {% if wechat_oa.enabled == 1 %} + {% if wechat_oa_enabled == 1 %}
  • 关注订阅
  • {% endif %} diff --git a/app/Http/Home/Views/user/console/point_history.volt b/app/Http/Home/Views/user/console/point_history.volt index b84a8649..b5a3a58e 100644 --- a/app/Http/Home/Views/user/console/point_history.volt +++ b/app/Http/Home/Views/user/console/point_history.volt @@ -33,7 +33,7 @@
    - + {% endfor %} diff --git a/app/Http/Home/Views/user/console/point_redeems.volt b/app/Http/Home/Views/user/console/point_redeems.volt index bb7c3a41..6ee218c0 100644 --- a/app/Http/Home/Views/user/console/point_redeems.volt +++ b/app/Http/Home/Views/user/console/point_redeems.volt @@ -34,7 +34,7 @@ - + {% endfor %} diff --git a/app/Http/Home/Views/user/groups.volt b/app/Http/Home/Views/user/groups.volt index ac88f2bd..cc918c4d 100644 --- a/app/Http/Home/Views/user/groups.volt +++ b/app/Http/Home/Views/user/groups.volt @@ -4,7 +4,7 @@
    {% for item in pager.items %} - {% set group_url = url({'for':'home.group.show','id':item.id}) %} + {% set group_url = url({'for':'home.im_group.show','id':item.id}) %} {% set item.about = item.about ? item.about : '这家伙真懒,什么都没留下!' %}
    diff --git a/app/Library/AppInfo.php b/app/Library/AppInfo.php index cfce4822..b5df7269 100644 --- a/app/Library/AppInfo.php +++ b/app/Library/AppInfo.php @@ -11,7 +11,7 @@ class AppInfo protected $link = 'https://koogua.com'; - protected $version = '1.2.6'; + protected $version = '1.2.7'; public function __get($name) { diff --git a/app/Library/Utils/ServerInfo.php b/app/Library/Utils/ServerInfo.php index 9d89fb94..7fb0b1ed 100644 --- a/app/Library/Utils/ServerInfo.php +++ b/app/Library/Utils/ServerInfo.php @@ -26,16 +26,14 @@ class ServerInfo $total = 0; - if (preg_match('/MemTotal\:\s+(\d+) kB/', $mem, $matches)) { - $total = $matches[1]; + if (preg_match('/MemTotal\:\s+(\d+) kB/', $mem, $totalMatches)) { + $total = $totalMatches[1]; } - unset($matches); - $free = 0; - if (preg_match('/MemFree\:\s+(\d+) kB/', $mem, $matches)) { - $free = $matches[1]; + if (preg_match('/MemFree\:\s+(\d+) kB/', $mem, $freeMatches)) { + $free = $freeMatches[1]; } $usage = $total - $free; diff --git a/app/Models/CourseRating.php b/app/Models/CourseRating.php index a124f798..7e9e9118 100644 --- a/app/Models/CourseRating.php +++ b/app/Models/CourseRating.php @@ -17,28 +17,28 @@ class CourseRating extends Model * * @var float */ - public $rating = 0.00; + public $rating = 5.00; /** * 维度1评分 * * @var float */ - public $rating1 = 0.00; + public $rating1 = 5.00; /** * 维度2评分 * * @var float */ - public $rating2 = 0.00; + public $rating2 = 5.00; /** * 维度3评分 * * @var float */ - public $rating3 = 0.00; + public $rating3 = 5.00; /** * 创建时间 diff --git a/app/Models/CourseUser.php b/app/Models/CourseUser.php index f31c2995..f652fa9d 100644 --- a/app/Models/CourseUser.php +++ b/app/Models/CourseUser.php @@ -18,7 +18,7 @@ class CourseUser extends Model */ const SOURCE_FREE = 1; // 免费 const SOURCE_CHARGE = 2; // 付费 - const SOURCE_VIP = 3; // 会员 + const SOURCE_VIP = 3; // 会员(畅学) const SOURCE_IMPORT = 4; // 导入 const SOURCE_POINT_REDEEM = 5; // 积分兑换 const SOURCE_LUCKY_REDEEM = 6; // 抽奖兑换 diff --git a/app/Repos/Course.php b/app/Repos/Course.php index 43591050..d4b7cabe 100644 --- a/app/Repos/Course.php +++ b/app/Repos/Course.php @@ -180,6 +180,7 @@ class Course extends Repository ->join(CourseUserModel::class, 'u.id = cu.user_id', 'cu') ->where('cu.course_id = :course_id:', ['course_id' => $courseId]) ->andWhere('cu.role_type = :role_type:', ['role_type' => $roleType]) + ->andWhere('cu.deleted = :deleted:', ['deleted' => 0]) ->getQuery()->execute(); } diff --git a/app/Repos/ImFriendGroup.php b/app/Repos/ImFriendGroup.php index cb31a2c4..babbfa09 100644 --- a/app/Repos/ImFriendGroup.php +++ b/app/Repos/ImFriendGroup.php @@ -89,7 +89,7 @@ class ImFriendGroup extends Repository public function countUsers($groupId) { return (int)ImFriendUserModel::count([ - 'conditions' => 'group_id = :group_id: AND blocked = 0', + 'conditions' => 'group_id = :group_id:', 'bind' => ['group_id' => $groupId], ]); } diff --git a/app/Repos/Topic.php b/app/Repos/Topic.php index 14dc3372..dfeebe52 100644 --- a/app/Repos/Topic.php +++ b/app/Repos/Topic.php @@ -21,6 +21,10 @@ class Topic extends Repository $builder->where('1 = 1'); + if (!empty($where['id'])) { + $builder->andWhere('id = :id:', ['id' => $where['id']]); + } + if (!empty($where['title'])) { $builder->andWhere('title LIKE :title:', ['title' => "%{$where['title']}%"]); } diff --git a/app/Services/DingTalk/Notice/ConsultCreate.php b/app/Services/DingTalk/Notice/ConsultCreate.php index 7bb9abf3..87d7e4c8 100644 --- a/app/Services/DingTalk/Notice/ConsultCreate.php +++ b/app/Services/DingTalk/Notice/ConsultCreate.php @@ -14,6 +14,8 @@ class ConsultCreate extends DingTalkNotice public function handleTask(TaskModel $task) { + if (!$this->enabled) return; + $consultRepo = new ConsultRepo(); $consult = $consultRepo->findById($task->item_id); @@ -32,11 +34,13 @@ class ConsultCreate extends DingTalkNotice 'consult.question' => $consult->question, ]); - return $this->atCourseTeacher($course->id, $content); + $this->atCourseTeacher($course->id, $content); } public function createTask(ConsultModel $consult) { + if (!$this->enabled) return; + $keyName = "dingtalk_consult_create_notice:{$consult->owner_id}"; $cache = $this->getCache(); diff --git a/app/Services/DingTalk/Notice/CustomService.php b/app/Services/DingTalk/Notice/CustomService.php index a57483cb..08d0b289 100644 --- a/app/Services/DingTalk/Notice/CustomService.php +++ b/app/Services/DingTalk/Notice/CustomService.php @@ -13,6 +13,8 @@ class CustomService extends DingTalkNotice public function handleTask(TaskModel $task) { + if (!$this->enabled) return; + $messageRepo = new ImMessageRepo(); $message = $messageRepo->findById($task->item_id); @@ -26,11 +28,13 @@ class CustomService extends DingTalkNotice 'message.content' => $message->content, ]); - return $this->atCustomService($content); + $this->atCustomService($content); } public function createTask(ImMessageModel $message) { + if (!$this->enabled) return; + $keyName = "dingtalk_custom_service_notice:{$message->sender_id}"; $cache = $this->getCache(); diff --git a/app/Services/DingTalk/Notice/LiveTeacher.php b/app/Services/DingTalk/Notice/LiveTeacher.php index db20b0cb..e5125f76 100644 --- a/app/Services/DingTalk/Notice/LiveTeacher.php +++ b/app/Services/DingTalk/Notice/LiveTeacher.php @@ -13,6 +13,8 @@ class TeacherLive extends DingTalkNotice public function handleTask(TaskModel $task) { + if (!$this->enabled) return; + $liveRepo = new ChapterLiveRepo(); $live = $liveRepo->findById($task->item_id); @@ -26,11 +28,13 @@ class TeacherLive extends DingTalkNotice 'live.start_time' => date('Y-m-d H:i', $live->start_time), ]); - return $this->atCourseTeacher($course->id, $content); + $this->atCourseTeacher($course->id, $content); } public function createTask(ChapterLiveModel $live) { + if (!$this->enabled) return; + $task = new TaskModel(); $itemInfo = [ diff --git a/app/Services/DingTalk/Notice/PointRedeem.php b/app/Services/DingTalk/Notice/PointRedeem.php index 791db8b1..ec2890d9 100644 --- a/app/Services/DingTalk/Notice/PointRedeem.php +++ b/app/Services/DingTalk/Notice/PointRedeem.php @@ -13,6 +13,8 @@ class PointRedeem extends DingTalkNotice public function handleTask(TaskModel $task) { + if (!$this->enabled) return; + $redeemRepo = new PointRedeemRepo(); $redeem = $redeemRepo->findById($task->item_id); @@ -22,11 +24,13 @@ class PointRedeem extends DingTalkNotice 'gift.name' => $redeem->gift_name, ]); - return $this->atCustomService($content); + $this->atCustomService($content); } public function createTask(PointRedeemModel $redeem) { + if (!$this->enabled) return; + if ($redeem->gift_type != PointGiftModel::TYPE_GOODS) return; $task = new TaskModel(); diff --git a/app/Services/DingTalk/Notice/ServerMonitor.php b/app/Services/DingTalk/Notice/ServerMonitor.php index 3901bafc..10202c95 100644 --- a/app/Services/DingTalk/Notice/ServerMonitor.php +++ b/app/Services/DingTalk/Notice/ServerMonitor.php @@ -10,15 +10,19 @@ class ServerMonitor extends DingTalkNotice public function handleTask(TaskModel $task) { + if (!$this->enabled) return; + $notice = new DingTalkNotice(); $content = $task->item_info['content']; - return $notice->atTechSupport($content); + $notice->atTechSupport($content); } public function createTask($content) { + if (!$this->enabled) return; + $task = new TaskModel(); $itemInfo = ['content' => $content]; diff --git a/app/Services/DingTalkNotice.php b/app/Services/DingTalkNotice.php index fad0c1f0..166cb52c 100644 --- a/app/Services/DingTalkNotice.php +++ b/app/Services/DingTalkNotice.php @@ -2,6 +2,7 @@ namespace App\Services; +use App\Library\Validators\Common as CommonValidator; use App\Repos\Account as AccountRepo; use App\Repos\Course as CourseRepo; use GuzzleHttp\Client as HttpClient; @@ -20,11 +21,18 @@ class DingTalkNotice extends Service */ protected $logger; + /** + * @var bool + */ + protected $enabled; + public function __construct() { $this->settings = $this->getSettings('dingtalk.robot'); $this->logger = $this->getLogger('dingtalk'); + + $this->enabled = $this->settings['enabled'] == 1; } /** @@ -99,11 +107,9 @@ class DingTalkNotice extends Service $account = $accountRepo->findById($course->teacher_id); - if (empty($account->phone)) { - return false; - } + if (empty($account->phone)) return false; - $atMobiles = $account->phone; + $atMobiles = [$account->phone]; $atContent = $this->buildAtContent($content, $atMobiles); @@ -124,19 +130,24 @@ class DingTalkNotice extends Service */ public function send($params) { - if (isset($params['msgtype'])) { + if (!isset($params['msgtype'])) { $params['msgtype'] = 'text'; } - $webHook = "https://oapi.dingtalk.com/robot/send?access_token=%s×tamp=%s&sign=%s"; - $appSecret = $this->settings['app_secret']; $appToken = $this->settings['app_token']; $timestamp = time() * 1000; $data = sprintf("%s\n%s", $timestamp, $appSecret); $sign = urlencode(base64_encode(hash_hmac('sha256', $data, $appSecret, true))); - $postUrl = sprintf($webHook, $appToken, $timestamp, $sign); + + $baseUrl = 'https://oapi.dingtalk.com/robot/send'; + + $postUrl = $baseUrl . '?' . http_build_query([ + 'access_token' => $appToken, + 'timestamp' => $timestamp, + 'sign' => $sign, + ]); try { @@ -178,15 +189,21 @@ class DingTalkNotice extends Service */ protected function parseAtMobiles($mobiles) { - if (empty($mobiles)) { - return []; - } + if (empty($mobiles)) return []; + + $mobiles = str_replace([',', '|', '|'], ',', $mobiles); $mobiles = explode(',', $mobiles); - return array_map(function ($mobile) { - return trim($mobile); - }, $mobiles); + $result = []; + + foreach ($mobiles as $mobile) { + if (CommonValidator::phone($mobile)) { + $result[] = $mobile; + } + } + + return $result; } /** @@ -196,9 +213,7 @@ class DingTalkNotice extends Service */ protected function buildAtContent($content, $mobiles = []) { - if (count($mobiles) == 0) { - return $content; - } + if (empty($mobiles)) return $content; $result = ''; diff --git a/app/Services/Logic/User/CourseList.php b/app/Services/Logic/User/CourseList.php index 431ad8ba..1ef41939 100644 --- a/app/Services/Logic/User/CourseList.php +++ b/app/Services/Logic/User/CourseList.php @@ -58,6 +58,7 @@ class CourseList extends Service 'progress' => $relation['progress'], 'duration' => $relation['duration'], 'reviewed' => $relation['reviewed'], + 'source_type' => $relation['source_type'], 'expiry_time' => $relation['expiry_time'], 'create_time' => $relation['create_time'], 'course' => $course, diff --git a/app/Validators/ImFriendGroup.php b/app/Validators/ImFriendGroup.php index 6d6d7450..5746d067 100644 --- a/app/Validators/ImFriendGroup.php +++ b/app/Validators/ImFriendGroup.php @@ -3,14 +3,14 @@ namespace App\Validators; use App\Exceptions\BadRequest as BadRequestException; -use App\Repos\ImGroup as ImGroupRepo; +use App\Repos\ImFriendGroup as ImFriendGroupRepo; class ImFriendGroup extends Validator { public function checkGroup($id) { - $groupRepo = new ImGroupRepo(); + $groupRepo = new ImFriendGroupRepo(); $group = $groupRepo->findById($id); diff --git a/db/migrations/20210215024511_data_202102151130.php b/db/migrations/20210215024511_data_202102151130.php index e2d0fde5..60a959dd 100644 --- a/db/migrations/20210215024511_data_202102151130.php +++ b/db/migrations/20210215024511_data_202102151130.php @@ -34,6 +34,8 @@ class Data202102151130 extends Phinx\Migration\AbstractMigration ]; $this->table('kg_setting')->insert($rows)->save(); + + $this->updateImGroupRouter(); } public function down() @@ -44,4 +46,25 @@ class Data202102151130 extends Phinx\Migration\AbstractMigration ->execute(); } + protected function updateImGroupRouter() + { + $roles = $this->getQueryBuilder() + ->select('*') + ->from('kg_role') + ->execute(); + + if ($roles->count() == 0) return; + + foreach ($roles as $role) { + if (strpos($role['routes'], 'admin.group') !== false) { + $routes = str_replace('admin.group', 'admin.im_group', $role['routes']); + $this->getQueryBuilder() + ->update('kg_role') + ->set(['routes' => $routes]) + ->where(['id' => $role['id']]) + ->execute(); + } + } + } + } From 7f3717094e5b9691bae571708aa0d66bbea068c1 Mon Sep 17 00:00:00 2001 From: koogua Date: Fri, 26 Feb 2021 10:35:43 +0800 Subject: [PATCH 08/10] =?UTF-8?q?=E5=89=8D=E5=8F=B0=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=E9=83=A8=E4=BB=B6=E6=98=BE=E7=A4=BA=E5=A2=9E=E5=8A=A0=E9=9D=9E?= =?UTF-8?q?=E7=A9=BA=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Home/Views/index/full.volt | 72 +++++++++++++++------------ app/Http/Home/Views/index/simple.volt | 72 +++++++++++++++------------ 2 files changed, 82 insertions(+), 62 deletions(-) diff --git a/app/Http/Home/Views/index/full.volt b/app/Http/Home/Views/index/full.volt index 00786429..2879f5fd 100644 --- a/app/Http/Home/Views/index/full.volt +++ b/app/Http/Home/Views/index/full.volt @@ -31,47 +31,57 @@
    {%- endmacro %} -
    - + {% if item.id == 1 %} + + {% else %} + + {% endif %}
    {{ event_type_info(item.event_type) }} {{ event_point_info(item.event_point) }} {{ event_detail_info(item) }}{{ date('Y-m-d H:i',item.create_time) }}{{ date('Y-m-d',item.create_time) }}
    {{ item.gift.name }} {{ gift_type_info(item.gift.type) }} {{ item.gift.point }} {{ redeem_status_info(item.status) }}{{ date('Y-m-d H:i',item.create_time) }}{{ date('Y-m-d',item.create_time) }}
    {{ item.id }}{{ item.name }}{{ item.name }}{{ item.name }}{{ type_info(item.type) }} @@ -61,11 +65,16 @@
    diff --git a/app/Http/Home/Views/index/full.volt b/app/Http/Home/Views/index/full.volt index 00786429..2879f5fd 100644 --- a/app/Http/Home/Views/index/full.volt +++ b/app/Http/Home/Views/index/full.volt @@ -31,47 +31,57 @@ {%- endmacro %} -