From 475908089fdb05b0771f2a59d845be8313b6d72a Mon Sep 17 00:00:00 2001 From: LittleJake <465917717@qq.com> Date: Sun, 24 May 2020 09:45:39 +0800 Subject: [PATCH 1/9] update --- .gitignore | 7 + .travis.yml | 42 + CHANGELOG.md | 927 ++++++++++++++++++ LICENSE | 2 +- LICENSE.txt | 32 + application/.htaccess | 1 + application/admin/controller/Index.php | 85 ++ application/api/controller/Stat.php | 85 ++ application/command.php | 12 + application/common.php | 12 + application/http/middleware/FlowControll.php | 10 + application/index/controller/Base.php | 85 ++ application/index/controller/Index.php | 38 + application/index/view/index/index.html | 17 + application/index/view/index/info.html | 174 ++++ application/provider.php | 14 + application/tags.php | 28 + build.php | 26 + composer.json | 33 + composer.lock | 124 +++ config/.gitignore | 2 + config/app.php | 146 +++ config/cache.php.bak | 28 + config/console.php | 20 + config/cookie.php | 30 + config/database.php | 63 ++ config/log.php | 30 + config/middleware.php | 18 + config/secret.php | 12 + config/session.php | 26 + config/template.php | 35 + config/trace.php | 18 + extend/.gitignore | 2 + public/.htaccess | 8 + public/favicon.ico | Bin 0 -> 1150 bytes public/index.php | 21 + public/js/progressbar.js/progressbar.min.js | 6 + .../js/progressbar.js/progressbar.min.js.map | 1 + public/robots.txt | 2 + public/router.php | 17 + public/static/.gitignore | 2 + route/route.php | 20 + runtime/.gitignore | 2 + think | 22 + 44 files changed, 2284 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 LICENSE.txt create mode 100644 application/.htaccess create mode 100644 application/admin/controller/Index.php create mode 100644 application/api/controller/Stat.php create mode 100644 application/command.php create mode 100644 application/common.php create mode 100644 application/http/middleware/FlowControll.php create mode 100644 application/index/controller/Base.php create mode 100644 application/index/controller/Index.php create mode 100644 application/index/view/index/index.html create mode 100644 application/index/view/index/info.html create mode 100644 application/provider.php create mode 100644 application/tags.php create mode 100644 build.php create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 config/.gitignore create mode 100644 config/app.php create mode 100644 config/cache.php.bak create mode 100644 config/console.php create mode 100644 config/cookie.php create mode 100644 config/database.php create mode 100644 config/log.php create mode 100644 config/middleware.php create mode 100644 config/secret.php create mode 100644 config/session.php create mode 100644 config/template.php create mode 100644 config/trace.php create mode 100644 extend/.gitignore create mode 100644 public/.htaccess create mode 100644 public/favicon.ico create mode 100644 public/index.php create mode 100644 public/js/progressbar.js/progressbar.min.js create mode 100644 public/js/progressbar.js/progressbar.min.js.map create mode 100644 public/robots.txt create mode 100644 public/router.php create mode 100644 public/static/.gitignore create mode 100644 route/route.php create mode 100644 runtime/.gitignore create mode 100644 think diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2b6f52c --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +/.idea +/.vscode +/vendor +*.log +thinkphp +.env +.DS_Store diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..36f7b6f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,42 @@ +sudo: false + +language: php + +branches: + only: + - stable + +cache: + directories: + - $HOME/.composer/cache + +before_install: + - composer self-update + +install: + - composer install --no-dev --no-interaction --ignore-platform-reqs + - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip . + - composer require --update-no-dev --no-interaction "topthink/think-image:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0" + - composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0" + - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip . + +script: + - php think unit + +deploy: + provider: releases + api_key: + secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw= + file: + - ThinkPHP_Core.zip + - ThinkPHP_Full.zip + skip_cleanup: true + on: + tags: true diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e320da4 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,927 @@ +## V5.1.39 LTS(2019-11-18) + +本次更新为常规更新,主要包括: + +* 修正`memcached`驱动 +* 改进`HasManyThrough`关联查询 +* 改进`Request`类`isJson`方法 +* 改进关联查询 +* 改进`redis`驱动 +* 增加 Model类`getWhere`方法对复合主键的支持 +* 改进`newQuery`方法 +* 改进闭包查询的参数绑定 +* 修正`Validate` +* 修复某些情况下URL会多一个冒号 +* 调整composer.json +* 修复使用`Cache::clear()`时,报错缓存文件不存在问题 +* 使用File类的unlink方法进行文件删除 +* 改进`paraseData`方法 +* 修正image验证方法 +* 改进Url生成 +* 改进空操作对数字的支持 +* 改进一处PHP7.4兼容性问题 + +## V5.1.38 LTS(2019-8-8) + +本次更新为常规更新,主要包括: + +* `Request`类增加`isJson`方法 +* 改进浮点型查询 +* 修正关联查询关联外键为空的查询错误 +* 远程一对多支持关联统计和预载入查询 +* 远程一对多关联支持`has`/`hasWhere`查询 +* 优化`parseIn`解析 +* 改进`parseLike`查询 +* 改进Url生成 +* 改进模型的`toArray`方法 +* 修正`notIn`查询 +* 改进`JSON`字段查询 +* 改进Controller类`display`/`fetch`方法返回`ViewResponse`对象 +* 改进`param`方法 +* 改进`mysql`驱动`getExplain`方法 +* 改进时间查询 +* 改进模型关联的`has`/`hasWhere`方法对软删除的支持 +* 修正社区反馈的BUG + +## V5.1.37 LTS(2019-5-26) + +本次更新为常规更新,主要更新如下: + +* 改进关联数据更新 +* 修正关联动态获取器 +* 改进`redis`驱动 +* 修复验证规则里面出现二维数组时的错误 +* 改进跨域请求支持 +* 完善模型`hidden`方法对关联属性的支持 +* 改进`where`查询方法传入`Query`对象的支持`bind`数据 +* 改进数据集对象的`load`方法 +* 修正缓存类`clear`方法对`tag`的支持 + +## V5.1.36 LTS(2019-4-28) + +本次更新为常规更新,主要更新如下: + +* 修正`chunk`方法一处异常抛出的错误 +* 修正模型输出的`visible` +* 改进环境变量加载 +* 改进命令行日志的`level`配置支持 +* 修复设置有缓存前缀时,无法清空缓存标签的问题 +* HasMony对象`saveAll`方法兼容`Collection`格式参数格式 +* 修正`whereOr`查询使用字符串的问题 +* 改进`dateFormat`设置对写入数据的影响 +* 修正查询缓存 +* 记住指定的跳转地址 +* 改进软删除 +* 改进聚合查询SQL去除limit 1 +* 改进缓存驱动 + +## V5.1.35 LTS(2019-3-2) + +本次主要为常规更新,修正了一些反馈的问题。 + +* 修正验证类自定义验证方法执行两次的问题 +* 模型增加`isEmpty`方法用于判断是否空模型 +* 改进获取器对`append`的支持 +* 修正一对多关联的`withCount`自关联问题 +* facade类注释调整 +* 改进关联属性的`visible`和`hidden`判断 +* 修正路由分组的`MISS`路由 +* 改进pgsql.sql + +## V5.1.34 LTS(2019-1-30) + +本次更新为常规更新,修正了一些反馈的问题。 + +* 改进Request类的`has`方法,支持`patch` +* 改进`unique`验证的多条件支持 +* 修复自定义上传验证,检测文件大小 +* 改进`in`查询支持表达式 +* 改进路由的`getBind`方法 +* 改进验证类的错误信息获取 +* 改进`response`助手函数默认值 +* 修正mysql的`regexp`查询 +* 改进模型类型强制转换写入对`Expression`对象的支持 + +## V5.1.33 LTS(2019-1-16) + +* 修复路由中存在多个相同替换的正则BUG +* 修正whereLike查询 +* join方法支持参数绑定 +* 改进union方法 +* 修正多对多关联的attach方法 +* 改进验证类的正则规则自定义 +* 改进Request类method方法 +* 改进File日志类型的CLI日志写入 +* 改进文件日志time_format配置对JSON格式的支持 + +## V5.1.32 LTS(2018-12-24) + +本次主要为常规更新,修正了一些反馈的问题。 + + +* 改进多对多关联的`attach`方法 +* 改进聚合查询的`field`处理 +* 改进关联的`save`方法 +* 修正模型`exists`方法返回值 +* 改进时间字段写入和输出 +* 改进控制器中间件的调用 +* 改进路由变量替换的性能 +* 改进缓存标签的处理机制 + +## V5.1.31 LTS (2018-12-9) + +本次版本包含一个安全更新,建议升级。 + +* 改进`field`方法 +* 改进`count`方法返回类型 +* `download`函数增加在浏览器中显示文件功能 +* 修正多对多模型的中间表数据写入 +* 改进`sqlsrv`驱动支持多个Schemas模式查询 +* 统一助手函数与\think\response\Download函数文件过期时间 +* 完善关联模型的`save`方法 增加`make`方法仅创建对象不保存 +* 修改条件表达式对静态变量的支持 +* 修正控制器名获取 +* 改进view方法的`field`解析 + +## V5.1.30 LTS(2018-11-30) + +该版本为常规更新,修正了一些社区反馈的问题。 + +主要更新如下: + +* 改进查询类的`execute`方法 +* 判断路由规则定义添加对请求类型的判断 +* 修复`orderRaw`异常 +* 修正 `optimize:autoload`指令 +* 改进软删除的`destroy`方法造成重复执行事件的问题 +* 改进验证类对扩展验证规则 始终验证 不管是否`require` +* 修复自定义验证`remove`所有规则的异常 +* 改进时间字段的自动写入支持微秒数据 +* 改进`Connection`类的`getrealsql`方法 +* 修正`https`地址的URL生成 +* 修复 `array_walk_recursive` 在低于PHP7.1消耗内部指针问题 +* 改进手动参数绑定使用 +* 改进聚合查询方法的`field`参数支持`Expression` + +## V5.1.29 LTS(2018-11-11) + +该版本主要改进了参数绑定的解析问题和提升性能,并修正了一些反馈的问题。 + +* 改进手动参数绑定 +* 修正MISS路由的分组参数无效问题 +* 行为支持对象的方法 +* 修正全局查询范围 +* 改进`belongsto`关联的`has`方法 +* 改进`hasMany`关联 +* 改进模型观察者多次注册的问题 +* 改进`query`类的默认查询参数处理 +* 修正`parseBetween`解析方法 +* 改进路由地址生成的本地域名支持 +* 改进参数绑定的实际URL解析性能 +* 改进`Env`类的`getEnv`和`get`方法 +* 改进模板缓存的生成优化 +* 修复验证类的多语言支持 +* 修复自定义场景验证`remove`规则异常 +* File类添加是否自动补全扩展名的选项 +* 改进`strpos`对子串是否存在的判断 +* 修复`choice`无法用值选择第一个选项问题 +* 验证器支持多维数组取值验证 +* 改进解析`extend`和`block`标签的正则 + +## V5.1.28 LTS(2018-10-29) + +该版本主要修正了上一个版本存在的一些问题,并改进了关联查询 + +* 改进聚合查询方法的字段支持DISTINCT +* 改进定义路由后url函数的端口生成 +* 改进控制器中间件对`swoole`等的支持 +* 改进Log类`save`方法 +* 改进验证类的闭包验证参数 +* 多对多关联支持指定中间表数据的名称 +* 关联聚合查询支持闭包方式指定聚合字段 +* 改进Lang类`get`方法 +* 多对多关联增加判断关联数据是否存在的方法 +* 改进关联查询使用`fetchsql`的情况 +* 改进修改器的是否已经执行判断 +* 增加`afterWith`和`beforeWith`验证规则 用于比较日期字段 + +## V5.1.27 LTS(2018-10-22) + +该版本主要修正了路由绑定的参数,改进了修改器的执行多次问题,并正式宣布为LTS版本! + + +* 修正路由绑定的参数丢失问题 +* 修正路由别名的参数获取 +* 改进修改器会执行多次的问题 + +## V5.1.26(2018-10-12) + +该版本主要修正了上一个版本的一些问题,并改进了全局查询范围的支持,同时包含了一个安全更新。 + + +* 修正单一模块下注解路由无效的问题 +* 改进数据库的聚合查询的字段处理 +* 模型类增加`globalScope`属性定义 用于指定全局的查询范围 +* 模型的`useGlobalScope`方法支持传入数组 用于指定当前查询需要使用的全局查询范围 +* 改进数据集的`order`方法对数字类型的支持 +* 修正上一个版本`order`方法解析的一处BUG +* 排序字段不合法或者错误的时候抛出异常 +* 改进`Request`类的`file`方法对上传文件的错误判断 + +## V5.1.25(2018-9-21) + +该版本主要改进了查询参数绑定的性能和对浮点型的支持,以及一些细节的完善。 + +* 修正一处命令行问题 +* 改进`Socketlog`日志驱动,支持自定义默认展开日志类别 +* 修正`MorphMany`一处bug +* 跳转到上次记住的url,并支持默认值 +* 改进模型的异常提示 +* 改进参数绑定对浮点型的支持 +* 改进`order`方法解析 +* 改进`json`字段数据的自动编码 +* 改进日志`log_write`可能造成的日志写入死循环 +* Log类增加`log_level`行为标签位置,用于对某个类型的日志进行处理 +* Route类增加`clear`方法清空路由规则 +* 分布式数据库配置支持使用数组 +* 单日志文件也支持`max_files`参数 +* 改进查询参数绑定的性能 +* 改进别名路由的URL后缀参数检测 +* 控制器前置方法和控制器中间件的`only`和`except`定义不区分大小写 + +## V5.1.24(2018-9-5) + +该版本主要增加了命令行的表格输出功能,并增加了查看路由定义的指令,以及修正了社区的一些反馈问题。 + +* 修正`Request`类的`file`方法 +* 修正路由的`cache`方法 +* 修正路由缓存的一处问题 +* 改进上传文件获取的异常处理 +* 改进`fetchCollection`方法支持传入数据集类名 +* 修正多级控制器的注解路由生成 +* 改进`Middleware`类`clear`方法 +* 增加`route:list`指令用于[查看定义的路由](752690) 并支持排序 +* 命令行增加`Table`输出类 +* `Command`类增加`table`方法用于输出表格 +* 改进搜索器查询方法支持别名定义 +* 命令行配置增加`auto_path`参数用于定义自动载入的命令类路径 +* 增加`make:command`指令用于[快速生成指令](354146) +* 改进`make:controller`指令对操作方法后缀的支持 +* 改进命令行的定义文件支持索引数组 用于指令对象的惰性加载 +* 改进`value`和`column`方法对后续查询结果的影响 +* 改进`RuleName`类的`setRule`方法 + +## V5.1.23(2018-8-23) + +该版本主要改进了数据集对象的处理,增加了`findOrEmpty`方法,并且修正了一些社区反馈的BUG。 + +* 数据集类增加`diff`/`intersect`方法用于获取差集和交集(默认根据主键值比较) +* 数据集类增加`order`方法支持指定字段排序 +* 数据集类增加`map`方法使用回调函数处理数据并返回新的数据集对象 +* Db增加`allowEmpty`方法允许`find`方法在没有数据的时候返回空数组或者空模型对象而不是null +* Db增加`findOrEmpty`方法 +* Db增加`fetchCollection`方法用于指定查询返回数据集对象 +* 改进`order`方法的数组方式解析,增强安全性 +* 改进`withSearch`方法,支持第三个参数传入字段前缀标识,用于多表查询字段搜索 +* 修正`optimize:route`指令开启类库后缀后的注解路由生成 +* 修正redis缓存及session驱动 +* 支持指定`Yaconf`的独立配置文件 +* 增加`yaconf`助手函数用于配置文件 + + +## V5.1.22(2018-8-9) + +该版本主要增加了模型搜索器和`withJoin`方法,完善了模型输出和对`Yaconf`的支持,修正了一些社区反馈的BUG。 + +* 改进一对一关联的`table`识别问题 +* 改进内置`Facade`类 +* 增加`withJoin`方法支持`join`方式的[一对一关联](一对一关联.md)查询 +* 改进`join`预载入查询的空数据问题 +* 改进`Config`类的`load`方法支持快速加载配置文件 +* 改进`execute`方法和事务的断线重连 +* 改进`memcache`驱动的`has`方法 +* 模型类支持定义[搜索器](搜索器.md)方法 +* 完善`Config`类对`Yaconf`的支持 +* 改进模型的`hidden/visible/append/withAttr`方法,支持在[查询前后调用](数组访问.md),以及支持数据集对象 +* 数据集对象增加`where`方法根据字段或者关联数据[过滤数据](模型数据集.md) +* 改进AJAX请求的`204`判断 + + +## V5.1.21(2018-8-2) + +该版本主要增加了下载响应对象和数组查询对象的支持,并修正了一些社区反馈的问题。 + +* 改进核心对象的无用信息调试输出 +* 改进模型的`isRelationAttr`方法判断 +* 模型类的`get`和`all`方法并入Db类 +* 增加[下载响应对象](文件下载.md)和`download`助手函数 +* 修正别名路由配置定义读取 +* 改进`resultToModel`方法 +* 修正开启类库后缀后的注解路由生成 +* `Response`类增加`noCache`快捷方法 +* 改进路由对象在`Swoole`/`Workerman`下面参数多次合并问题 +* 修正路由`ajax`/`pjax`参数后路由变量无法正确获取的问题 +* 增加清除中间件的方法 +* 改进依赖注入的参数规范自动识别(便于对接前端小写+下划线规范) +* 改进`hasWhere`的数组条件的字段判断 +* 增加[数组查询对象](高级查询.md)`Where`支持(喜欢数组查询的福音) +* 改进多对多关联的闭包支持 + +## V5.1.20(2018-7-25) + +该版本主要增加了Db和模型的动态获取器的支持,并修正了一些已知问题。 + +* Db类添加[获取器支持](703981) +* 支持模型及关联模型字段[动态定义获取器](354046) +* 动态获取器支持`JSON`字段 +* 改进路由的`before`行为执行(匹配后执行) +* `Config`类支持`Yaconf` +* 改进Url生成的端口问题 +* Request类增加`setUrl`和`setBaseUrl`方法 +* 改进页面trace的信息显示 +* 修正`MorphOne`关联 +* 命令行添加[查看版本指令](703994) + +## V5.1.19 (2018-7-13) + +该版本是一个小幅改进版本,针对`Swoole`和`Workerman`的`Cookie`支持做了一些改进,并修正了一些已知的问题。 + + +* 改进query类`delete`方法对软删除条件判断 +* 修正分表查询的软删除问题 +* 模型查询的时候同时传入`table`和`name`属性 +* 容器类增加`IteratorAggregate`和`Countable`接口支持 +* 路由分组支持对下面的资源路由统一设置`only/except/vars`参数 +* 改进Cookie类更好支持扩展 +* 改进Request类`post`方法 +* 改进模型自关联的自动识别 +* 改进Request类对`php://input`数据的处理 + + +## V5.1.18 (2018-6-30) + +该版本主要完善了对`Swoole`和`Workerman`的`HttpServer`运行支持,改进`Request`类,并修正了一些已知的问题。 + +* 改进关联`append`方法的处理 +* 路由初始化和检测方法分离 +* 修正`destroy`方法强制删除 +* `app_init`钩子位置移入`run`方法 +* `think-swoole`扩展更新到2.0版本 +* `think-worker`扩展更新到2.0版本 +* 改进Url生成的域名自动识别 +* `Request`类增加`setPathinfo`方法和`setHost`方法 +* `Request`类增加`withGet`/`withPost`/`withHeader`/`withServer`/`withCookie`/`withEnv`方法进行赋值操作 +* Route类改进`host`属性的获取 +* 解决注解路由配置不生效的问题 +* 取消Test日志驱动,改为使用`close`设置关闭全局日志写入 +* 修正路由的`response`参数 +* 修正204响应输出的判断 + +## V5.1.17 (2018-6-18) + +该版本主要增加了控制器中间件的支持,改进了路由功能,并且修正了社区反馈的一些问题。 + +* 修正软删除的`delete`方法 +* 修正Query类`Count`方法 +* 改进多对多`detach`方法 +* 改进Request类`Session`方法 +* 增加控制器中间件支持 +* 模型类增加`jsonAssoc`属性用于定义json数据是否返回数组 +* 修正Request类`method`方法的请求伪装 +* 改进静态路由的匹配 +* 分组首页路由自动完整匹配 +* 改进sqlsrv的`column`方法 +* 日志类的`apart_level`配置支持true自动生成对应类型的日志文件 +* 改进`204`输出判断 +* 修正cli下页面输出的BUG +* 验证类使用更高效的`ctype`验证机制 +* 改进Request类`cookie`方法 +* 修正软删除的`withTrashed`方法 +* 改进多态一对多的预载入查询 +* 改进Query类`column`方法的缓存读取 +* Query类增加`whereBetweenTimeField`方法 +* 改进分组下多个相同路由规则的合并匹配问题 +* 路由类增加`getRule`/`getRuleList`方法获取定义的路由 + +## V5.1.16 (2018-6-7) + +该版本主要修正了社区反馈的一些问题,并对Request类做了进一步规范和优化。 + +* 改进Session类的`boot`方法 +* App类的初始化方法可以单独执行 +* 改进Request类的`param`方法 +* 改进资源路由的变量替换 +* Request类增加`__isset`方法 +* 改进`useGlobalScope`方法对软删除的影响 +* 修正命令行调用 +* 改进Cookie类`init`方法 +* 改进多对多关联删除的返回值 +* 一对多关联写入支持`replace` +* 路由增加`filter`检测方法,用于通过请求参数检测路由是否匹配 +* 取消Request类`session/env/server`方法的`filter`参数 +* 改进关联的指定属性输出 +* 模型删除操作删除后不清空对象数据仅作标记 +* 调整模型的`save`方法返回值为布尔值 +* 修正Request类`isAjax`方法 +* 修正中间件的模块配置读取 +* 取消Request类的请求变量的设置功能 +* 取消请求变量获取的默认修饰符 +* Request类增加`setAction/setModule/setController`方法 +* 关联模型的`delete`方法调用Query类 +* 改进URL生成的域名识别 +* 改进URL检测对已定义路由的域名判断 +* 模型类增加`isExists`和`isForce`方法 +* 软删除的`destroy`和`restore`方法返回值调整为布尔值 + +## V5.1.15 (2018-6-1) + +该版本主要改进了路由缓存的性能和缓存方式设置,增加了JSON格式文件日志的支持,并修正了社区反馈的一些问题。 + +* 容器类增加`exists`方法 仅判断是否存在对象实例 +* 取消配置类的`autoload`方法 +* 改进路由缓存大小提高性能 +* 改进Dispatch类`init`方法 +* 增加`make:validate`指令生成验证器类 +* Config类`get`方法支持默认值参数 +* 修正字段缓存指令 +* 改进App类对`null`数据的返回 +* 改进模型类的`__isset`方法判断 +* 修正`Query`类的`withAggregate`方法 +* 改进`RuleItem`类的`setRuleName`方法 +* 修正依赖注入和参数的冲突问题 +* 修正Db类对第三方驱动的支持 +* 修正模型类查询对象问题 +* 修正File缓存驱动的`has`方法 +* 修正资源路由嵌套 +* 改进Request类对`$_SERVER`变量的读取 +* 改进请求缓存处理 +* 路由缓存支持指定单独的缓存方式和参数 +* 修正资源路由的中间件多次执行问题 +* 修正`optimize:config`指令 +* 文件日志支持`JSON`格式日志保存 +* 修正Db类`connect`方法 +* 改进Log类`write`方法不会自动写入之前日志 +* 模型的关联操作默认启用事务 +* 改进软删除的事件响应 + +## V5.1.14 (2018-5-18) + +该版本主要对底层容器进行了一些优化改进,并增加了路由缓存功能,可以进一步提升路由性能。 + +* 依赖注入的对象参数传入改进 +* 改进核心类的容器实例化 +* 改进日期字段的读取 +* 改进验证类的`getScene`方法 +* 模型的`create`方法和`save`方法支持`replace`操作 +* 改进`Db`类的调用机制 +* App类调整为容器类 +* 改进容器默认绑定 +* `Loader`类增加工厂类的实例化方法 +* 增加路由变量默认规则配置参数 +* 增加路由缓存设计 +* 错误处理机制改进 +* 增加清空路由缓存指令 + + +## V5.1.13 (2018-5-11) + +该版本主要增加了MySQL的XA事务支持,模型事件支持观察者,以及对Facade类的改进。 + +* 改进自动缓存 +* 改进Url生成 +* 修正数据缓存 +* 修正`value`方法的缓存 +* `join`方法和`view`方法的条件支持使用`Expression`对象 +* 改进驱动的`parseKey`方法 +* 改进Request类`host`方法和`domain`方法对端口的处理 +* 模型增加`withEvent`方法用于控制当前操作是否需要执行模型事件 +* 模型`setInc/setDec`方法支持更新事件 +* 模型添加`before_restore/after_restore`事件 +* 增加模型事件观察者 +* 路由增加`mobile`方法设置是否允许手机访问 +* 数据库XA事务支持 +* 改进索引数组查询对`IN`查询的支持 +* 修正`invokeMethod`方法 +* 修正空数据写入返回值的BUG +* redis驱动支持`predis` +* 改进`parseData`方法 +* 改进模块加载 +* App类初始化方法调整 +* 改进数组查询对表达式`Expression`对象支持 +* 改进闭包的依赖注入调用 +* 改进多对多关联的中间表模型更新 +* 增加容器中对象的自定义实例化 + +## V5.1.12 (2018-4-25) + +该版本主要改进了主从查询的及时性,并支持动态设置请求数据。 + +* 支持动态设置请求数据 +* 改进`comment`方法解析 +* 修正App类`__unset`方法 +* 改进url生成的域名绑定 +* 改进主从查询的及时性 +* 修正`value`的数据缓存功能 +* 改进分页类的集合对象方法调用 +* 改进Db类的代码提示 +* SQL日志增加主从标记 + +## V5.1.11 (2018-4-19) + +该版本为安全和修正版本,改进了JSON查询的参数绑定问题和容器类对象实例获取,并包含一处可能的安全隐患,建议更新。 + +* 支持指定JSON数据查询的字段类型 +* 修正`selectInsert`方法 +* `whereColumn`方法支持数组方式 +* 改进容器类`make`方法 +* 容器类`delete`方法支持数组 +* 改进`composer`自动加载 +* 改进模板引擎 +* 修正`like`查询的一处安全隐患 + +## V5.1.10 (2018-4-16) + +该版本为修正版本,修正上一个版本的一些BUG,并增强了`think clear`指令。 + +* 改进`orderField`方法 +* 改进`exists`查询 +* 修改cli模式入口文件位置计算 +* 修正`null`查询 +* 改进`parseTime`方法 +* 修正关联预载入查询 +* 改进`mysql`驱动 +* 改进`think clear`指令 支持 `-c -l -r `选项 +* 改进路由规则对`/`结尾的支持 + +## V5.1.9 (2018-4-12) + +该版本主要是一些改进和修正,并包含一个安全更新,是一个推荐更新版本。 + +* 默认模板渲染规则支持配置保持操作方法名 +* 改进`Request`类的`ip`方法 +* 支持模型软删除字段的默认值定义 +* 改进路由变量规则对中文的支持 +* 使用闭包查询的时候使用`cache(true)` 抛出异常提示 +* 改进`Loader`类`loadComposerAutoloadFiles`方法 +* 改进查询方法安全性 +* 修正路由地址中控制器名驼峰问题 +* 调整上一个版本的`module_init`和`app_begin`的钩子顺序问题 +* 改进CLI命令行执行的问题 +* 修正社区反馈的其它问题 + +## V5.1.8 (2018-4-5) + +该版本主要改进了中间件的域名和模块支持,并同时修正了几个已知问题。 + +* 增加`template.auto_rule` 参数设置默认模板渲染的操作名自动转换规则 +* 默认模板渲染规则改由视图驱动实现 +* 修正路由标识定义 +* 修正控制器路由方法 +* 改进Request类`ip`方法支持自定义代理IP参数 +* 路由注册中间件支持数组方式别名 +* 改进命令行执行下的`composer`自动加载 +* 添加域名中间件注册支持 +* 全局中间件支持模块定义文件 +* Log日志配置支持`close`参数可以全局关闭日志写入 +* 中间件方法中捕获`HttpResponseException`异常 +* 改进中间件的闭包参数传入 +* 改进分组路由的延迟解析 +* 改进URL生成对域名绑定的支持 +* 改进文件缓存和文件日志驱动的并发支持 + +## V5.1.7 (2018-3-28) + +该版本主要修正了路由的一些问题,并改进了查询的安全性。 + +* 支持`middleware`配置文件预先定义中间件别名方便路由调用 +* 修正资源路由 +* 改进`field`方法 自动识别`fieldRaw` +* 增加`Expression`类 +* Query类增加`raw`方法 +* Query类的`field`/ `order` 和` where`方法都支持使用`raw`表达式查询 +* 改进`inc/dec`查询 支持批量更新 +* 改进路由分组 +* 改进Response类`create`方法 +* 改进composer自动加载 +* 修正域名路由的`append`方法 +* 修正操作方法的初始化方法获取不到问题 + +## V5.1.6 (2018-3-26) + +该版本主要改进了路由规则的匹配算法,大幅提升了路由性能。并正式引入了中间件的支持,可以在路由中定义或者全局定义。另外包含了一个安全更新,是一个建议更新版本。 + +* 改进URL生成对路由`ext`方法的支持 +* 改进查询缓存对不同数据库相同表名的支持 +* 改进composer自动加载的性能 +* 改进空路由变量对默认参数的影响 +* mysql的`json`字段查询支持多级 +* Query类增加`option`方法 +* 优化路由匹配 +* 修复验证规则数字键名丢失问题 +* 改进路由Url生成 +* 改进一对一关联预载入查询 +* Request类增加`rootDomain`方法 +* 支持API资源控制器生成 `make:controller --api` +* 优化Template类的标签解析 +* 容器类增加删除和清除对象实例的方法 +* 修正MorphMany关联的`eagerlyMorphToMany`方法一处错误 +* Container类的异常捕获改进 +* Domain对象支持`bind`方法 +* 修正分页参数 +* 默认模板的输出规则不受URL影响 +* 注解路由支持多级控制器 +* Query类增加`getNumRows`方法获取前次操作影响的记录数 +* 改进查询条件的性能 +* 改进模型类`readTransform`方法对序列化类型的处理 +* Log类增加`close`方法可以临时关闭当前请求的日志写入 +* 文件日志方式增加自动清理功能(设置`max_files`参数) +* 修正Query类的`getPk`方法 +* 修正模板缓存的布局开关问题 +* 修正Query类`select`方法的缓存 +* 改进input助手函数 +* 改进断线重连的信息判断 +* 改进正则验证方法 +* 调整语言包的加载顺序 放到`app_init`之前 +* controller类`fetch`方法改为`final` +* 路由地址中的变量支持使用``方式 +* 改进XMLResponse 支持传入编码过的xml内容 +* 修正Query类`view`方法的数组表名支持 +* 改进路由的模型闭包绑定 +* 改进分组变量规则的继承 +* 改进`cli-server`模式下的`composer`自动加载 +* 路由变量规则异常捕获 +* 引入中间件支持 +* 路由定义增加`middleware`方法 +* 增加生成中间件指令`make:middleware` +* 增加全局中间件定义支持 +* 改进`optimize:config`指令对全局中间件的支持 +* 改进config类`has`方法 +* 改进时间查询的参数绑定 +* 改进`inc/dec/exp`查询的安全性 + + +## V5.1.5 (2018-1-31) + +该版本主要增强了数据库的JSON查询,并支持JSON字段的聚合查询,改进了一些性能问题,修正了路由的一些BUG,主要更新如下: + +* 改进数据集查询对`JSON`数据的支持 +* 改进聚合查询对`JSON`字段的支持 +* 模型类增加`getOrFail`方法 +* 改进数据库驱动的`parseKey`方法 +* 改进Query类`join`方法的自关联查询 +* 改进数据查询不存在不生成查询缓存 +* 增加`run`命令行指令启动内置服务器 +* `Request`类`pathinfo`方法改进对`cli-server`支持 +* `Session`类增加`use_lock`配置参数设置是否启用锁机制 +* 优化`File`缓存自动生成空目录的问题 +* 域名及分组路由支持`append`方法传递隐式参数 +* 改进日志的并发写入问题 +* 改进`Query`类的`where`方法支持传入`Query`对象 +* 支持设置单个日志文件的文件名 +* 修正路由规则的域名条件约束 +* `Request`类增加`subDomain`方法用于获取当前子域名 +* `Response`类增加`allowCache`方法控制是否允许请求缓存 +* `Request`类增加`sendData`方法便于扩展 +* 改进`Env`类不依赖`putenv`方法 +* 改进控制台`trace`显示错误 +* 改进`MorphTo`关联 +* 改进完整路由匹配后带斜线访问出错的情况 +* 改进路由的多级分组问题 +* 路由url地址生成支持多级分组 +* 改进路由Url生成的`url_convert`参数的影响 +* 改进`miss`和`auto`路由内部解析 +* 取消预载入关联查询缓存功能 + +## V5.1.4 (2018-1-19) + +该版本主要增强了数据库和模型操作,主要更新如下: + +* 支持设置 `deleteTime`属性为`false` 关闭软删除 +* 模型增加`getError`方法 +* 改进Query类的`getTableFields`/`getFieldsType`方法 支持表名自动获取 +* 模型类`toCollection`方法增加参数指定数据集类 +* 改进`union`查询 +* 关联预载入`with`方法增加缓存参数 +* 改进模型类的`get`和`all`方法的缓存 支持关联缓存 +* 支持`order by field`操作 +* 改进`insertAll`分批写入 +* 改进`json`字段数据支持 +* 增加JSON数据的模型对象化操作 +* 改进路由`ext`参数检测 +* 修正`rule`方法的`method`参数使用 `get|post` 方式注册路由的问题 + +## V5.1.3 (2018-1-12) + +该版本主要改进了路由及调整函数加载顺序,主要更新如下: + +* 增加`env`助手函数; +* 增加`route`助手函数; +* 增加视图路由方法; +* 增加路由重定向方法; +* 路由默认区分最后的目录斜杆(支持设置不区分); +* 调整公共文件和配置文件的加载顺序(可以在配置文件中直接使用助手函数); +* 视图类增加`filter`方法设置输出过滤; +* `view`助手函数增加`filter`参数; +* 改进缓存生成指令; +* Session类的`get`方法支持获取多级; +* Request类`only`方法支持指定默认值; +* 改进路由分组; +* 修正使用闭包查询的时候自动数据缓存出错的情况; +* 废除`view_filter`钩子位置; +* 修正分组下面的资源路由; +* 改进session驱动; + +## V5.1.2 (2018-1-8) + +该版本改进了配置类及数据库类,主要更新如下: + +* 修正嵌套路由分组; +* 修正自定义模板标签界定符后表达式语法出错的情况; +* 修正自关联的多次调用问题; +* 修正数组查询的`null`条件查询; +* 修正Query类的`order`及`field`的一处可能的BUG; +* 配置参数设置支持三级; +* 配置对象支持`ArrayAccess`; +* App类增加`path`方法用于设置应用目录; +* 关联定义增加`selfRelation`方法用于设置是否为自关联; + +## V5.1.1 (2018-1-3) + +修正一些反馈的BUG,包括: + +* 修正Cookie类存取数组的问题 +* 修正Controller的`fetch`方法 +* 改进跨域请求 +* 修正`insertAll`方法 +* 修正`chunk`方法 + +## V5.1.0 (2018-1-1) + +主要更新如下: + +* 增加注解路由支持 +* 路由支持跨域请求设置 +* 增加`app_dispatch`钩子位置 +* 修正多对多关联的`detach`方法 +* 修正软删除的`destroy`方法 +* Cookie类`httponly`参数默认为false +* 日志File驱动增加`single`参数配置记录同一个文件(不按日期生成) +* 路由的`ext`和`denyExt`方法支持不传任何参数 +* 改进模型的`save`方法对`oracle`的支持 +* Query类的`insertall`方法支持配合`data`和`limit`方法 +* 增加`whereOr`动态查询支持 +* 日志的ip地址记录改进 +* 模型`saveAll`方法支持`isUpdate`方法 +* 改进`Pivot`模型的实例化操作 +* 改进Model类的`data`方法 +* 改进多对多中间表模型类 +* 模型增加`force`方法强制更新所有数据 +* Hook类支持设置入口方法名称 +* 改进验证类 +* 改进`hasWhere`查询的数据重复问题 +* 模型的`saveall`方法返回数据集对象 +* 改进File缓存的`clear`方法 +* 缓存添加统一的序列化机制 +* 改进泛三级域名的绑定 +* 改进泛域名的传值和取值 +* Request类增加`panDomain`方法 +* 改进废弃字段判断 +* App类增加`create`方法用于实例化应用类库 +* 容器类增加`has`方法 +* 改进多数据库切换连接 +* 改进断线重连的异常捕获 +* 改进模型类`buildQuery`方法 +* Query类增加`unionAll`方法 +* 关联统计功能增强(支持Sum/Max/Min/Avg) +* 修正延迟写入 +* chunk方法支持复合主键 +* 改进JSON类型的写入 +* 改进Mysql的insertAll方法 +* Model类`save`方法改进复合主键包含自增的情况 +* 改进Query类`inc`和`dec`方法的关键字处理 +* File缓存inc和dec方法保持原来的有效期 +* 改进redis缓存的有效期判断 +* 增加checkRule方法用于单独数据的多个验证规则 +* 修正setDec方法的延迟写入 +* max和min方法增加force参数 +* 二级配置参数区分大小写 +* 改进join方法自关联的问题 +* 修正关联模型自定义表名的情况 +* Query类增加getFieldsType和getTableFields方法 +* 取消视图替换功能及view_replace_str配置参数 +* 改进域名绑定模块后的额外路由规则问题 +* 改进mysql的insertAll方法 +* 改进insertAll方法写入json字段数据的支持 +* 改进redis长连接多编号库的情况 + +## RC3版本(2017-11-6) + +主要更新如下: + +* 改进redis驱动的`get`方法 +* 修正Query类的`alias`方法 +* `File`类错误信息支持多语言 +* 修正路由的额外参数解析 +* 改进`whereTime`方法 +* 改进Model类`getAttr`方法 +* 改进App类的`controller`和`validate`方法支持多层 +* 改进`HasManyThrough`类 +* 修正软删除的`restore`方法 +* 改进`MorpthTo`关联 +* 改进数据库驱动类的`parseKey`方法 +* 增加`whereField`动态查询方法 +* 模型增加废弃字段功能 +* 改进路由的`after`行为检查和`before`行为机制 +* 改进路由分组的检查 +* 修正mysql的`json`字段查询 +* 取消Connection类的`quote`方法 +* 改进命令行的支持 +* 验证信息支持多语言 +* 修正路由模型绑定 +* 改进参数绑定类型对枚举类型的支持 +* 修正模板的`{$Think.version} `输出 +* 改进模板`date`函数解析 +* 改进`insertAll`方法支持分批执行 +* Request类`host`方法支持反向代理 +* 改进`JumpResponse`支持区分成功和错误模板 +* 改进开启类库后缀后的关联外键自动识别问题 +* 修正一对一关联的JOIN方式预载入查询问题 +* Query类增加`hidden`方法 + +## RC2版本(2017-10-17) + +主要更新如下: + +* 修正视图查询 +* 修正资源路由 +* 修正`HasMany`关联 修正`where`方法的闭包查询 +* 一对一关联绑定属性到父模型后 关联属性不再保留 +* 修正应用的命令行配置文件读取 +* 改进`Connection`类的`getCacheKey`方法 +* 改进文件上传的非法图像异常 +* 改进验证类的`unique`规则 +* Config类`get`方法支持获取一级配置 +* 修正count方法对`fetchSql`的支持 +* 修正mysql驱动对`socket`支持 +* 改进Connection类的`getRealSql`方法 +* 修正`view`助手函数 +* Query类增加`leftJoin` `rightJoin` 和 `fullJoin`方法 +* 改进app_namespace的获取 +* 改进`append`方法对一对一`bind`属性的支持 +* 改进关联的`saveall`方法的返回值 +* 路由标识设置异常修复 +* 改进Route类`rule`方法 +* 改进模型的`table`属性设置 +* 改进composer autofile的加载顺序 +* 改进`exception_handle`配置对闭包的支持 +* 改进app助手函数增加参数 +* 改进composer的加载路径判断 +* 修正路由组合变量的URL生成 +* 修正路由URL生成 +* 改进`whereTime`查询并支持扩展规则 +* File类的`move`方法第二个参数支持`false` +* 改进Config类 +* 改进缓存类`remember`方法 +* 惯例配置文件调整 Url类当普通模式参数的时候不做`urlencode`处理 +* 取消`ROOT_PATH`和`APP_PATH`常量定义 如需更改应用目录 自己重新定义入口文件 +* 增加`app_debug`的`Env`获取 +* 修正泛域名绑定 +* 改进查询表达式的解析机制 +* mysql增加`regexp`查询表达式 支持正则查询 +* 改进查询表达式的异常判断 +* 改进model类的`destroy`方法 +* 改进Builder类 取消`parseValue`方法 +* 修正like查询的参数绑定问题 +* console和start文件移出核心纳入应用库 +* 改进Db类主键删除方法 +* 改进泛域名绑定模块 +* 取消`BIND_MODULE`常量 改为在入口文件使用`bind`方法设置 +* 改进数组查询 +* 改进模板渲染的异常处理 +* 改进控制器基类的架构方法参数 +* 改进Controller类的`success`和`error`方法 +* 改进对浏览器`JSON-Handle`插件的支持 +* 优化跳转模板的移动端显示 +* 修正模型查询的`chunk`方法对时间字段的支持 +* 改进trace驱动 +* Collection类增加`push`方法 +* 改进Redis Session驱动 +* 增加JumpResponse驱动 + + +## RC1(2017-9-8) + +主要新特性为: + +* 引入容器和Facade支持 +* 依赖注入完善和支持更多场景 +* 重构的(对象化)路由 +* 配置和路由目录独立 +* 取消系统常量 +* 助手函数增强 +* 类库别名机制 +* 模型和数据库增强 +* 验证类增强 +* 模板引擎改进 +* 支持PSR-3日志规范 +* RC1版本取消了5.0多个字段批量数组查询的方式 \ No newline at end of file diff --git a/LICENSE b/LICENSE index 261eeb9..e89733f 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright [2020] [LittleJake] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..774fa76 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,32 @@ + +ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 +版权所有Copyright © 2006-2018 by ThinkPHP (http://thinkphp.cn) +All rights reserved。 +ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 + +Apache Licence是著名的非盈利开源组织Apache采用的协议。 +该协议和BSD类似,鼓励代码共享和尊重原作者的著作权, +允许代码修改,再作为开源或商业软件发布。需要满足 +的条件: +1. 需要给代码的用户一份Apache Licence ; +2. 如果你修改了代码,需要在被修改的文件中说明; +3. 在延伸的代码中(修改和有源代码衍生的代码中)需要 +带有原来代码中的协议,商标,专利声明和其他原来作者规 +定需要包含的说明; +4. 如果再发布的产品中包含一个Notice文件,则在Notice文 +件中需要带有本协议内容。你可以在Notice中增加自己的 +许可,但不可以表现为对Apache Licence构成更改。 +具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0 + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/application/.htaccess b/application/.htaccess new file mode 100644 index 0000000..3418e55 --- /dev/null +++ b/application/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/application/admin/controller/Index.php b/application/admin/controller/Index.php new file mode 100644 index 0000000..e7f09a8 --- /dev/null +++ b/application/admin/controller/Index.php @@ -0,0 +1,85 @@ + +// +---------------------------------------------------------------------- + +return []; diff --git a/application/common.php b/application/common.php new file mode 100644 index 0000000..55d22f2 --- /dev/null +++ b/application/common.php @@ -0,0 +1,12 @@ + +// +---------------------------------------------------------------------- + +// 应用公共文件 diff --git a/application/http/middleware/FlowControll.php b/application/http/middleware/FlowControll.php new file mode 100644 index 0000000..e6c3e43 --- /dev/null +++ b/application/http/middleware/FlowControll.php @@ -0,0 +1,10 @@ +hGetAll("system_monitor:hashes"); + + $this->assign("hash", $hash); + return $this->fetch(); + } + + public function info($token = ''){ + if(strlen($token) != 64){ + return $this->error("Wrong Token"); + } + + $ip = Cache::handler()->hMGet("system_monitor:hashes", [$token])[$token]; + if(empty($ip)){ + return $this->error("Wrong Token"); + } + $json = json_decode(Cache::handler()->get("system_monitor:stat:".$ip), true); + $uptime = intval($json['Uptime']); + $uptime_str = floor($uptime / (24*60*60)) ." Days ". + floor(($uptime / (60*60)) % 24) ." Hours ". + floor(($uptime / (60)) % 60) . " Minutes ". + floor($uptime % 60) . " Seconds"; + $info = Cache::handler()->hGetAll("system_monitor:info:".$ip); + $this->assign("json", $json); + $this->assign("uptime", $uptime_str); + $this->assign("info", $info); + return $this->fetch(); + } +} diff --git a/application/index/view/index/index.html b/application/index/view/index/index.html new file mode 100644 index 0000000..1702506 --- /dev/null +++ b/application/index/view/index/index.html @@ -0,0 +1,17 @@ + + + + + Title + + +
+

Monitor List

+
    + {foreach $hash as $k => $v} +
  1. {$v}
  2. + {/foreach} +
+
+ + \ No newline at end of file diff --git a/application/index/view/index/info.html b/application/index/view/index/info.html new file mode 100644 index 0000000..d7a5c18 --- /dev/null +++ b/application/index/view/index/info.html @@ -0,0 +1,174 @@ + + + + + Title + + + +
+

System Info

+ {foreach $info as $k => $v} +

{$k}

+

{$v}

+ {/foreach} +
+
+

CPU Load

+
+ 1 Min +
+
+ 5 Min +
+
+ 15 Min +
+
+
+

Memory

+
+

Memory {$json['Memory']['Mem']['used']} MB / {$json['Memory']['Mem']['total']} MB

+
+
+
+

Swap {$json['Memory']['Swap']['used']} MB / {$json['Memory']['Swap']['total']} MB

+
+
+
+
+

Disk

+
+

{$json['Disk']['used']} / {$json['Disk']['total']}

+
+
+
+
+

Process

+
+

{$json['Process']}

+
+
+
+

Connection

+
+

{$json['Connection']}

+
+
+
+

Uptime

+
+

{$uptime}

+
+
+ + + + \ No newline at end of file diff --git a/application/provider.php b/application/provider.php new file mode 100644 index 0000000..d0fcd24 --- /dev/null +++ b/application/provider.php @@ -0,0 +1,14 @@ + +// +---------------------------------------------------------------------- + +// 应用容器绑定定义 +return [ +]; diff --git a/application/tags.php b/application/tags.php new file mode 100644 index 0000000..4b18d10 --- /dev/null +++ b/application/tags.php @@ -0,0 +1,28 @@ + +// +---------------------------------------------------------------------- + +// 应用行为扩展定义文件 +return [ + // 应用初始化 + 'app_init' => [], + // 应用开始 + 'app_begin' => [], + // 模块初始化 + 'module_init' => [], + // 操作开始执行 + 'action_begin' => [], + // 视图内容过滤 + 'view_filter' => [], + // 日志写入 + 'log_write' => [], + // 应用结束 + 'app_end' => [], +]; diff --git a/build.php b/build.php new file mode 100644 index 0000000..34ba3c8 --- /dev/null +++ b/build.php @@ -0,0 +1,26 @@ + +// +---------------------------------------------------------------------- + +return [ + // 生成应用公共文件 + '__file__' => ['common.php'], + + // 定义demo模块的自动生成 (按照实际定义的文件名生成) + 'demo' => [ + '__file__' => ['common.php'], + '__dir__' => ['behavior', 'controller', 'model', 'view'], + 'controller' => ['Index', 'Test', 'UserType'], + 'model' => ['User', 'UserType'], + 'view' => ['index/index'], + ], + + // 其他更多的模块定义 +]; diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..361d6f6 --- /dev/null +++ b/composer.json @@ -0,0 +1,33 @@ +{ + "name": "topthink/think", + "description": "the new thinkphp framework", + "type": "project", + "keywords": [ + "framework", + "thinkphp", + "ORM" + ], + "homepage": "http://thinkphp.cn/", + "license": "Apache-2.0", + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + } + ], + "require": { + "php": ">=5.6.0", + "topthink/framework": "5.1.*" + }, + "autoload": { + "psr-4": { + "app\\": "application" + } + }, + "extra": { + "think-path": "thinkphp" + }, + "config": { + "preferred-install": "dist" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..1329773 --- /dev/null +++ b/composer.lock @@ -0,0 +1,124 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "296bd8a1d28e39d56dcd80ce7be249f3", + "packages": [ + { + "name": "topthink/framework", + "version": "v5.1.39", + "source": { + "type": "git", + "url": "https://github.com/top-think/framework.git", + "reference": "5762858f3d58faafb3a39427f8788884b2927007" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/framework/zipball/5762858f3d58faafb3a39427f8788884b2927007", + "reference": "5762858f3d58faafb3a39427f8788884b2927007", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.6.0", + "topthink/think-installer": "2.*" + }, + "require-dev": { + "johnkary/phpunit-speedtrap": "^1.0", + "mikey179/vfsstream": "~1.6", + "phpdocumentor/reflection-docblock": "^2.0", + "phploc/phploc": "2.*", + "phpunit/phpunit": "^5.0|^6.0", + "sebastian/phpcpd": "2.*", + "squizlabs/php_codesniffer": "2.*" + }, + "type": "think-framework", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + }, + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "description": "the new thinkphp framework", + "homepage": "http://thinkphp.cn/", + "keywords": [ + "framework", + "orm", + "thinkphp" + ], + "time": "2019-11-17T23:22:02+00:00" + }, + { + "name": "topthink/think-installer", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-installer.git", + "reference": "f5400a12c60e513911aef41fe443fa6920952675" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-installer/zipball/f5400a12c60e513911aef41fe443fa6920952675", + "reference": "f5400a12c60e513911aef41fe443fa6920952675", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "composer-plugin-api": "^1.0" + }, + "require-dev": { + "composer/composer": "1.0.*@dev" + }, + "type": "composer-plugin", + "extra": { + "class": "think\\composer\\Plugin" + }, + "autoload": { + "psr-4": { + "think\\composer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "time": "2018-05-11T06:45:42+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.6.0" + }, + "platform-dev": [] +} diff --git a/config/.gitignore b/config/.gitignore new file mode 100644 index 0000000..4c1f1b7 --- /dev/null +++ b/config/.gitignore @@ -0,0 +1,2 @@ +# Created by .ignore support plugin (hsz.mobi) +cache.php \ No newline at end of file diff --git a/config/app.php b/config/app.php new file mode 100644 index 0000000..55bda2d --- /dev/null +++ b/config/app.php @@ -0,0 +1,146 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 应用设置 +// +---------------------------------------------------------------------- + +return [ + // 应用名称 + 'app_name' => '', + // 应用地址 + 'app_host' => '', + // 应用调试模式 + 'app_debug' => true, + // 应用Trace + 'app_trace' => false, + // 是否支持多模块 + 'app_multi_module' => true, + // 入口自动绑定模块 + 'auto_bind_module' => false, + // 注册的根命名空间 + 'root_namespace' => [], + // 默认输出类型 + 'default_return_type' => 'html', + // 默认AJAX 数据返回格式,可选json xml ... + 'default_ajax_return' => 'json', + // 默认JSONP格式返回的处理方法 + 'default_jsonp_handler' => 'jsonpReturn', + // 默认JSONP处理方法 + 'var_jsonp_handler' => 'callback', + // 默认时区 + 'default_timezone' => 'Asia/Shanghai', + // 是否开启多语言 + 'lang_switch_on' => false, + // 默认全局过滤方法 用逗号分隔多个 + 'default_filter' => '', + // 默认语言 + 'default_lang' => 'zh-cn', + // 应用类库后缀 + 'class_suffix' => false, + // 控制器类后缀 + 'controller_suffix' => false, + + // +---------------------------------------------------------------------- + // | 模块设置 + // +---------------------------------------------------------------------- + + // 默认模块名 + 'default_module' => 'index', + // 禁止访问模块 + 'deny_module_list' => ['common'], + // 默认控制器名 + 'default_controller' => 'Index', + // 默认操作名 + 'default_action' => 'index', + // 默认验证器 + 'default_validate' => '', + // 默认的空模块名 + 'empty_module' => '', + // 默认的空控制器名 + 'empty_controller' => 'Error', + // 操作方法前缀 + 'use_action_prefix' => false, + // 操作方法后缀 + 'action_suffix' => '', + // 自动搜索控制器 + 'controller_auto_search' => false, + + // +---------------------------------------------------------------------- + // | URL设置 + // +---------------------------------------------------------------------- + + // PATHINFO变量名 用于兼容模式 + 'var_pathinfo' => 's', + // 兼容PATH_INFO获取 + 'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'], + // pathinfo分隔符 + 'pathinfo_depr' => '/', + // HTTPS代理标识 + 'https_agent_name' => '', + // IP代理获取标识 + 'http_agent_ip' => 'X-REAL-IP', + // URL伪静态后缀 + 'url_html_suffix' => 'html', + // URL普通方式参数 用于自动生成 + 'url_common_param' => false, + // URL参数方式 0 按名称成对解析 1 按顺序解析 + 'url_param_type' => 0, + // 是否开启路由延迟解析 + 'url_lazy_route' => false, + // 是否强制使用路由 + 'url_route_must' => false, + // 合并路由规则 + 'route_rule_merge' => false, + // 路由是否完全匹配 + 'route_complete_match' => false, + // 使用注解路由 + 'route_annotation' => false, + // 域名根,如thinkphp.cn + 'url_domain_root' => '', + // 是否自动转换URL中的控制器和操作名 + 'url_convert' => true, + // 默认的访问控制器层 + 'url_controller_layer' => 'controller', + // 表单请求类型伪装变量 + 'var_method' => '_method', + // 表单ajax伪装变量 + 'var_ajax' => '_ajax', + // 表单pjax伪装变量 + 'var_pjax' => '_pjax', + // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则 + 'request_cache' => false, + // 请求缓存有效期 + 'request_cache_expire' => null, + // 全局请求缓存排除规则 + 'request_cache_except' => [], + // 是否开启路由缓存 + 'route_check_cache' => false, + // 路由缓存的Key自定义设置(闭包),默认为当前URL和请求类型的md5 + 'route_check_cache_key' => '', + // 路由缓存类型及参数 + 'route_cache_option' => [], + + // 默认跳转页面对应的模板文件 + 'dispatch_success_tmpl' => Env::get('think_path') . 'tpl/dispatch_jump.tpl', + 'dispatch_error_tmpl' => Env::get('think_path') . 'tpl/dispatch_jump.tpl', + + // 异常页面的模板文件 + 'exception_tmpl' => Env::get('think_path') . 'tpl/think_exception.tpl', + + // 错误显示信息,非调试模式有效 + 'error_message' => '页面错误!请稍后再试~', + // 显示错误信息 + 'show_error_msg' => false, + // 异常处理handle类 留空使用 \think\exception\Handle + 'exception_handle' => '', + +]; diff --git a/config/cache.php.bak b/config/cache.php.bak new file mode 100644 index 0000000..1908d11 --- /dev/null +++ b/config/cache.php.bak @@ -0,0 +1,28 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 缓存设置 +// +---------------------------------------------------------------------- + +return [ + // 驱动方式 + 'type' => 'Redis', + 'host' => '', + 'port' => 14191, + 'password' => '', + 'select' => 0, + 'timeout' => 0, + 'expire' => 0, + 'persistent' => false, + 'prefix' => '', + 'serialize' => true, +]; diff --git a/config/console.php b/config/console.php new file mode 100644 index 0000000..a7fabca --- /dev/null +++ b/config/console.php @@ -0,0 +1,20 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 控制台配置 +// +---------------------------------------------------------------------- +return [ + 'name' => 'Think Console', + 'version' => '0.1', + 'user' => null, + 'auto_path' => env('app_path') . 'command' . DIRECTORY_SEPARATOR, +]; diff --git a/config/cookie.php b/config/cookie.php new file mode 100644 index 0000000..1de0708 --- /dev/null +++ b/config/cookie.php @@ -0,0 +1,30 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | Cookie设置 +// +---------------------------------------------------------------------- +return [ + // cookie 名称前缀 + 'prefix' => '', + // cookie 保存时间 + 'expire' => 0, + // cookie 保存路径 + 'path' => '/', + // cookie 有效域名 + 'domain' => '', + // cookie 启用安全传输 + 'secure' => false, + // httponly设置 + 'httponly' => '', + // 是否使用 setcookie + 'setcookie' => true, +]; diff --git a/config/database.php b/config/database.php new file mode 100644 index 0000000..d14b952 --- /dev/null +++ b/config/database.php @@ -0,0 +1,63 @@ + +// +---------------------------------------------------------------------- + +return [ + // 数据库类型 + 'type' => 'mysql', + // 服务器地址 + 'hostname' => '127.0.0.1', + // 数据库名 + 'database' => '', + // 用户名 + 'username' => 'root', + // 密码 + 'password' => '', + // 端口 + 'hostport' => '', + // 连接dsn + 'dsn' => '', + // 数据库连接参数 + 'params' => [], + // 数据库编码默认采用utf8 + 'charset' => 'utf8', + // 数据库表前缀 + 'prefix' => '', + // 数据库调试模式 + 'debug' => true, + // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) + 'deploy' => 0, + // 数据库读写是否分离 主从式有效 + 'rw_separate' => false, + // 读写分离后 主服务器数量 + 'master_num' => 1, + // 指定从服务器序号 + 'slave_no' => '', + // 自动读取主库数据 + 'read_master' => false, + // 是否严格检查字段是否存在 + 'fields_strict' => true, + // 数据集返回类型 + 'resultset_type' => 'array', + // 自动写入时间戳字段 + 'auto_timestamp' => false, + // 时间字段取出后的默认时间格式 + 'datetime_format' => 'Y-m-d H:i:s', + // 是否需要进行SQL性能分析 + 'sql_explain' => false, + // Builder类 + 'builder' => '', + // Query类 + 'query' => '\\think\\db\\Query', + // 是否需要断线重连 + 'break_reconnect' => false, + // 断线标识字符串 + 'break_match_str' => [], +]; diff --git a/config/log.php b/config/log.php new file mode 100644 index 0000000..b3d87b4 --- /dev/null +++ b/config/log.php @@ -0,0 +1,30 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 日志设置 +// +---------------------------------------------------------------------- +return [ + // 日志记录方式,内置 file socket 支持扩展 + 'type' => 'File', + // 日志保存目录 + 'path' => '', + // 日志记录级别 + 'level' => [], + // 单文件日志写入 + 'single' => false, + // 独立日志级别 + 'apart_level' => [], + // 最大日志文件数量 + 'max_files' => 0, + // 是否关闭日志写入 + 'close' => false, +]; diff --git a/config/middleware.php b/config/middleware.php new file mode 100644 index 0000000..fe15ec3 --- /dev/null +++ b/config/middleware.php @@ -0,0 +1,18 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 中间件配置 +// +---------------------------------------------------------------------- +return [ + // 默认中间件命名空间 + 'default_namespace' => 'app\\http\\middleware\\', +]; diff --git a/config/secret.php b/config/secret.php new file mode 100644 index 0000000..08f151c --- /dev/null +++ b/config/secret.php @@ -0,0 +1,12 @@ + 'qxrJIZlv94KCyqGV', + 'password' => '' +]; \ No newline at end of file diff --git a/config/session.php b/config/session.php new file mode 100644 index 0000000..1d7b6c6 --- /dev/null +++ b/config/session.php @@ -0,0 +1,26 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 会话设置 +// +---------------------------------------------------------------------- + +return [ + 'id' => '', + // SESSION_ID的提交变量,解决flash上传跨域 + 'var_session_id' => '', + // SESSION 前缀 + 'prefix' => 'think', + // 驱动方式 支持redis memcache memcached + 'type' => '', + // 是否自动开启 SESSION + 'auto_start' => true, +]; diff --git a/config/template.php b/config/template.php new file mode 100644 index 0000000..299bd6f --- /dev/null +++ b/config/template.php @@ -0,0 +1,35 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 模板设置 +// +---------------------------------------------------------------------- + +return [ + // 模板引擎类型 支持 php think 支持扩展 + 'type' => 'Think', + // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法 + 'auto_rule' => 1, + // 模板路径 + 'view_path' => '', + // 模板后缀 + 'view_suffix' => 'html', + // 模板文件名分隔符 + 'view_depr' => DIRECTORY_SEPARATOR, + // 模板引擎普通标签开始标记 + 'tpl_begin' => '{', + // 模板引擎普通标签结束标记 + 'tpl_end' => '}', + // 标签库标签开始标记 + 'taglib_begin' => '{', + // 标签库标签结束标记 + 'taglib_end' => '}', +]; diff --git a/config/trace.php b/config/trace.php new file mode 100644 index 0000000..425d301 --- /dev/null +++ b/config/trace.php @@ -0,0 +1,18 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | Trace设置 开启 app_trace 后 有效 +// +---------------------------------------------------------------------- +return [ + // 内置Html Console 支持扩展 + 'type' => 'Html', +]; diff --git a/extend/.gitignore b/extend/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/extend/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..d9ee23c --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,8 @@ + + Options +FollowSymlinks -Multiviews + RewriteEngine On + + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L] + diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..e71815a6618c6ef19c78d27840b8995fb2521499 GIT binary patch literal 1150 zcmbVMSx8i26uv?4_SAEaJq7BFqqJE;Q9TBc5JYcLIgSmPnyr-jk`K{>ZB(>aLWVXo z*9E63a&I$RrZR03EEi&&_1^#9`}O_*AViPd;mm*e&-u>z&UX%1)0XhJY?;RY723X~ znzmfiw3Reo@g{fAL(}N{_i=@Ma0M%r6$X8HFcE zpG~1@_%Y6ow1ksJIN%eE0)m_g-8Gd#K%-r;7XvI$t0gLrlUMS(*o zV$Y+$Ct(SJ+L5c+)7OmI%nVG$!vbteaep>7ij6%r*#F`@;?!a~HIJfDIkr7LrT7TO z8Pus^>>;*w*WwO!6s7@#wJgVkVE+^G7)ra2;Ldm_p8Ob6`0br_NQk8JTkP3k{J^jG z*cCa8vT!3JGaq0ucb3{&JkLiTVfXWMD5q9ZyH%ZD)V;jPIT^6ouVd%VG`X~V*0H+F zhl^v6kP#Mn+6Yg-!rHDH>fs|^>X)1U?nncMSj%CIp#G9el3d=+e!&L43iV_6ITI5d zQv>h>y$V~X^k*JwD7m;pl{iR^$K%uN!-g$vq?qse=KxBm_3+$BoO#pw7gpx+aR#|L z%6Dm{!D`%_jIeKm8ajyn9!EZFoOpW+Tl5oZR|^>D;?7A9ZiV-%JuQ#*owco@x{a zD-|ENtov7tOFzK5r}KRMSHhkEb!7aa$$nhqBKuHtV!cJ5I+?Si!w-Hm{`)ye +// +---------------------------------------------------------------------- + +// [ 应用入口文件 ] +namespace think; + +// 加载基础文件 +require __DIR__ . '/../thinkphp/base.php'; + +// 支持事先使用静态方法设置Request对象和Config对象 + +// 执行应用并响应 +Container::get('app')->run()->send(); diff --git a/public/js/progressbar.js/progressbar.min.js b/public/js/progressbar.js/progressbar.min.js new file mode 100644 index 0000000..a92dbb1 --- /dev/null +++ b/public/js/progressbar.js/progressbar.min.js @@ -0,0 +1,6 @@ +// ProgressBar.js 1.1.0 +// https://kimmobrunfeldt.github.io/progressbar.js +// License: MIT + +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.ProgressBar=a()}}(function(){var a;return function(){function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){return e(b[g][1][a]||a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g0&&void 0!==arguments[0]?arguments[0]:{},b=new u,c=b.tween(a);return c.tweenable=b,c}c.d(b,"e",function(){return p}),c.d(b,"c",function(){return r}),c.d(b,"b",function(){return s}),c.d(b,"a",function(){return u}),c.d(b,"d",function(){return h});var i=c(1),j="undefined"!=typeof window?window:a,k=j.requestAnimationFrame||j.webkitRequestAnimationFrame||j.oRequestAnimationFrame||j.msRequestAnimationFrame||j.mozCancelRequestAnimationFrame&&j.mozRequestAnimationFrame||setTimeout,l=function(){},m=null,n=null,o=f({},i),p=function(a,b,c,d,e,f,g){var h=al?l:b,n=h-(l-m);m>=l?(i(j,c,n),a.stop(!0)):(a._applyFilter("beforeTween"),m1&&void 0!==arguments[1]?arguments[1]:"linear",c={},d=e(b);if("string"===d||"function"===d)for(var f in a)c[f]=b;else for(var g in a)c[g]=b[g]||"linear";return c},t=function(a){if(a===m)(m=a._next)?m._previous=null:n=null;else if(a===n)(n=a._previous)?n._next=null:m=null;else{var b=a._previous,c=a._next;b._next=c,c._previous=b}a._previous=a._next=null},u=function(){function a(){var b=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},c=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0;!function(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}(this,a),this._currentState=b,this._configured=!1,this._filters=[],this._timestamp=null,this._next=null,this._previous=null,c&&this.setConfig(c)}var b,c,e;return b=a,(c=[{key:"_applyFilter",value:function(a){var b=!0,c=!1,d=void 0;try{for(var e,f=this._filters[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value[a];g&&g(this)}}catch(a){c=!0,d=a}finally{try{b||null==f.return||f.return()}finally{if(c)throw d}}}},{key:"tween",value:function(){var b=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0,c=this._attachment,d=this._configured;return!b&&d||this.setConfig(b),this._pausedAtTime=null,this._timestamp=a.now(),this._start(this.get(),c),this.resume()}},{key:"setConfig",value:function(){var b=this,c=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},d=c.attachment,e=c.delay,g=void 0===e?0:e,h=c.duration,i=void 0===h?500:h,j=c.easing,k=c.from,m=c.promise,n=void 0===m?Promise:m,o=c.start,p=void 0===o?l:o,q=c.step,r=void 0===q?l:q,t=c.to;this._configured=!0,this._attachment=d,this._isPlaying=!1,this._pausedAtTime=null,this._scheduleId=null,this._delay=g,this._start=p,this._step=r,this._duration=i,this._currentState=f({},k||this.get()),this._originalState=this.get(),this._targetState=f({},t||this.get());var u=this._currentState;this._targetState=f({},u,this._targetState),this._easing=s(u,j);var v=a.filters;for(var w in this._filters.length=0,v)v[w].doesApply(this)&&this._filters.push(v[w]);return this._applyFilter("tweenCreated"),this._promise=new n(function(a,c){b._resolve=a,b._reject=c}),this._promise.catch(l),this}},{key:"get",value:function(){return f({},this._currentState)}},{key:"set",value:function(a){this._currentState=a}},{key:"pause",value:function(){if(this._isPlaying)return this._pausedAtTime=a.now(),this._isPlaying=!1,t(this),this}},{key:"resume",value:function(){if(null===this._timestamp)return this.tween();if(this._isPlaying)return this._promise;var b=a.now();return this._pausedAtTime&&(this._timestamp+=b-this._pausedAtTime,this._pausedAtTime=null),this._isPlaying=!0,null===m?(m=this,n=this,function a(){m&&(k.call(j,a,1e3/60),r())}()):(this._previous=n,n._next=this,n=this),this._promise}},{key:"seek",value:function(b){b=Math.max(b,0);var c=a.now();return this._timestamp+b===0?this:(this._timestamp=c-b,this._isPlaying||q(this,c),this)}},{key:"stop",value:function(){var a=arguments.length>0&&void 0!==arguments[0]&&arguments[0],b=this._attachment,c=this._currentState,d=this._easing,e=this._originalState,f=this._targetState;if(this._isPlaying)return this._isPlaying=!1,t(this),a?(this._applyFilter("beforeTween"),p(1,c,e,f,1,0,d),this._applyFilter("afterTween"),this._applyFilter("afterTweenEnd"),this._resolve(c,b)):this._reject(c,b),this}},{key:"isPlaying",value:function(){return this._isPlaying}},{key:"setScheduleFunction",value:function(b){a.setScheduleFunction(b)}},{key:"dispose",value:function(){for(var a in this)delete this[a]}}])&&d(b.prototype,c),e&&d(b,e),a}();u.setScheduleFunction=function(a){return k=a},u.formulas=o,u.filters={},u.now=Date.now||function(){return+new Date}}).call(this,c(2))},function(a,b,c){"use strict";c.r(b),c.d(b,"linear",function(){return d}),c.d(b,"easeInQuad",function(){return e}),c.d(b,"easeOutQuad",function(){return f}),c.d(b,"easeInOutQuad",function(){return g}),c.d(b,"easeInCubic",function(){return h}),c.d(b,"easeOutCubic",function(){return i}),c.d(b,"easeInOutCubic",function(){return j}),c.d(b,"easeInQuart",function(){return k}),c.d(b,"easeOutQuart",function(){return l}),c.d(b,"easeInOutQuart",function(){return m}),c.d(b,"easeInQuint",function(){return n}),c.d(b,"easeOutQuint",function(){return o}),c.d(b,"easeInOutQuint",function(){return p}),c.d(b,"easeInSine",function(){return q}),c.d(b,"easeOutSine",function(){return r}),c.d(b,"easeInOutSine",function(){return s}),c.d(b,"easeInExpo",function(){return t}),c.d(b,"easeOutExpo",function(){return u}),c.d(b,"easeInOutExpo",function(){return v}),c.d(b,"easeInCirc",function(){return w}),c.d(b,"easeOutCirc",function(){return x}),c.d(b,"easeInOutCirc",function(){return y}),c.d(b,"easeOutBounce",function(){return z}),c.d(b,"easeInBack",function(){return A}),c.d(b,"easeOutBack",function(){return B}),c.d(b,"easeInOutBack",function(){return C}),c.d(b,"elastic",function(){return D}),c.d(b,"swingFromTo",function(){return E}),c.d(b,"swingFrom",function(){return F}),c.d(b,"swingTo",function(){return G}),c.d(b,"bounce",function(){return H}),c.d(b,"bouncePast",function(){return I}),c.d(b,"easeFromTo",function(){return J}),c.d(b,"easeFrom",function(){return K}),c.d(b,"easeTo",function(){return L});var d=function(a){return a},e=function(a){return Math.pow(a,2)},f=function(a){return-(Math.pow(a-1,2)-1)},g=function(a){return(a/=.5)<1?.5*Math.pow(a,2):-.5*((a-=2)*a-2)},h=function(a){return Math.pow(a,3)},i=function(a){return Math.pow(a-1,3)+1},j=function(a){return(a/=.5)<1?.5*Math.pow(a,3):.5*(Math.pow(a-2,3)+2)},k=function(a){return Math.pow(a,4)},l=function(a){return-(Math.pow(a-1,4)-1)},m=function(a){return(a/=.5)<1?.5*Math.pow(a,4):-.5*((a-=2)*Math.pow(a,3)-2)},n=function(a){return Math.pow(a,5)},o=function(a){return Math.pow(a-1,5)+1},p=function(a){return(a/=.5)<1?.5*Math.pow(a,5):.5*(Math.pow(a-2,5)+2)},q=function(a){return 1-Math.cos(a*(Math.PI/2))},r=function(a){return Math.sin(a*(Math.PI/2))},s=function(a){return-.5*(Math.cos(Math.PI*a)-1)},t=function(a){return 0===a?0:Math.pow(2,10*(a-1))},u=function(a){return 1===a?1:1-Math.pow(2,-10*a)},v=function(a){return 0===a?0:1===a?1:(a/=.5)<1?.5*Math.pow(2,10*(a-1)):.5*(2-Math.pow(2,-10*--a))},w=function(a){return-(Math.sqrt(1-a*a)-1)},x=function(a){return Math.sqrt(1-Math.pow(a-1,2))},y=function(a){return(a/=.5)<1?-.5*(Math.sqrt(1-a*a)-1):.5*(Math.sqrt(1-(a-=2)*a)+1)},z=function(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+.9375:7.5625*(a-=2.625/2.75)*a+.984375},A=function(a){var b=1.70158;return a*a*((b+1)*a-b)},B=function(a){var b=1.70158;return(a-=1)*a*((b+1)*a+b)+1},C=function(a){var b=1.70158;return(a/=.5)<1?a*a*((1+(b*=1.525))*a-b)*.5:.5*((a-=2)*a*((1+(b*=1.525))*a+b)+2)},D=function(a){return-1*Math.pow(4,-8*a)*Math.sin((6*a-1)*(2*Math.PI)/2)+1},E=function(a){var b=1.70158;return(a/=.5)<1?a*a*((1+(b*=1.525))*a-b)*.5:.5*((a-=2)*a*((1+(b*=1.525))*a+b)+2)},F=function(a){var b=1.70158;return a*a*((b+1)*a-b)},G=function(a){var b=1.70158;return(a-=1)*a*((b+1)*a+b)+1},H=function(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+.9375:7.5625*(a-=2.625/2.75)*a+.984375},I=function(a){return a<1/2.75?7.5625*a*a:a<2/2.75?2-(7.5625*(a-=1.5/2.75)*a+.75):a<2.5/2.75?2-(7.5625*(a-=2.25/2.75)*a+.9375):2-(7.5625*(a-=2.625/2.75)*a+.984375)},J=function(a){return(a/=.5)<1?.5*Math.pow(a,4):-.5*((a-=2)*Math.pow(a,3)-2)},K=function(a){return Math.pow(a,4)},L=function(a){return Math.pow(a,.25)}},function(a,b){var c;c=function(){return this}();try{c=c||new Function("return this")()}catch(a){"object"==typeof window&&(c=window)}a.exports=c},function(a,b,c){"use strict";function d(a){return parseInt(a,16)}function e(a){var b=a._currentState;[b,a._originalState,a._targetState].forEach(z),a._tokenData=C(b)}function f(a){var b=a._currentState,c=a._originalState,d=a._targetState,e=a._easing,f=a._tokenData;I(e,f),[b,c,d].forEach(function(a){return D(a,f)})}function g(a){var b=a._currentState,c=a._originalState,d=a._targetState,e=a._easing,f=a._tokenData;[b,c,d].forEach(function(a){return H(a,f)}),J(e,f)}function h(a,b,c){return b in a?Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}):a[b]=c,a}function i(a){return function(a){if(Array.isArray(a)){for(var b=0,c=new Array(a.length);b=0?a:0-a};return g=1-(i=3*b)-(h=3*(d-b)-i),j=1-(l=3*c)-(k=3*(e-c)-l),function(a,b){return c=function(a,b){var c,d,e,f,j,k,l;for(e=a,k=0;k<8;k++){if(f=m(e)-a,n(f)(d=1))return d;for(;cf?c=e:d=e,e=.5*(d-c)+c}return e}(a,b),((j*c+k)*c+l)*c;var c}(a,function(a){return 1/(200*a)}(f))}c.r(b);var m={};c.r(m),c.d(m,"doesApply",function(){return K}),c.d(m,"tweenCreated",function(){return e}),c.d(m,"beforeTween",function(){return f}),c.d(m,"afterTween",function(){return g});var n,o,p=c(0),q=/(\d|-|\.)/,r=/([^\-0-9.]+)/g,s=/[0-9.-]+/g,t=(n=s.source,o=/,\s*/.source,new RegExp("rgb\\(".concat(n).concat(o).concat(n).concat(o).concat(n,"\\)"),"g")),u=/^.*\(/,v=/#([0-9]|[a-f]){3,6}/gi,w=function(a,b){return a.map(function(a,c){return"_".concat(b,"_").concat(c)})},x=function(a){return"rgb(".concat((b=a,3===(b=b.replace(/#/,"")).length&&(b=(b=b.split(""))[0]+b[0]+b[1]+b[1]+b[2]+b[2]),[d(b.substr(0,2)),d(b.substr(2,2)),d(b.substr(4,2))]).join(","),")");var b},y=function(a,b,c){var d=b.match(a),e=b.replace(a,"VAL");return d&&d.forEach(function(a){return e=e.replace("VAL",c(a))}),e},z=function(a){for(var b in a){var c=a[b];"string"==typeof c&&c.match(v)&&(a[b]=y(v,c,x))}},A=function(a){var b=a.match(s).map(Math.floor);return"".concat(a.match(u)[0]).concat(b.join(","),")")},B=function(a){return a.match(s)},C=function(a){var b,c,d={};for(var e in a){var f=a[e];"string"==typeof f&&(d[e]={formatString:(b=f,c=void 0,c=b.match(r),c?(1===c.length||b.charAt(0).match(q))&&c.unshift(""):c=["",""],c.join("VAL")),chunkNames:w(B(f),e)})}return d},D=function(a,b){var c=function(c){B(a[c]).forEach(function(d,e){return a[b[c].chunkNames[e]]=+d}),delete a[c]};for(var d in b)c(d)},E=function(a,b){var c={};return b.forEach(function(b){c[b]=a[b],delete a[b]}),c},F=function(a,b){return b.map(function(b){return a[b]})},G=function(a,b){return b.forEach(function(b){return a=a.replace("VAL",+b.toFixed(4))}),a},H=function(a,b){for(var c in b){var d=b[c],e=d.chunkNames,f=d.formatString,g=G(f,F(E(a,e),e));a[c]=y(t,g,A)}},I=function(a,b){var c=function(c){var d=b[c].chunkNames,e=a[c];if("string"==typeof e){var f=e.split(" "),g=f[f.length-1];d.forEach(function(b,c){return a[b]=f[c]||g})}else d.forEach(function(b){return a[b]=e});delete a[c]};for(var d in b)c(d)},J=function(a,b){for(var c in b){var d=b[c].chunkNames,e=a[d[0]];a[c]="string"==typeof e?d.map(function(b){var c=a[b];return delete a[b],c}).join(" "):e}},K=function(a){var b=a._currentState;return Object.keys(b).some(function(a){return"string"==typeof b[a]})},L=new p.a,M=p.a.filters,N=function(a,b,c,d){var e=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,f=function(a){for(var b=1;ba.strokeWidth&&(b=a.trailWidth);var c=50-b/2;return e.render(this._pathTemplate,{radius:c,"2radius":2*c})},f.prototype._trailString=function(a){return this._pathString(a)},b.exports=f},{"./shape":7,"./utils":9}],3:[function(a,b,c){var d=a("./shape"),e=a("./utils"),f=function(a,b){this._pathTemplate="M 0,{center} L 100,{center}",d.apply(this,arguments)};f.prototype=new d,f.prototype.constructor=f,f.prototype._initializeSvg=function(a,b){a.setAttribute("viewBox","0 0 100 "+b.strokeWidth),a.setAttribute("preserveAspectRatio","none")},f.prototype._pathString=function(a){return e.render(this._pathTemplate,{center:a.strokeWidth/2})},f.prototype._trailString=function(a){return this._pathString(a)},b.exports=f},{"./shape":7,"./utils":9}],4:[function(a,b,c){b.exports={Line:a("./line"),Circle:a("./circle"),SemiCircle:a("./semicircle"),Square:a("./square"),Path:a("./path"),Shape:a("./shape"),utils:a("./utils")}},{"./circle":2,"./line":3,"./path":5,"./semicircle":6,"./shape":7,"./square":8,"./utils":9}],5:[function(a,b,c){var d=a("shifty"),e=a("./utils"),f=d.Tweenable,g={easeIn:"easeInCubic",easeOut:"easeOutCubic",easeInOut:"easeInOutCubic"},h=function a(b,c){if(!(this instanceof a))throw new Error("Constructor was called without new keyword");c=e.extend({delay:0,duration:800,easing:"linear",from:{},to:{},step:function(){}},c);var d;d=e.isString(b)?document.querySelector(b):b,this.path=d,this._opts=c,this._tweenable=null;var f=this.path.getTotalLength();this.path.style.strokeDasharray=f+" "+f,this.set(0)};h.prototype.value=function(){var a=this._getComputedDashOffset(),b=this.path.getTotalLength(),c=1-a/b;return parseFloat(c.toFixed(6),10)},h.prototype.set=function(a){this.stop(),this.path.style.strokeDashoffset=this._progressToOffset(a);var b=this._opts.step;if(e.isFunction(b)){var c=this._easing(this._opts.easing);b(this._calculateTo(a,c),this._opts.shape||this,this._opts.attachment)}},h.prototype.stop=function(){this._stopTween(),this.path.style.strokeDashoffset=this._getComputedDashOffset()},h.prototype.animate=function(a,b,c){b=b||{},e.isFunction(b)&&(c=b,b={});var d=e.extend({},b),g=e.extend({},this._opts);b=e.extend(g,b);var h=this._easing(b.easing),i=this._resolveFromAndTo(a,h,d);this.stop(),this.path.getBoundingClientRect();var j=this._getComputedDashOffset(),k=this._progressToOffset(a),l=this;this._tweenable=new f,this._tweenable.tween({from:e.extend({offset:j},i.from),to:e.extend({offset:k},i.to),duration:b.duration,delay:b.delay,easing:h,step:function(a){l.path.style.strokeDashoffset=a.offset;var c=b.shape||l;b.step(a,c,b.attachment)}}).then(function(a){e.isFunction(c)&&c()})},h.prototype._getComputedDashOffset=function(){var a=window.getComputedStyle(this.path,null);return parseFloat(a.getPropertyValue("stroke-dashoffset"),10)},h.prototype._progressToOffset=function(a){var b=this.path.getTotalLength();return b-a*b},h.prototype._resolveFromAndTo=function(a,b,c){return c.from&&c.to?{from:c.from,to:c.to}:{from:this._calculateFrom(b),to:this._calculateTo(a,b)}},h.prototype._calculateFrom=function(a){return d.interpolate(this._opts.from,this._opts.to,this.value(),a)},h.prototype._calculateTo=function(a,b){return d.interpolate(this._opts.from,this._opts.to,a,b)},h.prototype._stopTween=function(){null!==this._tweenable&&(this._tweenable.stop(),this._tweenable=null)},h.prototype._easing=function(a){return g.hasOwnProperty(a)?g[a]:a},b.exports=h},{"./utils":9,shifty:1}],6:[function(a,b,c){var d=a("./shape"),e=a("./circle"),f=a("./utils"),g=function(a,b){this._pathTemplate="M 50,50 m -{radius},0 a {radius},{radius} 0 1 1 {2radius},0",this.containerAspectRatio=2,d.apply(this,arguments)};g.prototype=new d,g.prototype.constructor=g,g.prototype._initializeSvg=function(a,b){a.setAttribute("viewBox","0 0 100 50")},g.prototype._initializeTextContainer=function(a,b,c){a.text.style&&(c.style.top="auto",c.style.bottom="0",a.text.alignToBottom?f.setStyle(c,"transform","translate(-50%, 0)"):f.setStyle(c,"transform","translate(-50%, 50%)"))},g.prototype._pathString=e.prototype._pathString,g.prototype._trailString=e.prototype._trailString,b.exports=g},{"./circle":2,"./shape":7,"./utils":9}],7:[function(a,b,c){var d=a("./path"),e=a("./utils"),f="Object is destroyed",g=function a(b,c){if(!(this instanceof a))throw new Error("Constructor was called without new keyword");if(0!==arguments.length){this._opts=e.extend({color:"#555",strokeWidth:1,trailColor:null,trailWidth:null,fill:null,text:{style:{color:null,position:"absolute",left:"50%",top:"50%",padding:0,margin:0,transform:{prefix:!0,value:"translate(-50%, -50%)"}},autoStyleContainer:!0,alignToBottom:!0,value:null,className:"progressbar-text"},svgStyle:{display:"block",width:"100%"},warnings:!1},c,!0),e.isObject(c)&&void 0!==c.svgStyle&&(this._opts.svgStyle=c.svgStyle),e.isObject(c)&&e.isObject(c.text)&&void 0!==c.text.style&&(this._opts.text.style=c.text.style);var f,g=this._createSvgView(this._opts);if(!(f=e.isString(b)?document.querySelector(b):b))throw new Error("Container does not exist: "+b);this._container=f,this._container.appendChild(g.svg),this._opts.warnings&&this._warnContainerAspectRatio(this._container),this._opts.svgStyle&&e.setStyles(g.svg,this._opts.svgStyle),this.svg=g.svg,this.path=g.path,this.trail=g.trail,this.text=null;var h=e.extend({attachment:void 0,shape:this},this._opts);this._progressPath=new d(g.path,h),e.isObject(this._opts.text)&&null!==this._opts.text.value&&this.setText(this._opts.text.value)}};g.prototype.animate=function(a,b,c){if(null===this._progressPath)throw new Error(f);this._progressPath.animate(a,b,c)},g.prototype.stop=function(){if(null===this._progressPath)throw new Error(f);void 0!==this._progressPath&&this._progressPath.stop()},g.prototype.pause=function(){if(null===this._progressPath)throw new Error(f);void 0!==this._progressPath&&this._progressPath._tweenable&&this._progressPath._tweenable.pause()},g.prototype.resume=function(){if(null===this._progressPath)throw new Error(f);void 0!==this._progressPath&&this._progressPath._tweenable&&this._progressPath._tweenable.resume()},g.prototype.destroy=function(){if(null===this._progressPath)throw new Error(f);this.stop(),this.svg.parentNode.removeChild(this.svg),this.svg=null,this.path=null,this.trail=null,this._progressPath=null,null!==this.text&&(this.text.parentNode.removeChild(this.text),this.text=null)},g.prototype.set=function(a){if(null===this._progressPath)throw new Error(f);this._progressPath.set(a)},g.prototype.value=function(){if(null===this._progressPath)throw new Error(f);return void 0===this._progressPath?0:this._progressPath.value()},g.prototype.setText=function(a){if(null===this._progressPath)throw new Error(f);null===this.text&&(this.text=this._createTextContainer(this._opts,this._container),this._container.appendChild(this.text)),e.isObject(a)?(e.removeChildren(this.text),this.text.appendChild(a)):this.text.innerHTML=a},g.prototype._createSvgView=function(a){var b=document.createElementNS("http://www.w3.org/2000/svg","svg");this._initializeSvg(b,a);var c=null;(a.trailColor||a.trailWidth)&&(c=this._createTrail(a),b.appendChild(c));var d=this._createPath(a);return b.appendChild(d),{svg:b,path:d,trail:c}},g.prototype._initializeSvg=function(a,b){a.setAttribute("viewBox","0 0 100 100")},g.prototype._createPath=function(a){var b=this._pathString(a);return this._createPathElement(b,a)},g.prototype._createTrail=function(a){var b=this._trailString(a),c=e.extend({},a);return c.trailColor||(c.trailColor="#eee"),c.trailWidth||(c.trailWidth=c.strokeWidth),c.color=c.trailColor,c.strokeWidth=c.trailWidth,c.fill=null,this._createPathElement(b,c)},g.prototype._createPathElement=function(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg","path");return c.setAttribute("d",a),c.setAttribute("stroke",b.color),c.setAttribute("stroke-width",b.strokeWidth),b.fill?c.setAttribute("fill",b.fill):c.setAttribute("fill-opacity","0"),c},g.prototype._createTextContainer=function(a,b){var c=document.createElement("div");c.className=a.text.className;var d=a.text.style;return d&&(a.text.autoStyleContainer&&(b.style.position="relative"),e.setStyles(c,d),d.color||(c.style.color=a.color)),this._initializeTextContainer(a,b,c),c},g.prototype._initializeTextContainer=function(a,b,c){},g.prototype._pathString=function(a){throw new Error("Override this function for each progress bar")},g.prototype._trailString=function(a){throw new Error("Override this function for each progress bar")},g.prototype._warnContainerAspectRatio=function(a){if(this.containerAspectRatio){var b=window.getComputedStyle(a,null),c=parseFloat(b.getPropertyValue("width"),10),d=parseFloat(b.getPropertyValue("height"),10);e.floatEquals(this.containerAspectRatio,c/d)||(console.warn("Incorrect aspect ratio of container","#"+a.id,"detected:",b.getPropertyValue("width")+"(width)","/",b.getPropertyValue("height")+"(height)","=",c/d),console.warn("Aspect ratio of should be",this.containerAspectRatio))}},b.exports=g},{"./path":5,"./utils":9}],8:[function(a,b,c){var d=a("./shape"),e=a("./utils"),f=function(a,b){this._pathTemplate="M 0,{halfOfStrokeWidth} L {width},{halfOfStrokeWidth} L {width},{width} L {halfOfStrokeWidth},{width} L {halfOfStrokeWidth},{strokeWidth}",this._trailTemplate="M {startMargin},{halfOfStrokeWidth} L {width},{halfOfStrokeWidth} L {width},{width} L {halfOfStrokeWidth},{width} L {halfOfStrokeWidth},{halfOfStrokeWidth}",d.apply(this,arguments)};f.prototype=new d,f.prototype.constructor=f,f.prototype._pathString=function(a){var b=100-a.strokeWidth/2;return e.render(this._pathTemplate,{width:b,strokeWidth:a.strokeWidth,halfOfStrokeWidth:a.strokeWidth/2})},f.prototype._trailString=function(a){var b=100-a.strokeWidth/2;return e.render(this._trailTemplate,{width:b,strokeWidth:a.strokeWidth,halfOfStrokeWidth:a.strokeWidth/2,startMargin:a.strokeWidth/2-a.trailWidth/2})},b.exports=f},{"./shape":7,"./utils":9}],9:[function(a,b,c){function d(a,b,c){a=a||{},b=b||{},c=c||!1;for(var e in b)if(b.hasOwnProperty(e)){var f=a[e],g=b[e];c&&l(f)&&l(g)?a[e]=d(f,g,c):a[e]=g}return a}function e(a,b){var c=a;for(var d in b)if(b.hasOwnProperty(d)){var e=b[d],f="\\{"+d+"\\}",g=new RegExp(f,"g");c=c.replace(g,e)}return c}function f(a,b,c){for(var d=a.style,e=0;e +// +---------------------------------------------------------------------- +// $Id$ + +if (is_file($_SERVER["DOCUMENT_ROOT"] . $_SERVER["SCRIPT_NAME"])) { + return false; +} else { + require __DIR__ . "/index.php"; +} diff --git a/public/static/.gitignore b/public/static/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/public/static/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/route/route.php b/route/route.php new file mode 100644 index 0000000..6f479d3 --- /dev/null +++ b/route/route.php @@ -0,0 +1,20 @@ + +// +---------------------------------------------------------------------- + +Route::get('think', function () { + return 'hello,ThinkPHP5!'; +}); + +Route::get('hello/:name', 'index/hello'); + +return [ + +]; diff --git a/runtime/.gitignore b/runtime/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/runtime/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/think b/think new file mode 100644 index 0000000..6a923b3 --- /dev/null +++ b/think @@ -0,0 +1,22 @@ +#!/usr/bin/env php + +// +---------------------------------------------------------------------- + +namespace think; + +// 加载基础文件 +require __DIR__ . '/thinkphp/base.php'; + +// 应用初始化 +Container::get('app')->path(__DIR__ . '/application/')->initialize(); + +// 控制台初始化 +Console::init(); \ No newline at end of file From 40c34617c15708748082c86f2f12d0b889b0b070 Mon Sep 17 00:00:00 2001 From: LittleJake <465917717@qq.com> Date: Tue, 26 May 2020 13:36:46 +0800 Subject: [PATCH 2/9] 1. extract config to .env 2. add mask to hide real IP 3. add flag-icon-css and using api ip-api.com to check IP country 4. add file caches (or redis) to ease remote redis server load and local server --- application/common/lib/SystemMonitor.php | 118 +++++++++++++++++++++++ application/index/controller/Index.php | 32 +++--- application/index/view/index/index.html | 11 ++- config/.gitignore | 2 - config/cache.php | 50 ++++++++++ config/cache.php.bak | 28 ------ route/route.php | 6 +- 7 files changed, 193 insertions(+), 54 deletions(-) create mode 100644 application/common/lib/SystemMonitor.php delete mode 100644 config/.gitignore create mode 100644 config/cache.php delete mode 100644 config/cache.php.bak diff --git a/application/common/lib/SystemMonitor.php b/application/common/lib/SystemMonitor.php new file mode 100644 index 0000000..37b4380 --- /dev/null +++ b/application/common/lib/SystemMonitor.php @@ -0,0 +1,118 @@ +has($v) + && !empty(Cache::store('flag')->get($v))) + $info[$v] = Cache::store('flag')->get($v); + else { + $i = json_decode(self::curl_get(self::$url.$tmp),true); + Cache::store('flag')->set($v, $i); + $info[$v] = $i; + } + } + }else{ + $tmp = strstr($ip, '/', true); + if(Cache::store('flag')->has($ip) + && !empty(Cache::store('flag')->get($ip))) + return Cache::store('flag')->get($ip); + else { + $info[$ip] = json_decode(self::curl_get(self::$url.$tmp),true); + Cache::store('flag')->set($ip, $info); + } + } + + return $info; + } + + static public function getHashes(){ + if(Cache::has('system_monitor:hashes') + && !empty(Cache::get('system_monitor:hashes'))){ + $hash = Cache::get('system_monitor:hashes'); + } else { + $hash = Cache::store('redis')->handler() + ->hGetAll("system_monitor:hashes"); + Cache::set('system_monitor:hashes', $hash); + } + + + return $hash; + } + + static public function getStat($ip) { + if(Cache::has("system_monitor:stat:$ip") + && !empty(Cache::get("system_monitor:stat:$ip"))){ + $stat = Cache::get("system_monitor:stat:$ip"); + } else{ + $stat = Cache::store('redis')->handler() + ->get("system_monitor:stat:$ip"); + Cache::set("system_monitor:stat:$ip", $stat); + } + + return $stat; + } + + static public function getInfo($ip) { + if(Cache::has("system_monitor:info:$ip") + && !empty(Cache::get("system_monitor:info:$ip"))){ + $info = Cache::get("system_monitor:info:$ip"); + } else{ + $info = Cache::store('redis')->handler() + ->hGetAll("system_monitor:info:$ip"); + Cache::set("system_monitor:info:$ip", $info); + } + + return $info; + } + + static public function timeFormat($time){ + return floor($time / (24*60*60)) ." Days ". + floor(($time / (60*60)) % 24) ." Hours ". + floor(($time / (60)) % 60) . " Minutes ". + floor($time % 60) . " Seconds"; + } + + static private function curl_get($url){ + $header = array( + 'Accept: application/json', + ); + $curl = curl_init(); + //设置抓取的url + curl_setopt($curl, CURLOPT_URL, $url); + //设置头文件的信息作为数据流输出 + curl_setopt($curl, CURLOPT_HEADER, 0); + // 超时设置,以秒为单位 + curl_setopt($curl, CURLOPT_TIMEOUT, 1); + + // 超时设置,以毫秒为单位 + curl_setopt($curl, CURLOPT_TIMEOUT_MS, 1000); + + // 设置请求头 + curl_setopt($curl, CURLOPT_HTTPHEADER, $header); + //设置获取的信息以文件流的形式返回,而不是直接输出。 + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + //执行命令 + $data = curl_exec($curl); + + // 显示错误信息 + if (curl_error($curl)) + Log::error(curl_error($curl)); + else + curl_close($curl); + + return $data; + } +} diff --git a/application/index/controller/Index.php b/application/index/controller/Index.php index 6b377d6..001773c 100644 --- a/application/index/controller/Index.php +++ b/application/index/controller/Index.php @@ -1,35 +1,33 @@ hGetAll("system_monitor:hashes"); + $hash = SystemMonitor::getHashes(); + $info = SystemMonitor::fetchIPInfo(array_values($hash)); $this->assign("hash", $hash); + $this->assign("info", $info); return $this->fetch(); } public function info($token = ''){ - if(strlen($token) != 64){ - return $this->error("Wrong Token"); - } + if(strlen($token) != 64) + $this->error("Wrong Token"); + + $hash = SystemMonitor::getHashes(); + $ip = $hash[$token]; + + if(empty($ip)) + $this->error("Wrong Token"); - $ip = Cache::handler()->hMGet("system_monitor:hashes", [$token])[$token]; - if(empty($ip)){ - return $this->error("Wrong Token"); - } - $json = json_decode(Cache::handler()->get("system_monitor:stat:".$ip), true); - $uptime = intval($json['Uptime']); - $uptime_str = floor($uptime / (24*60*60)) ." Days ". - floor(($uptime / (60*60)) % 24) ." Hours ". - floor(($uptime / (60)) % 60) . " Minutes ". - floor($uptime % 60) . " Seconds"; - $info = Cache::handler()->hGetAll("system_monitor:info:".$ip); + $json = json_decode(SystemMonitor::getStat($ip), true); + $uptime_str = SystemMonitor::timeFormat(intval($json['Uptime'])); + $info = SystemMonitor::getInfo($ip); $this->assign("json", $json); $this->assign("uptime", $uptime_str); $this->assign("info", $info); diff --git a/application/index/view/index/index.html b/application/index/view/index/index.html index 1702506..951d8ff 100644 --- a/application/index/view/index/index.html +++ b/application/index/view/index/index.html @@ -3,15 +3,22 @@ Title +
-

Monitor List

+

Server Monitor List

    {foreach $hash as $k => $v} -
  1. {$v}
  2. +
  3. + + + {:preg_replace("/\\.[\\d]+/",".*",$v)} + +
  4. {/foreach}
+
\ No newline at end of file diff --git a/config/.gitignore b/config/.gitignore deleted file mode 100644 index 4c1f1b7..0000000 --- a/config/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Created by .ignore support plugin (hsz.mobi) -cache.php \ No newline at end of file diff --git a/config/cache.php b/config/cache.php new file mode 100644 index 0000000..818cd4f --- /dev/null +++ b/config/cache.php @@ -0,0 +1,50 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 缓存设置 +// +---------------------------------------------------------------------- + +return [ + // 驱动方式 + 'type' => 'complex', + 'default' => [ + 'type' => 'file', + // 全局缓存有效期(0为永久有效) + 'expire'=> 150, + // 缓存前缀 + 'prefix'=> 'monitor', + // 缓存目录 + 'path' => '../runtime/cache/', + ], + 'redis' => [ + 'type' => 'Redis', + 'host' => Env::get('redis.host'), + 'port' => Env::get('redis.port'), + 'password' => Env::get('redis.password'), + 'select' => 0, + 'timeout' => 0, + 'expire' => 0, + 'persistent' => false, + 'prefix' => '', + 'serialize' => true, + ], + 'flag' => [ + 'type' => 'file', + // 全局缓存有效期(0为永久有效) + 'expire'=> 0, + // 缓存前缀 + 'prefix'=> 'flag', + // 缓存目录 + 'path' => '../runtime/cache/', + ], + +]; diff --git a/config/cache.php.bak b/config/cache.php.bak deleted file mode 100644 index 1908d11..0000000 --- a/config/cache.php.bak +++ /dev/null @@ -1,28 +0,0 @@ - -// +---------------------------------------------------------------------- - -// +---------------------------------------------------------------------- -// | 缓存设置 -// +---------------------------------------------------------------------- - -return [ - // 驱动方式 - 'type' => 'Redis', - 'host' => '', - 'port' => 14191, - 'password' => '', - 'select' => 0, - 'timeout' => 0, - 'expire' => 0, - 'persistent' => false, - 'prefix' => '', - 'serialize' => true, -]; diff --git a/route/route.php b/route/route.php index 6f479d3..429111f 100644 --- a/route/route.php +++ b/route/route.php @@ -9,11 +9,7 @@ // | Author: liu21st // +---------------------------------------------------------------------- -Route::get('think', function () { - return 'hello,ThinkPHP5!'; -}); - -Route::get('hello/:name', 'index/hello'); +Route::get('info/:token','index/index/info'); return [ From 04e02c648ffa7d3061be458779a98495a9fe2bb0 Mon Sep 17 00:00:00 2001 From: LittleJake <465917717@qq.com> Date: Tue, 26 May 2020 17:32:15 +0800 Subject: [PATCH 3/9] 1. increase cache TTL (less aggressive) 2. add MDUI.js framework 3. improve page style --- application/common/lib/SystemMonitor.php | 28 ++- application/index/controller/Index.php | 6 +- application/index/view/index/index.html | 58 ++++-- application/index/view/index/info.html | 167 +++++++++++------- application/index/view/index/info_ajax.html | 185 ++++++++++++++++++++ config/cache.php | 2 +- 6 files changed, 358 insertions(+), 88 deletions(-) create mode 100644 application/index/view/index/info_ajax.html diff --git a/application/common/lib/SystemMonitor.php b/application/common/lib/SystemMonitor.php index 37b4380..9193938 100644 --- a/application/common/lib/SystemMonitor.php +++ b/application/common/lib/SystemMonitor.php @@ -51,13 +51,27 @@ static public function getHashes(){ } static public function getStat($ip) { - if(Cache::has("system_monitor:stat:$ip") - && !empty(Cache::get("system_monitor:stat:$ip"))){ - $stat = Cache::get("system_monitor:stat:$ip"); - } else{ - $stat = Cache::store('redis')->handler() - ->get("system_monitor:stat:$ip"); - Cache::set("system_monitor:stat:$ip", $stat); + if(is_array($ip)){ + foreach ($ip as $v){ + if(Cache::has("system_monitor:stat:$v") + && !empty(Cache::get("system_monitor:stat:$v"))){ + $stat[$v] = Cache::get("system_monitor:stat:$v"); + } else{ + $tmp = json_decode(Cache::store('redis')->handler() + ->get("system_monitor:stat:$v"),true); + $stat[$v] = $tmp; + Cache::set("system_monitor:stat:$v", $tmp); + } + } + }else{ + if(Cache::has("system_monitor:stat:$ip") + && !empty(Cache::get("system_monitor:stat:$ip"))){ + $stat = Cache::get("system_monitor:stat:$ip"); + } else{ + $stat = json_decode(Cache::store('redis')->handler() + ->get("system_monitor:stat:$ip"),true); + Cache::set("system_monitor:stat:$ip", $stat); + } } return $stat; diff --git a/application/index/controller/Index.php b/application/index/controller/Index.php index 001773c..3422b19 100644 --- a/application/index/controller/Index.php +++ b/application/index/controller/Index.php @@ -9,7 +9,9 @@ public function index() { $hash = SystemMonitor::getHashes(); $info = SystemMonitor::fetchIPInfo(array_values($hash)); + $json = SystemMonitor::getStat(array_values($hash)); + $this->assign("json", $json); $this->assign("hash", $hash); $this->assign("info", $info); return $this->fetch(); @@ -25,12 +27,14 @@ public function info($token = ''){ if(empty($ip)) $this->error("Wrong Token"); - $json = json_decode(SystemMonitor::getStat($ip), true); + $json = SystemMonitor::getStat($ip); $uptime_str = SystemMonitor::timeFormat(intval($json['Uptime'])); $info = SystemMonitor::getInfo($ip); $this->assign("json", $json); $this->assign("uptime", $uptime_str); $this->assign("info", $info); + if($this->request->isAjax()) + return $this->fetch("index/info_ajax"); return $this->fetch(); } } diff --git a/application/index/view/index/index.html b/application/index/view/index/index.html index 951d8ff..c1dab2b 100644 --- a/application/index/view/index/index.html +++ b/application/index/view/index/index.html @@ -2,23 +2,57 @@ - Title + Server Monitor List + - -
-

Server Monitor List

-
    + +
    +
    + + menu + + Server Monitor List +
    +
    +
    +
    +
- + +
+
+ Server Monitor
+ + + \ No newline at end of file diff --git a/application/index/view/index/info.html b/application/index/view/index/info.html index d7a5c18..453bcb4 100644 --- a/application/index/view/index/info.html +++ b/application/index/view/index/info.html @@ -2,7 +2,9 @@ - Title + Info + + -
-

System Info

- {foreach $info as $k => $v} -

{$k}

-

{$v}

- {/foreach} -
-
-

CPU Load

-
- 1 Min -
-
- 5 Min -
-
- 15 Min -
-
-
-

Memory

-
-

Memory {$json['Memory']['Mem']['used']} MB / {$json['Memory']['Mem']['total']} MB

-
-
-
-

Swap {$json['Memory']['Swap']['used']} MB / {$json['Memory']['Swap']['total']} MB

-
-
-
-
-

Disk

-
-

{$json['Disk']['used']} / {$json['Disk']['total']}

-
+ -
-

Process

-
-

{$json['Process']}

-
-
-
-

Connection

-
-

{$json['Connection']}

-
-
-
-

Uptime

-
-

{$uptime}

+
+
+
+
+
System Info
+
IP, System version, etc.
+ keyboard_arrow_down +
+
+
+ {foreach $info as $k => $v} +

{$k}

+

{$v|default='None'}

+ {/foreach} +
+
+

Process

+

{$json['Process']}

+

Connection

+

{$json['Connection']}

+

Uptime

+

{$uptime}

+
+
+
+
+
+ +
CPU Load
+ keyboard_arrow_down +
+
+
+ 1 Min +
+
+ 5 Min +
+
+ 15 Min +
+
+
+
+
+ +
Storage
+ keyboard_arrow_down +
+
+
+

{$json['Disk']['used']} / {$json['Disk']['total']}

+
+
+
+
+
+
+ +
Memory
+
Including Physical and Swap.
+ keyboard_arrow_down +
+
+
+

Memory {$json['Memory']['Mem']['used']} MB / {$json['Memory']['Mem']['total']} MB

+
+
+
+

Swap {$json['Memory']['Swap']['used']} MB / {$json['Memory']['Swap']['total']} MB

+
+
+
+
+
+ \ No newline at end of file diff --git a/application/index/view/index/info_ajax.html b/application/index/view/index/info_ajax.html new file mode 100644 index 0000000..47d69f5 --- /dev/null +++ b/application/index/view/index/info_ajax.html @@ -0,0 +1,185 @@ + +
+
+
+ +
System Info
+
IP, System version, etc.
+ keyboard_arrow_down +
+
+
+ {foreach $info as $k => $v} +

{$k}

+

{$v|default='None'}

+ {/foreach} +
+
+

Process

+

{$json['Process']}

+

Connection

+

{$json['Connection']}

+

Uptime

+

{$uptime}

+
+
+
+
+
+ +
CPU Load
+ keyboard_arrow_down +
+
+
+ 1 Min +
+
+ 5 Min +
+
+ 15 Min +
+
+
+
+
+ +
Storage
+ keyboard_arrow_down +
+
+
+

{$json['Disk']['used']} / {$json['Disk']['total']}

+
+
+
+
+
+
+ +
Memory
+
Including Physical and Swap.
+ keyboard_arrow_down +
+
+
+

Memory {$json['Memory']['Mem']['used']} MB / {$json['Memory']['Mem']['total']} MB

+
+
+
+

Swap {$json['Memory']['Swap']['used']} MB / {$json['Memory']['Swap']['total']} MB

+
+
+
+
+ +
+ + \ No newline at end of file diff --git a/config/cache.php b/config/cache.php index 818cd4f..9035311 100644 --- a/config/cache.php +++ b/config/cache.php @@ -19,7 +19,7 @@ 'default' => [ 'type' => 'file', // 全局缓存有效期(0为永久有效) - 'expire'=> 150, + 'expire'=> 240, // 缓存前缀 'prefix'=> 'monitor', // 缓存目录 From 18a9eee786abf447e76dc1fac14beaec317ba934 Mon Sep 17 00:00:00 2001 From: LittleJake <465917717@qq.com> Date: Sun, 24 May 2020 09:45:39 +0800 Subject: [PATCH 4/9] update --- application/index/controller/Index.php | 1 + application/index/view/index/info.html | 1 + route/route.php | 1 + 3 files changed, 3 insertions(+) diff --git a/application/index/controller/Index.php b/application/index/controller/Index.php index 3422b19..5a09772 100644 --- a/application/index/controller/Index.php +++ b/application/index/controller/Index.php @@ -3,6 +3,7 @@ use app\common\lib\SystemMonitor; + class Index extends Base { public function index() diff --git a/application/index/view/index/info.html b/application/index/view/index/info.html index 453bcb4..12962d7 100644 --- a/application/index/view/index/info.html +++ b/application/index/view/index/info.html @@ -23,6 +23,7 @@ } .line { margin: 20px; + width: 70%; height: 8px; position: relative; } diff --git a/route/route.php b/route/route.php index 429111f..2c165d7 100644 --- a/route/route.php +++ b/route/route.php @@ -9,6 +9,7 @@ // | Author: liu21st // +---------------------------------------------------------------------- + Route::get('info/:token','index/index/info'); return [ From 8fec21ad3d5a6d690857394555fc737482145abe Mon Sep 17 00:00:00 2001 From: LittleJake <465917717@qq.com> Date: Wed, 27 May 2020 10:00:11 +0800 Subject: [PATCH 5/9] 1. update style 2. use cdn --- application/index/view/index/index.html | 52 ++++++++++++++++++- application/index/view/index/info.html | 15 ++---- application/index/view/index/info_ajax.html | 1 - public/js/progressbar.js/progressbar.min.js | 6 --- .../js/progressbar.js/progressbar.min.js.map | 1 - 5 files changed, 54 insertions(+), 21 deletions(-) delete mode 100644 public/js/progressbar.js/progressbar.min.js delete mode 100644 public/js/progressbar.js/progressbar.min.js.map diff --git a/application/index/view/index/index.html b/application/index/view/index/index.html index c1dab2b..cd8fe4b 100644 --- a/application/index/view/index/index.html +++ b/application/index/view/index/index.html @@ -7,12 +7,24 @@ + @@ -29,16 +41,52 @@ {$info[$v]['city'].", ".$info[$v]['countryCode']}
+ {if(!empty($json[$v]))} + {else} + + {/if} {/foreach}
- Server Monitor +
+
+
+
Server Monitor
+
+
+
+

Active Servers

+

{:sizeof($json)}

+
+
+ +
+
+
+
+
+
About
+
+
+

Server Monitor

+

Made and Loved by LittleJake, 2020.

+

Every code is valuable.

+
+
+
+
+
+
+ - +