作者 景龙

新建独角星球项目

要显示太多修改。

为保证性能只显示 27 of 27+ 个文件。

.buildpath
.DS_Store
.project
.settings
.idea
/api
/public/api
/public/assets/dist
/node_modules
Vagrantfile
.vagrant
\ No newline at end of file
... ...
如何贡献我的源代码
===
... ...
ThinkCMF遵循Apache2开源协议发布,并提供免费使用。
版权所有Copyright © 2013-2018 by ThinkCMF (https://www.thinkcmf.com)
All rights reserved。
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.
... ...
ThinkCMF 5.0.190312 正式版
===============
> ThinkCMF5.1已经发布,如果你是新同学,请学习[ThinkCMF5.1](https://github.com/thinkcmf/thinkcmf/tree/5.1),更清爽,更自由!
### 系列讲座
https://www.thinkcmf.com/college.html
### ThinkCMF5主要特性
* 基于全新 ThinkPHP5.0开发
* 更规范的代码,遵循PSR-2命名规范和PSR-4自动加载规范
* 更规范的数据库设计
* 前后台完全基于bootstrap3
* 增加 api 模块(需单独下载)
* 支持 composer 管理第三方库
* 核心化:独立核心代码包
* 应用化:开发者以应用的形式增加项目模模块
* 插件化:更强的插件机制,开发者以插件形式扩展功能
* 模板化:模板完全傻瓜式,用户无须改动任何代码即可在后台完成模板设计和配置
* 增加 URL美化功能,支持别名设置,更简单
* 独立的回收站功能,可以管理所有应用临时删除的数据
* 统一的资源管理,相同文件只保存一份
* 注解式的后台菜单管理功能,方便开发者代码管理后台菜单
* 文件存储插件化,默认支持七牛文件存储插件
* 模板制作标签化,内置多个cmf标签,方便小白用户
* 更人性化的导航标签,可以随意定制 html 结构
* 后台首页插件化,用户可以定制的网站后台首页
### 环境推荐
> php5.5+
> mysql 5.6+
> 打开rewrite
### 最低环境要求
> php5.4+
> mysql 5.5+ (mysql5.1安装时选择utf8编码,不支持表情符)
> 打开rewrite
### 运行环境配置教程
https://www.thinkcmf.com/topic/1502.html
### 自动安装
> 之前安装过 cmf5的同学,请手动创建`data/install.lock`文件
代码已经加入自动安装程序,如果你在安装中有任何问题请提交 issue!
1. public目录做为网站根目录,入口文件在 public/index.php
2. 配置好网站,请访问http://你的域名
enjoy your cmf~!
### 系统更新
如果您是已经安装过 cmf5的用户,请查看 update 目录下的 sql 升级文件,根据自己的下载的程序版本进行更新
### API开发 (支持app,小程序,web)
如果你需要 `api` 开发请下载:
ThinkCMF5 API :https://github.com/thinkcmf/thinkcmfapi
### 完整版目录结构
```
thinkcmf 根目录
├─api api目录(核心版不带)
├─app 应用目录
│ ├─portal 门户应用目录
│ │ ├─config.php 应用配置文件
│ │ ├─common.php 模块函数文件
│ │ ├─controller 控制器目录
│ │ ├─model 模型目录
│ │ └─ ... 更多类库目录
│ ├─ ... 更多应用
│ ├─command.php 命令行工具配置文件
│ ├─common.php 应用公共(函数)文件
│ ├─config.php 应用(公共)配置文件
│ ├─database.php 数据库配置文件
│ ├─tags.php 应用行为扩展定义文件
│ └─route.php 路由配置文件
├─data 数据目录
│ ├─conf 动态配置目录
│ ├─runtime 应用的运行时目录(可写)
│ └─ ... 更多
├─public WEB 部署目录(对外访问目录)
│ ├─api api入口目录(核心版不带)
│ ├─plugins 插件目录
│ ├─static 静态资源存放目录(css,js,image)
│ ├─themes 前后台主题目录
│ │ ├─admin_simpleboot3 后台默认主题
│ │ └─simpleboot3 前台默认主题
│ ├─upload 文件上传目录
│ ├─index.php 入口文件
│ ├─robots.txt 爬虫协议文件
│ ├─router.php 快速测试文件
│ └─.htaccess apache重写文件
├─simplewind
│ ├─cmf CMF核心库目录
│ ├─extend 扩展类库目录
│ ├─thinkphp thinkphp目录
│ └─vendor 第三方类库目录(Composer)
├─composer.json composer 定义文件
├─LICENSE.txt 授权说明文件
├─README.md README 文件
├─think 命令行入口文件
```
### 开发手册
http://www.kancloud.cn/thinkcmf/doc
### QQ群:
`ThinkCMF 官方交流群`:316669417
`ThinkCMF 高级交流群`:100828313 (付费)
高级群专属权益:
第一波:两个后台风格(ThinkCMF官网风格后台主题,蓝色风格后台主题)
第二波:ThinkCMF5完全开发手册离线版(PDF,EPUB,MOBI格式)
更多专属权益正在路上...
`ThinkCMF 铲屎官交流群`:415136742 (生活娱乐,为有喵的猿人准备)
### 话题专区
http://www.thinkcmf.com/topic/index/index/cat/11.html
### 反馈问题
https://github.com/thinkcmf/thinkcmf/issues
### 更新日志
#### 5.0.190419
* 优化动态配置函数
* 优化门户几处where用法
* 优化门户后台表单提交方式
* 优化后台菜单url生成
* 优化api跨域处理
* 修复模板设计公共配置文件有数组时报错
* 修复模板设计公共配置文件里数组列表有数据不显示
#### 5.0.190312
* 增加`app,api和插件`composer第三方库支持
* 增加插件`@adminMenuRoot`注解
* 增加后台模板动态设置
* 增加`WEB_ROOT`常量
* 优化url美化可能引起的安全漏洞(漏洞编号CVE-2019-6713 感谢topsec(zhan_ran)的及时反馈)
* 修复api跨域问题
* 修复子导航标签报错
* 计划删除`PLUGINS_PATH`常量,请不要再使用
* 删除`phpoffice/phpspreadsheet`,`phpoffice/phpexcel`,`dompdf/dompdf`第三方库,请自行安装
* 移动`qiniu/php-sdk`库到七牛插件
#### 5.0.190111
* 升级ThinkPHP到`5.0.24`(包含安全更新)
* 增加后台模板按文件列表设计
* 修复url无法美化
* 修复页面数据源报错
#### 5.0.181231
* 规范所有`5.0`代码方便升级到`5.1`
* 规范控制器`_initialize`方法为`initialize`
* 调整`cmf_theme_path,cmf_default_theme,cmf_admin_theme_path,cmf_admin_default_theme`到 `template` 配置下
* `hook,hook_one`方法取消`$extra`参数
* 增加数据库调试模式开关
* 增加模板设计关闭功能
* 优化七牛下载文件名为上传文件名
* 优化清除缓存,清除opcache缓存
* 修复七牛获取水印样式报错
* 修复模板设计后,前台 js 报错
#### 5.0.181212
* 升级ThinkPHP到`5.0.23`(包含安全更新)
* 增加`js-bootstrap-year`前端组件
* 增加文件大小格式化函数`cmf_file_size_format`
* 修复网站在二级目录下无法设计模板问题
* 修复模板设计公共模板设置数组无法编辑问题
* 修复模板设计公共组件数组无法编辑问题
* 修复门户模板`page.html`报错
* 优化图片验证码生成
* 优化`Rest API`跨域问题处理
#### 5.0.180901
* 增强模板设计,提供可视化模板设计
* 增加模板设计界面钩子
* 增加验证码图片钩子
* 增加后台设置网站信息界面钩子
* 增加后台清除缓存界面钩子
* 增加后台导航管理界面钩子
* 增加后台友情链接管理界面钩子
* 增加后台幻灯片管理界面钩子
* 增加后台幻灯片页面列表界面钩子
* 增加后台幻灯片页面添加界面钩子
* 增加后台幻灯片页面编辑界面钩子
* 增加后台管理员列表界面钩子
* 增加后台管理员添加界面钩子
* 增加后台管理员编辑界面钩子
* 增加后台角色管理界面钩子
* 增加后台角色添加界面钩子
* 增加后台角色编辑界面钩子
* 增加后台角色授权界面钩子
* 增加用户管理本站用户列表界面钩子
* 增加资源管理列表界面钩子
* 增加用户管理第三方用户列表界面钩子
* 增加后台首页界面钩子
* 增加后台回收站界面钩子
* 增加后台菜单管理界面钩子
* 增加后台自定义登录是否开启钩子
* 增加admin.js`js-ajax-btn`组件
* 优化插件加载
* 优化前后台上传js
[门户应用]
* 增加文章音频,视频功能
* 增加门户后台文章管理列表界面钩子
* 增加门户后台文章添加界面钩子
* 增加门户后台文章编辑界面钩子
* 增加门户后台文章分类管理列表界面钩子
* 增加门户后台文章分类添加界面钩子
* 增加门户后台文章分类编辑界面钩子
* 增加门户后台页面管理列表界面钩子
* 增加门户后台页面添加界面钩子
* 增加门户后台页面编辑界面钩子
* 增加门户后台文章标签管理列表界面钩子
* 增加门户后台文章添加编辑界面右侧栏钩子
* 增加门户后台文章添加编辑界面主要内容钩子
* 增加后台文章分类显示隐藏功能
* 增加后台文章分类列表搜索功能
* 增加后台文章分类列表层级折叠功能
#### 5.0.180626
* 升级TP到`5.0.20`
* 增加插件REST api基类`PluginRestBaseController`
* 增加我的喜欢功能
* 增加手机相关设备类型判断函数
* 优化百度编辑器视频上传
* 优化get_client_ip()方法,默认使用高级模式
* 优化手机号检查支持国际手机号
* 优化图片和文件链接转化函数
* Restful api基类增加apiVersion属性
* 修复邮箱验证码发送失败
* 七牛插件增加东南亚节点
* 前台模板文件解析标准化
[门户应用]
* 增加文章`thumbnail`字段
* 增加文章收藏数功能
#### 5.0.180525
* 修复ajax请求普通页面时返回格式为json
* 优化图片链接生成
* 修复插件模板常量地址问题
* 修复后台用户注册验证开关错误 #481
* 增加后台刷新后保持当前页面的功能 #475
* 取消用户名注册和绑定功能
* 优化无限滚动jquery插件
#### 5.0.180508
* 修复用户注册问题
* 优化缓存清理,防止删除日志文件
#### 5.0.180501
[核心]
* 升级TP到5.0.19,增强安全性
* 修复模板设计数组编辑验证规则不生效 #440
* 修复后台登录失效后iframe里加载首页
* 修复七牛插件上传云存储文件没有后缀名问题#437
* 修复删除评论时的错误文案提示 #443
* 修复ueditor漏洞#431
* 修复PHP7.2下后台清除报错
* 修复前台账号绑定无法获取mobile、email验证码 #418
* 修复百度编辑器大附件上传问题
* 修复百度编辑器大视频文件上传问题
* 升级font awesome到4.7.0
[门户应用]
* 修复文章分类修改层级后子分类层级不更新问题
* 优化 portal:articles 标签field,order 属性支持 php 变量
* 修复文章分类别名设置为纯数字,路由生成错误,无法访问。 #438
* 增加页面相册和附件功能 #449
#### 5.0.180123
[核心]
* 增加小程序管理插件
* 增加插件后台首页左侧菜单显示
* 增加 themes 根命名空间
* 增加模板设计图片模板变量取消功能
* 增加插件自定义处理配置功能
* 增加插件后台权限管理功能
* 增加后台模板切换
* 增加直传云存储功能
* 增强导航和子导航标签,自定义更随意
* 增加before_content,fetch_upload_view,log_write_done,switch_admin_theme钩子
* 增加PluginAdminBaseController基类
* 增加系统钩子同步
* 增加插件中可使用$site_info变量
* 增加 xml 生成函数
* 增加插件设置上传文件组件
* 优化数字验证码日志写入增加过期时间配置
* 优化数字验证码逻辑,增加数字验证码发送图片验证码,【升级时注意界面逻辑】
* 优化验证码生成功能,可增加验证码插件管理验证码生成
* 优化钩子插件管理
* 优化插件注册机制
* 优化后台首页菜单加载
* 修复模板管理变量数据为array时删除出错 #392
* 修复后台管理搜索翻页时条件丢失问题 #366
* 修复删除第三方用户时报错 #368
* 修复在使用cdn加速js时后台文章编辑器时无法加载编辑器配置
* 修复模板设计模板变量file类型不支持上传 #136
* 修复用户行为周期设置无效 #382
* 修复个人信息编辑签名验证问题
* 修复用户生日早于1970年报错
* 修复地址坐标选择搜索后无法确定坐标问题
* 优化IE8,9下的兼容问题
* 优化前台未登录时跳转方式
[安装程序]
* 增加安装时管理员密码长度限制 #334
* 增加安装时检查 rewrite设置
* 增加安装时 innodb 检测
* 更正PHP版本要求
[门户应用]
* 优化portal:articles标签可在模板里设置分页参数和样式
* 优化portal:articles标签所有属性都支持PHP变量
* 优化标签控制器支持标签名
* 增加portal:tagArticles标签
* 取消文章列表用户关联查询
* 修复文章多分类进文章列表文章重复问题
#### 5.0.170927
[核心]
* 增加是否开放注册设置
* 增加已经安装模板文件检测是否已经删除功能
* 增加模板卸载风险提示
* 增加钩子同步功能
* 增加用户操作同步功能 #291
* 增加网站信息【$site_info】变量,可以在插件中使用 #310
* 修复添加管理员不能登录 #110
* 优化 admin.js
* 优化后台模板设计排版
* 优化后台加密码设置
* 返回按钮统一优化
* 优化 url 美化时规划选择
* 修复`api`模块缺少函数报错
* 修复回收站还原提示错误 #111
* 修复原始网址和显示网址同时有参数的情况下,两个参数值相同的时候不能解析URL
* 修复模板设计数组编辑功能缺失
* 修复后台登录在双核浏览器下会使用 IE 内核问题#168
* 修复模板widget只有数组时,后台设计保存时报错
* 修复日期选择在windows firefox下报错
* 修复模板设计数据源页面清空链接错误
* 修复后台模板设计,json文件中的数组数据,不能正常显示 #222
* 修复`cmf\lib\Auth\check`方法逻辑问题 #252
* 修复后台用户登录自动退出后iframe页跳转到首页的问题
* 修复用户个人资料修改问题
* 修复绑定手机号和绑定邮箱号惟一性提示信息错
[安装程序]
* 更改安装时数据库默认为127.0.0.1
* 优化安装时链接生成
[门户应用]
* 增加前台文章控制器默认分类指定
* 增加后台文章列表所在分类列
* 增加后台文章分类必须指定分类验证
* 增加 portal:articles 标签 limit可以设置变量
* 增加模板设计页面数据源
* 完善 ApiService获取指定分类下的所有子分类方法
* 增加portal:categories,portal:subCategories,portal:allSubCategories标签
* 增加文章、页面、分类模板选择时模板文件名称查看
* 增加文章保存钩子
* 优化指定分类下所有子分类获取方法
* 修复文章分类管理中不保存选择的模板 #107
* 修复面包屑标签 self属性无法识别 false
* 修复后台编辑文件会覆盖原作者ID #175
* 修复后台文章保存后排序变化问题
* 修复添加文章分类时 path 没数据问题
[升级指导]
https://www.kancloud.cn/thinkcmf/doc/327443
#### 5.0.170607
[核心]
* 删除 app/common.php
* 规范 admin.js frontend.js函数名
* 更改后台模板设计的模板文件列表排序规则为从小到大排序
* 增加模板切换钩子,方便开发者实现复杂的模板切换功能
* 增加插件作者和演示信息
* 增加数字验证码模板编辑功能
* 增加模板变量编辑控件color
* 增加插件配置组件时间,图片,地理位置,颜色
* 优化模板配置更新
* 优化文件上传,检查已经上传文件是否存在,不存在重新上传
* 修复插件增加新配置时报错
* 修复模板变量 rule 规则存在,但没有规则时模板设计保存会报错
* 修复后台清除缓存后url生成不美化
* 修复模板设计一个页面有多个数组编辑问题
* 修复cdn设置不生效
* 修复后台菜单添加子菜单不选择上级问题
* 修复后台可能多个滚动条
* 修复后台添加、编辑角色一处文字错误
* 修复插件更新时不更新新增的钩子
[门户应用]
* 完善前台模板钩子
* 完善文章标签功能
* 增加前台模板手机注册关闭开关
* 优化文章后台文章分类链接生成
* 修复ff下文章相册图片替换和删除问题
* 修复文章分类排序功能
#### 5.0.170520
[核心]
* 完善插件后台管理
* 后台登录插件化
* 后台首页插件化
* 文件存储插件化
* 增加 URL 美化功能
* 增加后台加密码功能
* 增加用户修改头像
* 增加插件设置表单验证
* 增加前台后台通用语言包
* 增加编辑器里上传文件链接替换
* 增加应用 command.php 配置文件
* 增加后台管理员添加编辑用户名,邮箱惟一性验证
* 优化安装程序
* 优化上传文件
* 优化后台首页
* 优化回收站
* 优化插件启用禁用
* 优化小屏下后台首页不兼容问题
* 优化后台图片查看
* 修复后台菜单编辑不生效
* 修复幻灯片添加不显示问题
* 修复导航数据源数据返回为空时报错
* 修复 pathinfo 模式下后台本站用户默认头像不显示问题
* 修复后台 cdn 不能设置
* 合并asset应用到 user
[门户应用]
* 增加文章收藏功能
* 增加文章点赞限制,一个用户只能点赞一次
* 增加文章分类缩略图
* 优化文章分类管理删除
* 优化文章页和页面页内容图片样式问题
* 修复文章添加编辑默认图片错误
* 修复分类下没有文章时报错
* 修复页面模板设置无效
* 修复页面删除后仍可以访问
#### 5.0.170505
[核心]
* 完善用户注册流程
* 完善插件功能
* 增加手机验证码发送钩子
* 增加手机验证码发送演示插件
* 增加用户邮箱绑定
* 增加用户手机绑定
* 增加常用模板钩子
* 增加模板设计图片上传
* 增加用户密码修改
* 增加用户收藏功能
* 增加导航标签,子导航标签增加 `max-level` 设置
* 修复邮箱验证码发送
* 修复windows下获取模板数据时模板文件路径问题
* 修复单文件,多文件上传
* 修复后台首页用户昵称一直显示admin
* 修复 `navigation`,`subNavigation` 标签两个以上不能同时使用问题
* 修复 console 模式报错
* 取消前台有错误时界面刷新
[门户应用]
* 增加文章附件功能
* 优化文章相册
#### 5.0.170422
[核心]
* 完善幻灯片
* 完善后台控制器方法注释
* 增加调试模式下实时更新模板配置
* 增加友情链接图片上传
* 增加应用公共语言包功能
* 增加资源管理
* 增加模板设计数据源层级关系
* 更新jQuery Form版本
* 增加后台菜单类型是否有界面区分
* 增加权限验证时权限规则里没有的规则不用验证
* 增加前台网站信息获取
* 优化后台菜单导入
* 统一排序规则,按从小到大排序
* 修复后台模板管理点更新提示卸载
* 修复标签`NavigationMenu`
* 修复菜单导入时未添加权限规则
* 修复`navigationFolder`设置多个子菜单后会多循环数据
* 修复部分代码php5.4下不兼容
* 修复后台菜单不能添加编辑
[门户应用]
* 完全独立门户应用
* 完善后台页面管理
* 完善面包屑标签`breadcrumb`
* 完善文章分类管理
* 完善文章管理
* 修复文章分类`path`更新
* 优化文章列表标签`articles`
* 优化后台文章分类选择
* 增加前台文章点赞功能
* 增加前台文章搜索功能
* 增加文章列表分页总数获取
#### 5.0.170401
* 完善文件上传
* 增加回收站功能
* 完善友情链接
* 优化网站设置
* 增加后台登陆验证码
* 修复后台用户密码修改
* 修复用户管理-本站用户头像不显示
* 完善前台用户登录注册
* 增加后台菜单导入
* 修复后台菜单列表排序
* 完善导航
* 增加插件钩子管理
* 完善前台模板
... ...
theme: jekyll-theme-cayman
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 老猫 <zxxjjforever@163.com>
// +----------------------------------------------------------------------
namespace app\admin\annotation;
use mindplay\annotations\Annotation;
/**
* Specifies validation of a string, requiring a minimum and/or maximum length.
*
* @usage('method'=>true, 'inherited'=>true, 'multiple'=>false)
*/
class AdminMenuAnnotation extends Annotation
{
public $remark = '';
public $icon = '';
public $name = '';
public $param = '';
public $parent = '';
public $display = false;
public $order = 10000;
public $hasView = true;
/**
* Initialize the annotation.
* @param array $properties
*/
public function initAnnotation(array $properties)
{
parent::initAnnotation($properties);
}
}
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 老猫 <zxxjjforever@163.com>
// +----------------------------------------------------------------------
namespace app\admin\annotation;
use mindplay\annotations\AnnotationException;
use mindplay\annotations\Annotation;
/**
* Specifies validation of a string, requiring a minimum and/or maximum length.
*
* @usage('class'=>true, 'inherited'=>true, 'multiple'=>true)
*/
class AdminMenuRootAnnotation extends Annotation
{
/**
* @var int|null Minimum string length (or null, if no minimum)
*/
public $remark = '';
/**
* @var int|null Maximum string length (or null, if no maximum)
*/
public $icon = '';
/**
* @var int|null Minimum string length (or null, if no minimum)
*/
public $name = '';
public $action = '';
public $param = '';
public $parent = '';
public $display = false;
public $order = 10000;
/**
* Initialize the annotation.
* @param array $properties
*/
public function initAnnotation(array $properties)
{
parent::initAnnotation($properties);
}
}
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 老猫 <thinkcmf@126.com>
// +----------------------------------------------------------------------
namespace app\admin\api;
use app\admin\model\NavModel;
use think\db\Query;
class NavApi
{
/**
* 导航模板数据源 用于模板设计
* @param array $param
* @return array|\PDOStatement|string|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index($param = [])
{
$navModel = new NavModel();
$result = $navModel
->where(function (Query $query) use ($param) {
if (!empty($param['keyword'])) {
$query->where('name', 'like', "%{$param['keyword']}%");
}
})->select();
return $result;
}
}
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 老猫 <thinkcmf@126.com>
// +----------------------------------------------------------------------
namespace app\admin\api;
use app\admin\model\NavMenuModel;
class NavMenuApi
{
/**
* 导航菜单模板数据源 用于模板设计
* @param array $param
* @return array|\PDOStatement|string|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index($param = [])
{
$navMenuModel = new NavMenuModel();
$result = $navMenuModel
->where(function (Query $query) use ($param) {
if (!empty($param['keyword'])) {
$query->where('name', 'like', "%{$param['keyword']}%");
}
if (!empty($param['id'])) {
$query->where('nav_id', intval($param['id']));
}
})->select();
return $result;
}
}
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 老猫 <thinkcmf@126.com>
// +----------------------------------------------------------------------
namespace app\admin\api;
use app\admin\model\SlideModel;
use think\db\Query;
class SlideApi
{
/**
* 幻灯片模板数据源 用于模板设计
* @param array $param
* @return false|\PDOStatement|string|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index($param = [])
{
$slideModel = new SlideModel();
//返回的数据必须是数据集或数组,item里必须包括id,name,如果想表示层级关系请加上 parent_id
return $slideModel
->where(function (Query $query) use ($param) {
if (!empty($param['keyword'])) {
$query->where('name', 'like', "%{$param['keyword']}%");
}
})->select();
}
}
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 小夏 < 449134904@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use cmf\controller\AdminBaseController;
use app\admin\model\AboutUsModel;
use app\portal\model\PortalPostModel;
class AboutUsController extends AdminBaseController
{
protected $targets = ["_blank" => "新标签页打开", "_self" => "本窗口打开"];
//编辑页面
public function edit(){
$AboutUsModel = new AboutUsModel();
$about = $AboutUsModel->where('id',1)->find();
$contentModel = new PortalPostModel();
$about['content'] = $contentModel->getPostContentAttr($about['content']);
$this->assign('post', $about);
return $this->fetch();
}
//编辑保存页面
public function editPost(){
$data = $this->request->param();
$AboutUsModel = new AboutUsModel();
$result = $this->validate($data, 'AboutUs');
if ($result !== true) {
$this->error($result);
}
$contentModel = new PortalPostModel();
$data['content'] = $contentModel->setPostContentAttr($data['content']);
$AboutUsModel->allowField(true)->isUpdate(true)->save($data);
$this->success("保存成功!");
}
}
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 小夏 < 449134904@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use cmf\controller\AdminBaseController;
use app\admin\model\CooperationModel;
class CooperationController extends AdminBaseController
{
protected $targets = ["_blank" => "新标签页打开", "_self" => "本窗口打开"];
//首页
public function index(){
$CooperationModel = new CooperationModel();
$cooperation = $CooperationModel->order('weigh desc')->select();
$this->assign('cooperation', $cooperation);
return $this->fetch();
}
//添加页面
public function add(){
$this->assign('targets', $this->targets);
return $this->fetch();
}
//提交保存
public function addPost(){
$data = $this->request->param();
$CooperationModel = new CooperationModel();
$result = $this->validate($data, 'Cooperation');
if ($result !== true) {
$this->error($result);
}
$CooperationModel->allowField(true)->save($data);
$this->success("添加成功!", url("Cooperation/index"));
}
//编辑页面
public function edit(){
$id = $this->request->param('id', 0, 'intval');
$CooperationModel = new CooperationModel();
$cooperation = $CooperationModel->get($id);
$this->assign('targets', $this->targets);
$this->assign('cooperation', $cooperation);
return $this->fetch();
}
//编辑保存页面
public function editPost()
{
$data = $this->request->param();
$CooperationModel = new CooperationModel();
$result = $this->validate($data, 'Cooperation');
if ($result !== true) {
$this->error($result);
}
$CooperationModel->allowField(true)->isUpdate(true)->save($data);
$this->success("保存成功!", url("Cooperation/index"));
}
//删除
public function delete(){
$id = $this->request->param('id', 0, 'intval');
CooperationModel::destroy($id);
$this->success("删除成功!", url("Cooperation/index"));
}
//显示与隐藏
public function toggle()
{
$data = $this->request->param();
$CooperationModel = new CooperationModel();
if (isset($data['ids']) && !empty($data["display"])) {
$ids = $this->request->param('ids/a');
$CooperationModel->where('id', 'in', $ids)->update(['status' => 1]);
$this->success("更新成功!");
}
if (isset($data['ids']) && !empty($data["hide"])) {
$ids = $this->request->param('ids/a');
$CooperationModel->where('id', 'in', $ids)->update(['status' => 0]);
$this->success("更新成功!");
}
}
}
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 老猫 <zxxjjforever@163.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use cmf\controller\AdminBaseController;
class DialogController extends AdminBaseController
{
public function initialize()
{
}
public function map()
{
$location = $this->request->param('location');
$location = explode(',', $location);
$lng = empty($location[0]) ? 116.424966 : $location[0];
$lat = empty($location[1]) ? 39.907851 : $location[1];
$this->assign(['lng' => $lng, 'lat' => $lat]);
return $this->fetch();
}
}
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 小夏 < 449134904@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use cmf\controller\AdminBaseController;
use app\admin\model\FocusModel;
class FocusController extends AdminBaseController
{
protected $targets = ["_blank" => "新标签页打开", "_self" => "本窗口打开"];
//首页
public function index(){
$FocusModel = new FocusModel();
$Focus = $FocusModel->order('weigh desc')->select();
$this->assign('focus', $Focus);
return $this->fetch();
}
//添加页面
public function add(){
$this->assign('targets', $this->targets);
return $this->fetch();
}
//提交保存
public function addPost(){
$data = $this->request->param();
$FocusModel = new FocusModel();
$result = $this->validate($data, 'Focus');
if ($result !== true) {
$this->error($result);
}
$FocusModel->allowField(true)->save($data);
$this->success("添加成功!", url("Focus/index"));
}
//编辑页面
public function edit(){
$id = $this->request->param('id', 0, 'intval');
$FocusModel = new FocusModel();
$Focus = $FocusModel->get($id);
$this->assign('targets', $this->targets);
$this->assign('focus', $Focus);
return $this->fetch();
}
//编辑保存页面
public function editPost()
{
$data = $this->request->param();
$FocusModel = new FocusModel();
$result = $this->validate($data, 'Focus');
if ($result !== true) {
$this->error($result);
}
$FocusModel->allowField(true)->isUpdate(true)->save($data);
$this->success("保存成功!", url("Focus/index"));
}
//删除
public function delete(){
$id = $this->request->param('id', 0, 'intval');
FocusModel::destroy($id);
$this->success("删除成功!", url("Focus/index"));
}
//显示与隐藏
public function toggle()
{
$data = $this->request->param();
$FocusModel = new FocusModel();
if (isset($data['ids']) && !empty($data["display"])) {
$ids = $this->request->param('ids/a');
$FocusModel->where('id', 'in', $ids)->update(['status' => 1]);
$this->success("更新成功!");
}
if (isset($data['ids']) && !empty($data["hide"])) {
$ids = $this->request->param('ids/a');
$FocusModel->where('id', 'in', $ids)->update(['status' => 0]);
$this->success("更新成功!");
}
}
}
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 老猫 <zxxjjforever@163.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use cmf\controller\AdminBaseController;
use app\admin\model\HookModel;
use app\admin\model\PluginModel;
use app\admin\model\HookPluginModel;
use think\Db;
/**
* Class HookController 钩子管理控制器
* @package app\admin\controller
*/
class HookController extends AdminBaseController
{
/**
* 钩子管理
* @adminMenu(
* 'name' => '钩子管理',
* 'parent' => 'admin/Plugin/default',
* 'display'=> true,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '钩子管理',
* 'param' => ''
* )
*/
public function index()
{
$hookModel = new HookModel();
$hooks = $hookModel->select();
$this->assign('hooks', $hooks);
return $this->fetch();
}
/**
* 钩子插件管理
* @adminMenu(
* 'name' => '钩子插件管理',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '钩子插件管理',
* 'param' => ''
* )
*/
public function plugins()
{
$hook = $this->request->param('hook');
$pluginModel = new PluginModel();
$plugins = $pluginModel
->field('a.*,b.hook,b.plugin,b.list_order,b.status as hook_plugin_status,b.id as hook_plugin_id')
->alias('a')
->join('__HOOK_PLUGIN__ b', 'a.name = b.plugin')
->where('b.hook', $hook)
->order('b.list_order asc')
->select();
$this->assign('plugins', $plugins);
return $this->fetch();
}
/**
* 钩子插件排序
* @adminMenu(
* 'name' => '钩子插件排序',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '钩子插件排序',
* 'param' => ''
* )
*/
public function pluginListOrder()
{
$hookPluginModel = new HookPluginModel();
parent::listOrders($hookPluginModel);
$this->success("排序更新成功!");
}
/**
* 同步钩子
* @adminMenu(
* 'name' => '同步钩子',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '同步钩子',
* 'param' => ''
* )
*/
public function sync()
{
$apps = cmf_scan_dir(APP_PATH . '*', GLOB_ONLYDIR);
array_push($apps, 'cmf');
foreach ($apps as $app) {
if ($app == 'cmf') {
$hookConfigFile = cmf_core_path() . 'hooks.php';
} else {
$hookConfigFile = APP_PATH . $app . '/hooks.php';
}
if (file_exists($hookConfigFile)) {
$hooksInFile = include $hookConfigFile;
foreach ($hooksInFile as $hookName => $hook) {
$hook['type'] = empty($hook['type']) ? 2 : $hook['type'];
if (!in_array($hook['type'], [2, 3, 4]) && $app != 'cmf') {
$hook['type'] = 2;
}
$findHook = Db::name('hook')->where('hook', $hookName)->count();
$hook['app'] = $app;
if ($findHook > 0) {
Db::name('hook')->where('hook', $hookName)->strict(false)->field(true)->update($hook);
} else {
$hook['hook'] = $hookName;
Db::name('hook')->insert($hook);
}
}
}
}
return $this->fetch();
}
}
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 小夏 < 449134904@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use cmf\controller\AdminBaseController;
use think\Db;
use app\admin\model\AdminMenuModel;
class IndexController extends AdminBaseController
{
public function initialize()
{
$adminSettings = cmf_get_option('admin_settings');
if (empty($adminSettings['admin_password']) || $this->request->path() == $adminSettings['admin_password']) {
$adminId = cmf_get_current_admin_id();
if (empty($adminId)) {
session("__LOGIN_BY_CMF_ADMIN_PW__", 1);//设置后台登录加密码
}
}
parent::initialize();
}
/**
* 后台首页
*/
public function index()
{
$content = hook_one('admin_index_index_view');
if (!empty($content)) {
return $content;
}
$adminMenuModel = new AdminMenuModel();
$menus = cache('admin_menus_' . cmf_get_current_admin_id(), '', null, 'admin_menus');
if (empty($menus)) {
$menus = $adminMenuModel->menuTree();
cache('admin_menus_' . cmf_get_current_admin_id(), $menus, null, 'admin_menus');
}
$this->assign("menus", $menus);
$result = Db::name('AdminMenu')->order(["app" => "ASC", "controller" => "ASC", "action" => "ASC"])->select();
$menusTmp = array();
foreach ($result as $item){
//去掉/ _ 全部小写。作为索引。
$indexTmp = $item['app'].$item['controller'].$item['action'];
$indexTmp = preg_replace("/[\\/|_]/","",$indexTmp);
$indexTmp = strtolower($indexTmp);
$menusTmp[$indexTmp] = $item;
}
$this->assign("menus_js_var",json_encode($menusTmp));
//$admin = Db::name("user")->where('id', cmf_get_current_admin_id())->find();
//$this->assign('admin', $admin);
return $this->fetch();
}
}
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 小夏 < 449134904@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use cmf\controller\AdminBaseController;
use app\admin\model\LinkModel;
class LinkController extends AdminBaseController
{
protected $targets = ["_blank" => "新标签页打开", "_self" => "本窗口打开"];
/**
* 友情链接管理
* @adminMenu(
* 'name' => '友情链接',
* 'parent' => 'admin/Setting/default',
* 'display'=> true,
* 'hasView'=> true,
* 'order' => 50,
* 'icon' => '',
* 'remark' => '友情链接管理',
* 'param' => ''
* )
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index()
{
$content = hook_one('admin_link_index_view');
if (!empty($content)) {
return $content;
}
$linkModel = new LinkModel();
$links = $linkModel->select();
$this->assign('links', $links);
return $this->fetch();
}
/**
* 添加友情链接
* @adminMenu(
* 'name' => '添加友情链接',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '添加友情链接',
* 'param' => ''
* )
*/
public function add()
{
$this->assign('targets', $this->targets);
return $this->fetch();
}
/**
* 添加友情链接提交保存
* @adminMenu(
* 'name' => '添加友情链接提交保存',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '添加友情链接提交保存',
* 'param' => ''
* )
*/
public function addPost()
{
$data = $this->request->param();
$linkModel = new LinkModel();
$result = $this->validate($data, 'Link');
if ($result !== true) {
$this->error($result);
}
$linkModel->allowField(true)->save($data);
$this->success("添加成功!", url("Link/index"));
}
/**
* 编辑友情链接
* @adminMenu(
* 'name' => '编辑友情链接',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '编辑友情链接',
* 'param' => ''
* )
* @return mixed
* @throws \think\Exception\DbException
*/
public function edit()
{
$id = $this->request->param('id', 0, 'intval');
$linkModel = new LinkModel();
$link = $linkModel->get($id);
$this->assign('targets', $this->targets);
$this->assign('link', $link);
return $this->fetch();
}
/**
* 编辑友情链接提交保存
* @adminMenu(
* 'name' => '编辑友情链接提交保存',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '编辑友情链接提交保存',
* 'param' => ''
* )
*/
public function editPost()
{
$data = $this->request->param();
$linkModel = new LinkModel();
$result = $this->validate($data, 'Link');
if ($result !== true) {
$this->error($result);
}
$linkModel->allowField(true)->isUpdate(true)->save($data);
$this->success("保存成功!", url("Link/index"));
}
/**
* 删除友情链接
* @adminMenu(
* 'name' => '删除友情链接',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '删除友情链接',
* 'param' => ''
* )
*/
public function delete()
{
$id = $this->request->param('id', 0, 'intval');
LinkModel::destroy($id);
$this->success("删除成功!", url("link/index"));
}
/**
* 友情链接排序
* @adminMenu(
* 'name' => '友情链接排序',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '友情链接排序',
* 'param' => ''
* )
*/
public function listOrder()
{
$linkModel = new LinkModel();
parent::listOrders($linkModel);
$this->success("排序更新成功!");
}
/**
* 友情链接显示隐藏
* @adminMenu(
* 'name' => '友情链接显示隐藏',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '友情链接显示隐藏',
* 'param' => ''
* )
*/
public function toggle()
{
$data = $this->request->param();
$linkModel = new LinkModel();
if (isset($data['ids']) && !empty($data["display"])) {
$ids = $this->request->param('ids/a');
$linkModel->where('id', 'in', $ids)->update(['status' => 1]);
$this->success("更新成功!");
}
if (isset($data['ids']) && !empty($data["hide"])) {
$ids = $this->request->param('ids/a');
$linkModel->where('id', 'in', $ids)->update(['status' => 0]);
$this->success("更新成功!");
}
}
}
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 小夏 < 449134904@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use cmf\controller\AdminBaseController;
use think\Validate;
class MailerController extends AdminBaseController
{
/**
* 邮箱配置
* @adminMenu(
* 'name' => '邮箱配置',
* 'parent' => 'admin/Setting/default',
* 'display'=> true,
* 'hasView'=> true,
* 'order' => 10,
* 'icon' => '',
* 'remark' => '邮箱配置',
* 'param' => ''
* )
*/
public function index()
{
$emailSetting = cmf_get_option('smtp_setting');
$this->assign($emailSetting);
return $this->fetch();
}
/**
* 邮箱配置
* @adminMenu(
* 'name' => '邮箱配置提交保存',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '邮箱配置提交保存',
* 'param' => ''
* )
*/
public function indexPost()
{
$post = array_map('trim', $this->request->param());
if (in_array('', $post) && !empty($post['smtpsecure'])) {
$this->error("不能留空!");
}
cmf_set_option('smtp_setting', $post);
$this->success("保存成功!");
}
/**
* 邮件模板
* @adminMenu(
* 'name' => '邮件模板',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '邮件模板',
* 'param' => ''
* )
*/
public function template()
{
$allowedTemplateKeys = ['verification_code'];
$templateKey = $this->request->param('template_key');
if (empty($templateKey) || !in_array($templateKey, $allowedTemplateKeys)) {
$this->error('非法请求!');
}
$template = cmf_get_option('email_template_' . $templateKey);
$this->assign($template);
return $this->fetch('template_verification_code');
}
/**
* 邮件模板提交
* @adminMenu(
* 'name' => '邮件模板提交',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '邮件模板提交',
* 'param' => ''
* )
*/
public function templatePost()
{
$allowedTemplateKeys = ['verification_code'];
$templateKey = $this->request->param('template_key');
if (empty($templateKey) || !in_array($templateKey, $allowedTemplateKeys)) {
$this->error('非法请求!');
}
$data = $this->request->param();
unset($data['template_key']);
cmf_set_option('email_template_' . $templateKey, $data);
$this->success("保存成功!");
}
/**
* 邮件发送测试
* @adminMenu(
* 'name' => '邮件发送测试',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '邮件发送测试',
* 'param' => ''
* )
*/
public function test()
{
if ($this->request->isPost()) {
$validate = new Validate([
'to' => 'require|email',
'subject' => 'require',
'content' => 'require',
]);
$validate->message([
'to.require' => '收件箱不能为空!',
'to.email' => '收件箱格式不正确!',
'subject.require' => '标题不能为空!',
'content.require' => '内容不能为空!',
]);
$data = $this->request->param();
if (!$validate->check($data)) {
$this->error($validate->getError());
}
$result = cmf_send_email($data['to'], $data['subject'], $data['content']);
if ($result && empty($result['error'])) {
$this->success('发送成功!');
} else {
$this->error('发送失败:' . $result['message']);
}
} else {
return $this->fetch();
}
}
}
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 小夏 < 449134904@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use cmf\controller\AdminBaseController;
use think\Db;
use app\admin\model\Menu;
class MainController extends AdminBaseController
{
/**
* 后台欢迎页
*/
public function index()
{
$dashboardWidgets = [];
$widgets = cmf_get_option('admin_dashboard_widgets');
$defaultDashboardWidgets = [
'_SystemCmfHub' => ['name' => 'CmfHub', 'is_system' => 1],
'_SystemCmfDocuments' => ['name' => 'CmfDocuments', 'is_system' => 1],
'_SystemMainContributors' => ['name' => 'MainContributors', 'is_system' => 1],
'_SystemContributors' => ['name' => 'Contributors', 'is_system' => 1],
'_SystemCustom1' => ['name' => 'Custom1', 'is_system' => 1],
'_SystemCustom2' => ['name' => 'Custom2', 'is_system' => 1],
'_SystemCustom3' => ['name' => 'Custom3', 'is_system' => 1],
'_SystemCustom4' => ['name' => 'Custom4', 'is_system' => 1],
'_SystemCustom5' => ['name' => 'Custom5', 'is_system' => 1],
];
if (empty($widgets)) {
$dashboardWidgets = $defaultDashboardWidgets;
} else {
foreach ($widgets as $widget) {
if ($widget['is_system']) {
$dashboardWidgets['_System' . $widget['name']] = ['name' => $widget['name'], 'is_system' => 1];
} else {
$dashboardWidgets[$widget['name']] = ['name' => $widget['name'], 'is_system' => 0];
}
}
foreach ($defaultDashboardWidgets as $widgetName => $widget) {
$dashboardWidgets[$widgetName] = $widget;
}
}
$dashboardWidgetPlugins = [];
$hookResults = hook('admin_dashboard');
if (!empty($hookResults)) {
foreach ($hookResults as $hookResult) {
if (isset($hookResult['width']) && isset($hookResult['view']) && isset($hookResult['plugin'])) { //验证插件返回合法性
$dashboardWidgetPlugins[$hookResult['plugin']] = $hookResult;
if (!isset($dashboardWidgets[$hookResult['plugin']])) {
$dashboardWidgets[$hookResult['plugin']] = ['name' => $hookResult['plugin'], 'is_system' => 0];
}
}
}
}
$smtpSetting = cmf_get_option('smtp_setting');
$this->assign('dashboard_widgets', $dashboardWidgets);
$this->assign('dashboard_widget_plugins', $dashboardWidgetPlugins);
$this->assign('has_smtp_setting', empty($smtpSetting) ? false : true);
return $this->fetch();
}
public function dashboardWidget()
{
$dashboardWidgets = [];
$widgets = $this->request->param('widgets/a');
if (!empty($widgets)) {
foreach ($widgets as $widget) {
if ($widget['is_system']) {
array_push($dashboardWidgets, ['name' => $widget['name'], 'is_system' => 1]);
} else {
array_push($dashboardWidgets, ['name' => $widget['name'], 'is_system' => 0]);
}
}
}
cmf_set_option('admin_dashboard_widgets', $dashboardWidgets, true);
$this->success('更新成功!');
}
}
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 小夏 < 449134904@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use app\admin\model\AdminMenuModel;
use cmf\controller\AdminBaseController;
use think\Db;
use think\facade\Cache;
use tree\Tree;
use mindplay\annotations\Annotations;
class MenuController extends AdminBaseController
{
/**
* 后台菜单管理
* @adminMenu(
* 'name' => '后台菜单',
* 'parent' => 'admin/Setting/default',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '后台菜单管理',
* 'param' => ''
* )
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index()
{
$content = hook_one('admin_menu_index_view');
if (!empty($content)) {
return $content;
}
session('admin_menu_index', 'Menu/index');
$result = Db::name('AdminMenu')->order(["list_order" => "ASC"])->select()->toArray();
$tree = new Tree();
$tree->icon = ['&nbsp;&nbsp;&nbsp;│ ', '&nbsp;&nbsp;&nbsp;├─', '&nbsp;&nbsp;&nbsp;└─ '];
$tree->nbsp = '&nbsp;&nbsp;&nbsp;';
$newMenus = [];
foreach ($result as $m) {
$newMenus[$m['id']] = $m;
}
foreach ($result as $key => $value) {
$result[$key]['parent_id_node'] = ($value['parent_id']) ? ' class="child-of-node-' . $value['parent_id'] . '"' : '';
$result[$key]['style'] = empty($value['parent_id']) ? '' : 'display:none;';
$result[$key]['str_manage'] = '<a class="btn btn-xs btn-primary" href="' . url("Menu/add", ["parent_id" => $value['id'], "menu_id" => $this->request->param("menu_id")]) . '">' . lang('ADD_SUB_MENU') . '</a>
<a class="btn btn-xs btn-primary" href="' . url("Menu/edit", ["id" => $value['id'], "menu_id" => $this->request->param("menu_id")]) . '">' . lang('EDIT') . '</a>
<a class="btn btn-xs btn-danger js-ajax-delete" href="' . url("Menu/delete", ["id" => $value['id'], "menu_id" => $this->request->param("menu_id")]) . '">' . lang('DELETE') . '</a> ';
$result[$key]['status'] = $value['status'] ? '<span class="label label-success">' . lang('DISPLAY') . '</span>' : '<span class="label label-warning">' . lang('HIDDEN') . '</span>';
if (APP_DEBUG) {
$result[$key]['app'] = $value['app'] . "/" . $value['controller'] . "/" . $value['action'];
}
}
$tree->init($result);
$str = "<tr id='node-\$id' \$parent_id_node style='\$style'>
<td style='padding-left:20px;'><input name='list_orders[\$id]' type='text' size='3' value='\$list_order' class='input input-order'></td>
<td>\$id</td>
<td>\$spacer\$name</td>
<td>\$app</td>
<td>\$status</td>
<td>\$str_manage</td>
</tr>";
$category = $tree->getTree(0, $str);
$this->assign("category", $category);
return $this->fetch();
}
/**
* 后台所有菜单列表
* @adminMenu(
* 'name' => '所有菜单',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '后台所有菜单列表',
* 'param' => ''
* )
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function lists()
{
session('admin_menu_index', 'Menu/lists');
$result = Db::name('AdminMenu')->order(["app" => "ASC", "controller" => "ASC", "action" => "ASC"])->select();
$this->assign("menus", $result);
return $this->fetch();
}
/**
* 后台菜单添加
* @adminMenu(
* 'name' => '后台菜单添加',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '后台菜单添加',
* 'param' => ''
* )
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function add()
{
$tree = new Tree();
$parentId = $this->request->param("parent_id", 0, 'intval');
$result = Db::name('AdminMenu')->order(["list_order" => "ASC"])->select();
$array = [];
foreach ($result as $r) {
$r['selected'] = $r['id'] == $parentId ? 'selected' : '';
$array[] = $r;
}
$str = "<option value='\$id' \$selected>\$spacer \$name</option>";
$tree->init($array);
$selectCategory = $tree->getTree(0, $str);
$this->assign("select_category", $selectCategory);
return $this->fetch();
}
/**
* 后台菜单添加提交保存
* @adminMenu(
* 'name' => '后台菜单添加提交保存',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '后台菜单添加提交保存',
* 'param' => ''
* )
*/
public function addPost()
{
if ($this->request->isPost()) {
$result = $this->validate($this->request->param(), 'AdminMenu');
if ($result !== true) {
$this->error($result);
} else {
$data = $this->request->param();
Db::name('AdminMenu')->strict(false)->field(true)->insert($data);
$app = $this->request->param("app");
$controller = $this->request->param("controller");
$action = $this->request->param("action");
$param = $this->request->param("param");
$authRuleName = "$app/$controller/$action";
$menuName = $this->request->param("name");
$findAuthRuleCount = Db::name('auth_rule')->where([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url'
])->count();
if (empty($findAuthRuleCount)) {
Db::name('AuthRule')->insert([
"name" => $authRuleName,
"app" => $app,
"type" => "admin_url", //type 1-admin rule;2-user rule
"title" => $menuName,
'param' => $param,
]);
}
$sessionAdminMenuIndex = session('admin_menu_index');
$to = empty($sessionAdminMenuIndex) ? "Menu/index" : $sessionAdminMenuIndex;
$this->_exportAppMenuDefaultLang();
Cache::clear('admin_menus');// 删除后台菜单缓存
$this->success("添加成功!", url($to));
}
}
}
/**
* 后台菜单编辑
* @adminMenu(
* 'name' => '后台菜单编辑',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '后台菜单编辑',
* 'param' => ''
* )
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function edit()
{
$tree = new Tree();
$id = $this->request->param("id", 0, 'intval');
$rs = Db::name('AdminMenu')->where("id", $id)->find();
$result = Db::name('AdminMenu')->order(["list_order" => "ASC"])->select();
$array = [];
foreach ($result as $r) {
$r['selected'] = $r['id'] == $rs['parent_id'] ? 'selected' : '';
$array[] = $r;
}
$str = "<option value='\$id' \$selected>\$spacer \$name</option>";
$tree->init($array);
$selectCategory = $tree->getTree(0, $str);
$this->assign("data", $rs);
$this->assign("select_category", $selectCategory);
return $this->fetch();
}
/**
* 后台菜单编辑提交保存
* @adminMenu(
* 'name' => '后台菜单编辑提交保存',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '后台菜单编辑提交保存',
* 'param' => ''
* )
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
public function editPost()
{
if ($this->request->isPost()) {
$id = $this->request->param('id', 0, 'intval');
$oldMenu = Db::name('AdminMenu')->where('id', $id)->find();
$result = $this->validate($this->request->param(), 'AdminMenu.edit');
if ($result !== true) {
$this->error($result);
} else {
Db::name('AdminMenu')->strict(false)->field(true)->update($this->request->param());
$app = $this->request->param("app");
$controller = $this->request->param("controller");
$action = $this->request->param("action");
$param = $this->request->param("param");
$authRuleName = "$app/$controller/$action";
$menuName = $this->request->param("name");
$findAuthRuleCount = Db::name('auth_rule')->where([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url'
])->count();
if (empty($findAuthRuleCount)) {
$oldApp = $oldMenu['app'];
$oldController = $oldMenu['controller'];
$oldAction = $oldMenu['action'];
$oldName = "$oldApp/$oldController/$oldAction";
$findOldRuleId = Db::name('AuthRule')->where("name", $oldName)->value('id');
if (empty($findOldRuleId)) {
Db::name('AuthRule')->insert([
"name" => $authRuleName,
"app" => $app,
"type" => "admin_url",
"title" => $menuName,
"param" => $param
]);//type 1-admin rule;2-user rule
} else {
Db::name('AuthRule')->where('id', $findOldRuleId)->update([
"name" => $authRuleName,
"app" => $app,
"type" => "admin_url",
"title" => $menuName,
"param" => $param]);//type 1-admin rule;2-user rule
}
} else {
Db::name('AuthRule')->where([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url'
])->update(["title" => $menuName, 'param' => $param]);//type 1-admin rule;2-user rule
}
$this->_exportAppMenuDefaultLang();
Cache::clear('admin_menus');// 删除后台菜单缓存
$this->success("保存成功!");
}
}
}
/**
* 后台菜单删除
* @adminMenu(
* 'name' => '后台菜单删除',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '后台菜单删除',
* 'param' => ''
* )
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function delete()
{
$id = $this->request->param("id", 0, 'intval');
$count = Db::name('AdminMenu')->where("parent_id", $id)->count();
if ($count > 0) {
$this->error("该菜单下还有子菜单,无法删除!");
}
if (Db::name('AdminMenu')->delete($id) !== false) {
$this->success("删除菜单成功!");
} else {
$this->error("删除失败!");
}
}
/**
* 后台菜单排序
* @adminMenu(
* 'name' => '后台菜单排序',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '后台菜单排序',
* 'param' => ''
* )
*/
public function listOrder()
{
$adminMenuModel = new AdminMenuModel();
parent::listOrders($adminMenuModel);
$this->success("排序更新成功!");
}
/**
* 导入新后台菜单
* @adminMenu(
* 'name' => '导入新后台菜单',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '导入新后台菜单',
* 'param' => ''
* )
* @return mixed
* @throws \ReflectionException
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
public function getActions()
{
Annotations::$config['cache'] = false;
$annotationManager = Annotations::getManager();
$annotationManager->registry['adminMenu'] = 'app\admin\annotation\AdminMenuAnnotation';
$annotationManager->registry['adminMenuRoot'] = 'app\admin\annotation\AdminMenuRootAnnotation';
$newMenus = [];
$apps = cmf_scan_dir(APP_PATH . '*', GLOB_ONLYDIR);
$app = $this->request->param('app', '');
if (empty($app)) {
$app = $apps[0];
}
if (!in_array($app, $apps)) {
$this->error('应用' . $app . '不存在!');
}
if ($app == 'admin') {
$filePatten = APP_PATH . $app . '/controller/*Controller.php';
} else {
$filePatten = APP_PATH . $app . '/controller/Admin*Controller.php';
}
$controllers = cmf_scan_dir($filePatten);
if (!empty($controllers)) {
foreach ($controllers as $controller) {
$controller = preg_replace('/\.php$/', '', $controller);
$controllerName = preg_replace('/\Controller$/', '', $controller);
$controllerClass = "app\\$app\\controller\\$controller";
$menuAnnotations = Annotations::ofClass($controllerClass, '@adminMenuRoot');
if (!empty($menuAnnotations)) {
foreach ($menuAnnotations as $menuAnnotation) {
$name = $menuAnnotation->name;
$icon = $menuAnnotation->icon;
$type = 0;//1:有界面可访问菜单,2:无界面可访问菜单,0:只作为菜单
$action = $menuAnnotation->action;
$status = empty($menuAnnotation->display) ? 0 : 1;
$listOrder = floatval($menuAnnotation->order);
$param = $menuAnnotation->param;
$remark = $menuAnnotation->remark;
if (empty($menuAnnotation->parent)) {
$parentId = 0;
} else {
$parent = explode('/', $menuAnnotation->parent);
$countParent = count($parent);
if ($countParent > 3) {
throw new \Exception($controllerClass . ':' . $action . ' @adminMenuRoot parent格式不正确!');
}
$parentApp = $app;
$parentController = $controllerName;
$parentAction = '';
switch ($countParent) {
case 1:
$parentAction = $parent[0];
break;
case 2:
$parentController = $parent[0];
$parentAction = $parent[1];
break;
case 3:
$parentApp = $parent[0];
$parentController = $parent[1];
$parentAction = $parent[2];
break;
}
$findParentAdminMenu = Db::name('admin_menu')->where([
'app' => $parentApp,
'controller' => $parentController,
'action' => $parentAction
])->find();
if (empty($findParentAdminMenu)) {
$parentId = Db::name('admin_menu')->insertGetId([
'app' => $parentApp,
'controller' => $parentController,
'action' => $parentAction,
'name' => '--new--'
]);
} else {
$parentId = $findParentAdminMenu['id'];
}
}
$findAdminMenu = Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->find();
if (empty($findAdminMenu)) {
Db::name('admin_menu')->insert([
'parent_id' => $parentId,
'type' => $type,
'status' => $status,
'list_order' => $listOrder,
'app' => $app,
'controller' => $controllerName,
'action' => $action,
'param' => $param,
'name' => $name,
'icon' => $icon,
'remark' => $remark
]);
$menuName = $name;
array_push($newMenus, "$app/$controllerName/$action 已导入");
} else {
if ($findAdminMenu['name'] == '--new--') {
Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->update([
'parent_id' => $parentId,
'type' => $type,
'status' => $status,
'list_order' => $listOrder,
'param' => $param,
'name' => $name,
'icon' => $icon,
'remark' => $remark
]);
$menuName = $name;
} else {
// 只关注菜单层级关系,是否有视图
Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->update([
//'parent_id' => $parentId,
'type' => $type,
]);
$menuName = $findAdminMenu['name'];
}
array_push($newMenus, "$app/$controllerName/$action 层级关系已更新");
}
$authRuleName = "{$app}/{$controllerName}/{$action}";
$findAuthRuleCount = Db::name('auth_rule')->where([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url'
])->count();
if ($findAuthRuleCount == 0) {
Db::name('auth_rule')->insert([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url',
'param' => $param,
'title' => $menuName
]);
} else {
Db::name('auth_rule')->where([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url',
])->update([
'param' => $param,
'title' => $menuName
]);
}
}
}
$reflect = new \ReflectionClass($controllerClass);
$methods = $reflect->getMethods(\ReflectionMethod::IS_PUBLIC);
if (!empty($methods)) {
foreach ($methods as $method) {
if ($method->class == $controllerClass && strpos($method->name, '_') !== 0) {
$menuAnnotations = Annotations::ofMethod($controllerClass, $method->name, '@adminMenu');
if (!empty($menuAnnotations)) {
$menuAnnotation = $menuAnnotations[0];
$name = $menuAnnotation->name;
$icon = $menuAnnotation->icon;
$type = $menuAnnotation->hasView ? 1 : 2;//1:有界面可访问菜单,2:无界面可访问菜单,0:只作为菜单
$action = $method->name;
$status = empty($menuAnnotation->display) ? 0 : 1;
$listOrder = floatval($menuAnnotation->order);
$param = $menuAnnotation->param;
$remark = $menuAnnotation->remark;
if (empty($menuAnnotation->parent)) {
$parentId = 0;
} else {
$parent = explode('/', $menuAnnotation->parent);
$countParent = count($parent);
if ($countParent > 3) {
throw new \Exception($controllerClass . ':' . $action . ' @menuRoot parent格式不正确!');
}
$parentApp = $app;
$parentController = $controllerName;
$parentAction = '';
switch ($countParent) {
case 1:
$parentAction = $parent[0];
break;
case 2:
$parentController = $parent[0];
$parentAction = $parent[1];
break;
case 3:
$parentApp = $parent[0];
$parentController = $parent[1];
$parentAction = $parent[2];
break;
}
$findParentAdminMenu = Db::name('admin_menu')->where([
'app' => $parentApp,
'controller' => $parentController,
'action' => $parentAction
])->find();
if (empty($findParentAdminMenu)) {
$parentId = Db::name('admin_menu')->insertGetId([
'app' => $parentApp,
'controller' => $parentController,
'action' => $parentAction,
'name' => '--new--'
]);
} else {
$parentId = $findParentAdminMenu['id'];
}
}
$findAdminMenu = Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->find();
if (empty($findAdminMenu)) {
Db::name('admin_menu')->insert([
'parent_id' => $parentId,
'type' => $type,
'status' => $status,
'list_order' => $listOrder,
'app' => $app,
'controller' => $controllerName,
'action' => $action,
'param' => $param,
'name' => $name,
'icon' => $icon,
'remark' => $remark
]);
$menuName = $name;
array_push($newMenus, "$app/$controllerName/$action 已导入");
} else {
if ($findAdminMenu['name'] == '--new--') {
Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->update([
'parent_id' => $parentId,
'type' => $type,
'status' => $status,
'list_order' => $listOrder,
'param' => $param,
'name' => $name,
'icon' => $icon,
'remark' => $remark
]);
$menuName = $name;
} else {
// 只关注菜单层级关系,是否有视图
Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->update([
//'parent_id' => $parentId,
'type' => $type,
]);
$menuName = $findAdminMenu['name'];
}
array_push($newMenus, "$app/$controllerName/$action 已更新");
}
$authRuleName = "{$app}/{$controllerName}/{$action}";
$findAuthRuleCount = Db::name('auth_rule')->where([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url'
])->count();
if ($findAuthRuleCount == 0) {
Db::name('auth_rule')->insert([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url',
'param' => $param,
'title' => $menuName
]);
} else {
Db::name('auth_rule')->where([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url',
])->update([
'param' => $param,
'title' => $menuName
]);
}
}
}
}
}
}
}
$index = array_search($app, $apps);
$nextIndex = $index + 1;
$nextIndex = $nextIndex >= count($apps) ? 0 : $nextIndex;
if ($nextIndex) {
$this->assign("next_app", $apps[$nextIndex]);
}
$this->assign("app", $app);
$this->assign("new_menus", $newMenus);
Cache::clear('admin_menus');// 删除后台菜单缓存
return $this->fetch();
}
/**
* 导出后台菜单语言包
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function _exportAppMenuDefaultLang()
{
$menus = Db::name('AdminMenu')->order(["app" => "ASC", "controller" => "ASC", "action" => "ASC"])->select();
$langDir = config('DEFAULT_LANG');
$adminMenuLang = CMF_ROOT . "data/lang/" . $langDir . "/admin_menu.php";
if (!empty($adminMenuLang) && !file_exists_case($adminMenuLang)) {
mkdir(dirname($adminMenuLang), 0777, true);
}
$lang = [];
foreach ($menus as $menu) {
$lang_key = strtoupper($menu['app'] . '_' . $menu['controller'] . '_' . $menu['action']);
$lang[$lang_key] = $menu['name'];
}
$langStr = var_export($lang, true);
$langStr = preg_replace("/\s+\d+\s=>\s(\n|\r)/", "\n", $langStr);
if (!empty($adminMenuLang)) {
file_put_contents($adminMenuLang, "<?php\nreturn $langStr;");
}
}
}
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: kane <chengjin005@163.com> 小夏 < 449134904@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use cmf\controller\AdminBaseController;
use app\admin\model\NavModel;
use think\Db;
/**
* Class NavController 导航类别管理控制器
* @package app\admin\controller
*/
class NavController extends AdminBaseController
{
/**
* 导航管理
* @adminMenu(
* 'name' => '导航管理',
* 'parent' => 'admin/Setting/default',
* 'display'=> true,
* 'hasView'=> true,
* 'order' => 30,
* 'icon' => '',
* 'remark' => '导航管理',
* 'param' => ''
* )
*/
public function index()
{
$content = hook_one('admin_nav_index_view');
if (!empty($content)) {
return $content;
}
$navModel = new NavModel();
$navs = $navModel->select();
$this->assign('navs', $navs);
return $this->fetch();
}
/**
* 添加导航
* @adminMenu(
* 'name' => '添加导航',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '添加导航',
* 'param' => ''
* )
*/
public function add()
{
return $this->fetch();
}
/**
* 添加导航提交保存
* @adminMenu(
* 'name' => '添加导航提交保存',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '添加导航提交保存',
* 'param' => ''
* )
*/
public function addPost()
{
$navModel = new NavModel();
$arrData = $this->request->post();
if (empty($arrData["is_main"])) {
$arrData["is_main"] = 0;
} else {
$navModel->where("is_main", 1)->update(["is_main" => 0]);
}
$navModel->allowField(true)->insert($arrData);
$this->success(lang("EDIT_SUCCESS"), url("nav/index"));
}
/**
* 编辑导航
* @adminMenu(
* 'name' => '编辑导航',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '编辑导航',
* 'param' => ''
* )
*/
public function edit()
{
$navModel = new NavModel();
$intId = $this->request->param("id", 0, 'intval');
$objNavCat = $navModel->where("id", $intId)->find();
$arrNavCat = $objNavCat ? $objNavCat->toArray() : [];
$this->assign($arrNavCat);
return $this->fetch();
}
/**
* 编辑导航提交保存
* @adminMenu(
* 'name' => '编辑导航提交保存',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '编辑导航提交保存',
* 'param' => ''
* )
*/
public function editPost()
{
$navModel = new NavModel();
$arrData = $this->request->post();
if (empty($arrData["is_main"])) {
$arrData["is_main"] = 0;
} else {
$navModel->where("is_main", 1)->update(["is_main" => 0]);
}
$navModel->allowField(true)->where("id", intval($arrData["id"]))->update($arrData);
$this->success(lang("EDIT_SUCCESS"), url("nav/index"));
}
/**
* 删除导航
* @adminMenu(
* 'name' => '删除导航',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '删除导航',
* 'param' => ''
* )
*/
public function delete()
{
$navModel = new NavModel();
$intId = $this->request->param("id", 0, "intval");
if (empty($intId)) {
$this->error(lang("NO_ID"));
}
$navModel->where("id", $intId)->delete();
$this->success(lang("DELETE_SUCCESS"), url("nav/index"));
}
}
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: kane <chengjin005@163.com> 小夏 < 449134904@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use app\admin\model\NavMenuModel;
use cmf\controller\AdminBaseController;
use tree\Tree;
/**
* Class NavMenuController 前台菜单管理控制器
* @package app\admin\controller
*/
class NavMenuController extends AdminBaseController
{
/**
* 导航菜单
* @adminMenu(
* 'name' => '导航菜单',
* 'parent' => 'admin/Nav/index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '导航菜单',
* 'param' => ''
* )
*/
public function index()
{
$intNavId = $this->request->param("nav_id", 0, 'intval');
$navMenuModel = new NavMenuModel();
if (empty($intNavId)) {
$this->error("请指定导航!");
}
$objResult = $navMenuModel->where("nav_id", $intNavId)->order(["list_order" => "ASC"])->select();
$arrResult = $objResult ? $objResult->toArray() : [];
$tree = new Tree();
$tree->icon = ['&nbsp;&nbsp;&nbsp;│ ', '&nbsp;&nbsp;&nbsp;├─ ', '&nbsp;&nbsp;&nbsp;└─ '];
$tree->nbsp = '&nbsp;&nbsp;&nbsp;';
$array = [];
foreach ($arrResult as $r) {
$r['str_manage'] = '<a class="btn btn-xs btn-primary" href="' . url("NavMenu/add", ["parent_id" => $r['id'], "nav_id" => $r['nav_id']]) . '">添加子菜单</a>
<a class="btn btn-xs btn-primary" href="' . url("NavMenu/edit", ["id" => $r['id'], "parent_id" => $r['parent_id'], "nav_id" => $r['nav_id']]) . '">编辑</a>
<a class="btn btn-xs btn-danger js-ajax-delete" href="' . url("NavMenu/delete", ["id" => $r['id'], 'nav_id' => $r['nav_id']]) . '">删除</a> ';
$r['status'] = $r['status'] ? "显示" : "隐藏";
$array[] = $r;
}
$tree->init($array);
$str = "<tr>
<td><input name='list_orders[\$id]' type='text' size='3' value='\$list_order' class='input input-order'></td>
<td>\$id</td>
<td >\$spacer\$name</td>
<td>\$status</td>
<td>\$str_manage</td>
</tr>";
$categories = $tree->getTree(0, $str);
$this->assign("categories", $categories);
$this->assign('nav_id', $intNavId);
return $this->fetch();
}
/**
* 添加导航菜单
* @adminMenu(
* 'name' => '添加导航菜单',
* 'parent' => 'index',
* 'display'=> false,
* 'order' => 10000,
* 'hasView'=> true,
* 'icon' => '',
* 'remark' => '添加导航菜单',
* 'param' => ''
* )
*/
public function add()
{
$navMenuModel = new NavMenuModel();
$intNavId = $this->request->param("nav_id", 0, 'intval');
$intParentId = $this->request->param("parent_id", 0, 'intval');
$objResult = $navMenuModel->where("nav_id", $intNavId)->order(["list_order" => "ASC"])->select();
$arrResult = $objResult ? $objResult->toArray() : [];
$tree = new Tree();
$tree->icon = ['&nbsp;│ ', '&nbsp;├─ ', '&nbsp;└─ '];
$tree->nbsp = '&nbsp;';
$array = [];
foreach ($arrResult as $r) {
$r['str_manage'] = '<a href="' . url("NavMenu/add", ["parent_id" => $r['id']]) . '">添加子菜单</a> | <a href="'
. url("NavMenu/edit", ["id" => $r['id']]) . '">编辑</a> | <a class="J_ajax_del" href="'
. url("NavMenu/delete", ["id" => $r['id']]) . '">删除</a> ';
$r['status'] = $r['status'] ? "显示" : "隐藏";
$r['selected'] = $r['id'] == $intParentId ? "selected" : "";
$array[] = $r;
}
$tree->init($array);
$str = "<option value='\$id' \$selected>\$spacer\$name</option>";
$navTrees = $tree->getTree(0, $str);
$this->assign("nav_trees", $navTrees);
$navs = $navMenuModel->selectNavs();
$this->assign('navs', $navs);
$this->assign("nav_id", $intNavId);
return $this->fetch();
}
/**
* 添加导航菜单提交保存
* @adminMenu(
* 'name' => '添加导航菜单提交保存',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '添加导航菜单提交保存',
* 'param' => ''
* )
*/
public function addPost()
{
$navMenuModel = new NavMenuModel();
$arrData = $this->request->post();
if (isset($arrData['external_href'])) {
$arrData['href'] = htmlspecialchars_decode($arrData['external_href']);
} else {
$arrData['href'] = htmlspecialchars_decode($arrData['href']);
$arrData['href'] = base64_decode($arrData['href']);
}
$navMenuModel->allowField(true)->isUpdate(false)->save($arrData);
$this->success(lang("EDIT_SUCCESS"), url("NavMenu/index", ['nav_id' => $arrData['nav_id']]));
}
/**
* 编辑导航菜单
* @adminMenu(
* 'name' => '编辑导航菜单',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '编辑导航菜单',
* 'param' => ''
* )
*/
public function edit()
{
$navMenuModel = new NavMenuModel();
$intNavId = $this->request->param("nav_id", 0, 'intval');
$intId = $this->request->param("id", 0, 'intval');
$intParentId = $this->request->param("parent_id", 0, 'intval');
$objResult = $navMenuModel
->where("nav_id", $intNavId)
->where("id", "neq", $intId)
->order(["list_order" => "ASC"])
->select();
$arrResult = $objResult ? $objResult->toArray() : [];
$tree = new Tree();
$tree->icon = ['&nbsp;│ ', '&nbsp;├─ ', '&nbsp;└─ '];
$tree->nbsp = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
$array = [];
foreach ($arrResult as $r) {
$r['str_manage'] = '<a href="' . url("NavMenu/add", ["parent_id" => $r['id'], "nav_id" => $intNavId]) . '">添加子菜单</a> | <a href="'
. url("NavMenu/edit", ["id" => $r['id'], "nav_id" => $intNavId]) . '">编辑</a> | <a class="js-ajax-delete" href="'
. url("NavMenu/delete", ["id" => $r['id'], "nav_id" => $intNavId]) . '">删除</a> ';
$r['status'] = $r['status'] ? "显示" : "隐藏";
$r['selected'] = $r['id'] == $intParentId ? "selected" : "";
$array[] = $r;
}
$tree->init($array);
$str = "<option value='\$id' \$selected>\$spacer\$name</option>";
$nav_trees = $tree->getTree(0, $str);
$this->assign("nav_trees", $nav_trees);
$objNav = $navMenuModel->where("id", $intId)->find();
$arrNav = $objNav ? $objNav->toArray() : [];
$arrNav['href_old'] = $arrNav['href'];
if (strpos($arrNav['href'], "{") === 0 || $arrNav['href'] == 'home') {
$arrNav['href'] = base64_encode($arrNav['href']);
}
$this->assign($arrNav);
$navs = $navMenuModel->selectNavs();
$this->assign('navs', $navs);
$this->assign("nav_id", $intNavId);
$this->assign("parent_id", $intParentId);
return $this->fetch();
}
/**
* 编辑导航菜单提交保存
* @adminMenu(
* 'name' => '编辑导航菜单提交保存',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '编辑导航菜单提交保存',
* 'param' => ''
* )
*/
public function editPost()
{
$navMenuModel = new NavMenuModel();
$intId = $this->request->param('id', 0, 'intval');
$arrData = $this->request->post();
if (isset($arrData['external_href'])) {
$arrData['href'] = htmlspecialchars_decode($arrData['external_href']);
} else {
$arrData['href'] = htmlspecialchars_decode($arrData['href']);
$arrData['href'] = base64_decode($arrData['href']);
}
$navMenuModel->update($arrData, ["id" => $intId], true);
$this->success(lang("EDIT_SUCCESS"), url("NavMenu/index", ['nav_id' => $arrData['nav_id']]));
}
/**
* 删除导航菜单
* @adminMenu(
* 'name' => '删除导航菜单',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '删除导航菜单',
* 'param' => ''
* )
*/
public function delete()
{
$navMenuModel = new NavMenuModel();
$intId = $this->request->param("id", 0, "intval");
$intNavId = $this->request->param("nav_id", 0, "intval");
if (empty($intId)) {
$this->error(lang("NO_ID"));
}
$count = $navMenuModel->where("parent_id", $intId)->count();
if ($count > 0) {
$this->error("该菜单下还有子菜单,无法删除!");
}
$navMenuModel->where("id", $intId)->delete();
$this->success(lang("DELETE_SUCCESS"), url("NavMenu/index", ['nav_id' => $intNavId]));
}
/**
* 导航菜单排序
* @adminMenu(
* 'name' => '导航菜单排序',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '导航菜单排序',
* 'param' => ''
* )
*/
public function listOrder()
{
$navMenuModel = new NavMenuModel();
$status = parent::listOrders($navMenuModel);
if ($status) {
$this->success("排序更新成功!");
} else {
$this->error("排序更新失败!");
}
}
}
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 老猫 <zxxjjforever@163.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use cmf\controller\AdminBaseController;
use app\admin\model\PluginModel;
use app\admin\model\HookPluginModel;
use mindplay\annotations\Annotations;
use think\Db;
use think\facade\Cache;
use think\Validate;
/**
* Class PluginController
* @package app\admin\controller
* @adminMenuRoot(
* 'name' =>'插件中心',
* 'action' =>'default',
* 'parent' =>'',
* 'display'=> true,
* 'order' => 20,
* 'icon' =>'cloud',
* 'remark' =>'插件中心'
* )
*/
class PluginController extends AdminBaseController
{
protected $pluginModel;
/**
* 插件列表
* @adminMenu(
* 'name' => '插件列表',
* 'parent' => 'admin/Plugin/default',
* 'display'=> true,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '插件列表',
* 'param' => ''
* )
*/
public function index()
{
$pluginModel = new PluginModel();
$plugins = $pluginModel->getList();
$this->assign("plugins", $plugins);
return $this->fetch();
}
/**
* 插件启用/禁用
* @adminMenu(
* 'name' => '插件启用禁用',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '插件启用禁用',
* 'param' => ''
* )
*/
public function toggle()
{
$id = $this->request->param('id', 0, 'intval');
$pluginModel = PluginModel::get($id);
if (empty($pluginModel)) {
$this->error('插件不存在!');
}
$status = 1;
$successMessage = "启用成功!";
if ($this->request->param('disable')) {
$status = 0;
$successMessage = "禁用成功!";
}
$pluginModel->startTrans();
try {
$pluginModel->save(['status' => $status], ['id' => $id]);
$hookPluginModel = new HookPluginModel();
$hookPluginModel->save(['status' => $status], ['plugin' => $pluginModel->name]);
$pluginModel->commit();
} catch (\Exception $e) {
$pluginModel->rollback();
$this->error('操作失败!');
}
Cache::clear('init_hook_plugins');
$this->success($successMessage);
}
/**
* 插件设置
* @adminMenu(
* 'name' => '插件设置',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '插件设置',
* 'param' => ''
* )
*/
public function setting()
{
$id = $this->request->param('id', 0, 'intval');
$pluginModel = new PluginModel();
$plugin = $pluginModel->find($id);
if (empty($plugin)) {
$this->error('插件未安装!');
}
$plugin = $plugin->toArray();
$pluginClass = cmf_get_plugin_class($plugin['name']);
if (!class_exists($pluginClass)) {
$this->error('插件不存在!');
}
$pluginObj = new $pluginClass;
//$plugin['plugin_path'] = $pluginObj->plugin_path;
//$plugin['custom_config'] = $pluginObj->custom_config;
$pluginConfigInDb = $plugin['config'];
$plugin['config'] = include $pluginObj->getConfigFilePath();
if ($pluginConfigInDb) {
$pluginConfigInDb = json_decode($pluginConfigInDb, true);
foreach ($plugin['config'] as $key => $value) {
if ($value['type'] != 'group') {
if (isset($pluginConfigInDb[$key])) {
$plugin['config'][$key]['value'] = $pluginConfigInDb[$key];
}
} else {
foreach ($value['options'] as $group => $options) {
foreach ($options['options'] as $gkey => $value) {
if (isset($pluginConfigInDb[$gkey])) {
$plugin['config'][$key]['options'][$group]['options'][$gkey]['value'] = $pluginConfigInDb[$gkey];
}
}
}
}
}
}
$this->assign('data', $plugin);
// if ($plugin['custom_config']) {
// $this->assign('custom_config', $this->fetch($plugin['plugin_path'] . $plugin['custom_config']));
// }
$this->assign('id', $id);
return $this->fetch();
}
/**
* 插件设置提交
* @adminMenu(
* 'name' => '插件设置提交',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '插件设置提交',
* 'param' => ''
* )
*/
public function settingPost()
{
if ($this->request->isPost()) {
$id = $this->request->param('id', 0, 'intval');
$pluginModel = new PluginModel();
$plugin = $pluginModel->find($id)->toArray();
if (!$plugin) {
$this->error('插件未安装!');
}
$pluginClass = cmf_get_plugin_class($plugin['name']);
if (!class_exists($pluginClass)) {
$this->error('插件不存在!');
}
$pluginObj = new $pluginClass;
//$plugin['plugin_path'] = $pluginObj->plugin_path;
//$plugin['custom_config'] = $pluginObj->custom_config;
$pluginConfigInDb = $plugin['config'];
$plugin['config'] = include $pluginObj->getConfigFilePath();
$rules = [];
$messages = [];
foreach ($plugin['config'] as $key => $value) {
if ($value['type'] != 'group') {
if (isset($value['rule'])) {
$rules[$key] = $this->_parseRules($value['rule']);
}
if (isset($value['message'])) {
foreach ($value['message'] as $rule => $msg) {
$messages[$key . '.' . $rule] = $msg;
}
}
} else {
foreach ($value['options'] as $group => $options) {
foreach ($options['options'] as $gkey => $value) {
if (isset($value['rule'])) {
$rules[$gkey] = $this->_parseRules($value['rule']);
}
if (isset($value['message'])) {
foreach ($value['message'] as $rule => $msg) {
$messages[$gkey . '.' . $rule] = $msg;
}
}
}
}
}
}
$config = $this->request->param('config/a');
$validate = new Validate($rules, $messages);
$result = $validate->check($config);
if ($result !== true) {
$this->error($validate->getError());
}
$pluginModel = new PluginModel();
$pluginModel->save(['config' => json_encode($config)], ['id' => $id]);
$this->success('保存成功', '');
}
}
/**
* 解析插件配置验证规则
* @param $rules
* @return array
*/
private function _parseRules($rules)
{
$newRules = [];
$simpleRules = [
'require', 'number',
'integer', 'float', 'boolean', 'email',
'array', 'accepted', 'date', 'alpha',
'alphaNum', 'alphaDash', 'activeUrl',
'url', 'ip'];
foreach ($rules as $key => $rule) {
if (in_array($key, $simpleRules) && $rule) {
array_push($newRules, $key);
}
}
return $newRules;
}
/**
* 插件安装
* @adminMenu(
* 'name' => '插件安装',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '插件安装',
* 'param' => ''
* )
*/
public function install()
{
$pluginName = $this->request->param('name', '', 'trim');
$class = cmf_get_plugin_class($pluginName);
if (!class_exists($class)) {
$this->error('插件不存在!');
}
$pluginModel = new PluginModel();
$pluginCount = $pluginModel->where('name', $pluginName)->count();
if ($pluginCount > 0) {
$this->error('插件已安装!');
}
$plugin = new $class;
$info = $plugin->info;
if (!$info || !$plugin->checkInfo()) {//检测信息的正确性
$this->error('插件信息缺失!');
}
$installSuccess = $plugin->install();
if (!$installSuccess) {
$this->error('插件预安装失败!');
}
$methods = get_class_methods($plugin);
foreach ($methods as $methodKey => $method) {
$methods[$methodKey] = cmf_parse_name($method);
}
$systemHooks = $pluginModel->getHooks(true);
$pluginHooks = array_intersect($systemHooks, $methods);
//$info['hooks'] = implode(",", $pluginHooks);
if (!empty($plugin->hasAdmin)) {
$info['has_admin'] = 1;
} else {
$info['has_admin'] = 0;
}
$info['config'] = json_encode($plugin->getConfig());
$pluginModel->data($info)->allowField(true)->save();
$hookPluginModel = new HookPluginModel();
foreach ($pluginHooks as $pluginHook) {
$hookPluginModel->data(['hook' => $pluginHook, 'plugin' => $pluginName, 'status' => 1])->isUpdate(false)->save();
}
$this->_getActions($pluginName);
Cache::clear('init_hook_plugins');
Cache::clear('admin_menus');// 删除后台菜单缓存
$this->success('安装成功!');
}
/**
* 插件更新
* @adminMenu(
* 'name' => '插件更新',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '插件更新',
* 'param' => ''
* )
*/
public function update()
{
$pluginName = $this->request->param('name', '', 'trim');
$class = cmf_get_plugin_class($pluginName);
if (!class_exists($class)) {
$this->error('插件不存在!');
}
$plugin = new $class;
$info = $plugin->info;
if (!$info || !$plugin->checkInfo()) {//检测信息的正确性
$this->error('插件信息缺失!');
}
$methods = get_class_methods($plugin);
foreach ($methods as $methodKey => $method) {
$methods[$methodKey] = cmf_parse_name($method);
}
$pluginModel = new PluginModel();
$systemHooks = $pluginModel->getHooks(true);
$pluginHooks = array_intersect($systemHooks, $methods);
if (!empty($plugin->hasAdmin)) {
$info['has_admin'] = 1;
} else {
$info['has_admin'] = 0;
}
$config = $plugin->getConfig();
$defaultConfig = $plugin->getDefaultConfig();
$pluginModel = new PluginModel();
$config = array_merge($defaultConfig, $config);
$info['config'] = json_encode($config);
$pluginModel->allowField(true)->save($info, ['name' => $pluginName]);
$hookPluginModel = new HookPluginModel();
$pluginHooksInDb = $hookPluginModel->where('plugin', $pluginName)->column('hook');
$samePluginHooks = array_intersect($pluginHooks, $pluginHooksInDb);
$shouldDeleteHooks = array_diff($samePluginHooks, $pluginHooksInDb);
$newHooks = array_diff($pluginHooks, $samePluginHooks);
if (count($shouldDeleteHooks) > 0) {
$hookPluginModel->where('hook', 'in', $shouldDeleteHooks)->delete();
}
foreach ($newHooks as $pluginHook) {
$hookPluginModel->data(['hook' => $pluginHook, 'plugin' => $pluginName])->isUpdate(false)->save();
}
$this->_getActions($pluginName);
Cache::clear('init_hook_plugins');
Cache::clear('admin_menus');// 删除后台菜单缓存
$this->success('更新成功!');
}
private function _getActions($pluginName)
{
Annotations::$config['cache'] = false;
$annotationManager = Annotations::getManager();
$annotationManager->registry['adminMenu'] = 'app\admin\annotation\AdminMenuAnnotation';
$annotationManager->registry['adminMenuRoot'] = 'app\admin\annotation\AdminMenuRootAnnotation';
$newMenus = [];
$pluginDir = cmf_parse_name($pluginName);
$filePatten = WEB_ROOT . 'plugins/' . $pluginDir . '/controller/Admin*Controller.php';
$controllers = cmf_scan_dir($filePatten);
$app = 'plugin/' . $pluginName;
if (!empty($controllers)) {
foreach ($controllers as $controller) {
$controller = preg_replace('/\.php$/', '', $controller);
$controllerName = preg_replace('/\Controller$/', '', $controller);
$controllerClass = "plugins\\$pluginDir\\controller\\$controller";
$menuAnnotations = Annotations::ofClass($controllerClass, '@adminMenuRoot');
if (!empty($menuAnnotations)) {
foreach ($menuAnnotations as $menuAnnotation) {
$name = $menuAnnotation->name;
$icon = $menuAnnotation->icon;
$type = 0;//1:有界面可访问菜单,2:无界面可访问菜单,0:只作为菜单
$action = $menuAnnotation->action;
$status = empty($menuAnnotation->display) ? 0 : 1;
$listOrder = floatval($menuAnnotation->order);
$param = $menuAnnotation->param;
$remark = $menuAnnotation->remark;
if (empty($menuAnnotation->parent)) {
$parentId = 0;
} else {
$parent = explode('/', $menuAnnotation->parent);
$countParent = count($parent);
if ($countParent > 3) {
throw new \Exception($controllerClass . ':' . $action . ' @adminMenuRoot parent格式不正确!');
}
$parentApp = $app;
$parentController = $controllerName;
$parentAction = '';
switch ($countParent) {
case 1:
$parentAction = $parent[0];
break;
case 2:
$parentController = $parent[0];
$parentAction = $parent[1];
break;
case 3:
$parentApp = $parent[0];
$parentController = $parent[1];
$parentAction = $parent[2];
break;
}
$findParentAdminMenu = Db::name('admin_menu')->where([
'app' => $parentApp,
'controller' => $parentController,
'action' => $parentAction
])->find();
if (empty($findParentAdminMenu)) {
$parentId = Db::name('admin_menu')->insertGetId([
'app' => $parentApp,
'controller' => $parentController,
'action' => $parentAction,
'name' => '--new--'
]);
} else {
$parentId = $findParentAdminMenu['id'];
}
}
$findAdminMenu = Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->find();
if (empty($findAdminMenu)) {
Db::name('admin_menu')->insert([
'parent_id' => $parentId,
'type' => $type,
'status' => $status,
'list_order' => $listOrder,
'app' => $app,
'controller' => $controllerName,
'action' => $action,
'param' => $param,
'name' => $name,
'icon' => $icon,
'remark' => $remark
]);
$menuName = $name;
// array_push($newMenus, $app . "/$controllerName/$action 已导入");
} else {
if ($findAdminMenu['name'] == '--new--') {
Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->update([
'parent_id' => $parentId,
'type' => $type,
'status' => $status,
'list_order' => $listOrder,
'param' => $param,
'name' => $name,
'icon' => $icon,
'remark' => $remark
]);
$menuName = $name;
} else {
// 只关注菜单层级关系,是否有视图
Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->update([
//'parent_id' => $parentId,
'type' => $type,
]);
$menuName = $findAdminMenu['name'];
}
// array_push($newMenus, $app."/$controllerName/$action 层级关系已更新");
}
$authRuleName = "plugin/{$pluginName}/{$controllerName}/{$action}";
$findAuthRuleCount = Db::name('auth_rule')->where([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url'
])->count();
if ($findAuthRuleCount == 0) {
Db::name('auth_rule')->insert([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url',
'param' => $param,
'title' => $menuName
]);
} else {
Db::name('auth_rule')->where([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url',
])->update([
'param' => $param,
'title' => $menuName
]);
}
}
}
$reflect = new \ReflectionClass($controllerClass);
$methods = $reflect->getMethods(\ReflectionMethod::IS_PUBLIC);
if (!empty($methods)) {
foreach ($methods as $method) {
if ($method->class == $controllerClass && strpos($method->name, '_') !== 0) {
$menuAnnotations = Annotations::ofMethod($controllerClass, $method->name, '@adminMenu');
if (!empty($menuAnnotations)) {
$menuAnnotation = $menuAnnotations[0];
$name = $menuAnnotation->name;
$icon = $menuAnnotation->icon;
$type = $menuAnnotation->hasView ? 1 : 2;//1:有界面可访问菜单,2:无界面可访问菜单,0:只作为菜单
$action = $method->name;
$status = empty($menuAnnotation->display) ? 0 : 1;
$listOrder = floatval($menuAnnotation->order);
$param = $menuAnnotation->param;
$remark = $menuAnnotation->remark;
if (empty($menuAnnotation->parent)) {
$parentId = 0;
} else {
$parent = explode('/', $menuAnnotation->parent);
$countParent = count($parent);
if ($countParent > 3) {
throw new \Exception($controllerClass . ':' . $action . ' @menuRoot parent格式不正确!');
}
$parentApp = $app;
$parentController = $controllerName;
$parentAction = '';
switch ($countParent) {
case 1:
$parentAction = $parent[0];
break;
case 2:
$parentController = $parent[0];
$parentAction = $parent[1];
break;
case 3:
$parentApp = $parent[0];
$parentController = $parent[1];
$parentAction = $parent[2];
break;
}
$findParentAdminMenu = Db::name('admin_menu')->where([
'app' => $parentApp,
'controller' => $parentController,
'action' => $parentAction
])->find();
if (empty($findParentAdminMenu)) {
$parentId = Db::name('admin_menu')->insertGetId([
'app' => $parentApp,
'controller' => $parentController,
'action' => $parentAction,
'name' => '--new--'
]);
} else {
$parentId = $findParentAdminMenu['id'];
}
}
$findAdminMenu = Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->find();
if (empty($findAdminMenu)) {
Db::name('admin_menu')->insert([
'parent_id' => $parentId,
'type' => $type,
'status' => $status,
'list_order' => $listOrder,
'app' => $app,
'controller' => $controllerName,
'action' => $action,
'param' => $param,
'name' => $name,
'icon' => $icon,
'remark' => $remark
]);
$menuName = $name;
//array_push($newMenus, "$app/$controllerName/$action 已导入");
} else {
if ($findAdminMenu['name'] == '--new--') {
Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->update([
'parent_id' => $parentId,
'type' => $type,
'status' => $status,
'list_order' => $listOrder,
'param' => $param,
'name' => $name,
'icon' => $icon,
'remark' => $remark
]);
$menuName = $name;
} else {
// 只关注是否有视图
Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->update([
//'parent_id' => $parentId,
'type' => $type,
]);
$menuName = $findAdminMenu['name'];
}
// array_push($newMenus, "$app/$controllerName/$action 已更新");
}
$authRuleName = "plugin/{$pluginName}/{$controllerName}/{$action}";
$findAuthRuleCount = Db::name('auth_rule')->where([
'app' => $app,
'name' => $authRuleName,
'type' => 'plugin_url'
])->count();
if ($findAuthRuleCount == 0) {
Db::name('auth_rule')->insert([
'app' => $app,
'name' => $authRuleName,
'type' => 'plugin_url',
'param' => $param,
'title' => $menuName
]);
} else {
Db::name('auth_rule')->where([
'app' => $app,
'name' => $authRuleName,
'type' => 'plugin_url',
])->update([
'param' => $param,
'title' => $menuName
]);
}
}
}
}
}
}
}
}
/**
* 卸载插件
* @adminMenu(
* 'name' => '卸载插件',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '卸载插件',
* 'param' => ''
* )
*/
public function uninstall()
{
$pluginModel = new PluginModel();
$id = $this->request->param('id', 0, 'intval');
$result = $pluginModel->uninstall($id);
if ($result !== true) {
$this->error('卸载失败!');
}
Cache::clear('init_hook_plugins');
Cache::clear('admin_menus');// 删除后台菜单缓存
$this->success('卸载成功!');
}
}
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 小夏 < 449134904@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use cmf\controller\AdminBaseController;
use think\Db;
class PublicController extends AdminBaseController
{
public function initialize()
{
}
/**
* 后台登陆界面
*/
public function login()
{
$loginAllowed = session("__LOGIN_BY_CMF_ADMIN_PW__");
if (empty($loginAllowed)) {
//$this->error('非法登录!', cmf_get_root() . '/');
return redirect(cmf_get_root() . "/");
}
$admin_id = session('ADMIN_ID');
if (!empty($admin_id)) {//已经登录
return redirect(url("admin/Index/index"));
} else {
session("__SP_ADMIN_LOGIN_PAGE_SHOWED_SUCCESS__", true);
$result = hook_one('admin_login');
if (!empty($result)) {
return $result;
}
return $this->fetch(":login");
}
}
/**
* 登录验证
*/
public function doLogin()
{
if (hook_one('admin_custom_login_open')) {
$this->error('您已经通过插件自定义后台登录!');
}
$loginAllowed = session("__LOGIN_BY_CMF_ADMIN_PW__");
if (empty($loginAllowed)) {
$this->error('非法登录!', cmf_get_root() . '/');
}
$captcha = $this->request->param('captcha');
if (empty($captcha)) {
$this->error(lang('CAPTCHA_REQUIRED'));
}
//验证码
if (!cmf_captcha_check($captcha)) {
$this->error(lang('CAPTCHA_NOT_RIGHT'));
}
$name = $this->request->param("username");
if (empty($name)) {
$this->error(lang('USERNAME_OR_EMAIL_EMPTY'));
}
$pass = $this->request->param("password");
if (empty($pass)) {
$this->error(lang('PASSWORD_REQUIRED'));
}
if (strpos($name, "@") > 0) {//邮箱登陆
$where['user_email'] = $name;
} else {
$where['user_login'] = $name;
}
$result = Db::name('user')->where($where)->find();
if (!empty($result) && $result['user_type'] == 1) {
if (cmf_compare_password($pass, $result['user_pass'])) {
$groups = Db::name('RoleUser')
->alias("a")
->join('__ROLE__ b', 'a.role_id =b.id')
->where(["user_id" => $result["id"], "status" => 1])
->value("role_id");
if ($result["id"] != 1 && (empty($groups) || empty($result['user_status']))) {
$this->error(lang('USE_DISABLED'));
}
//登入成功页面跳转
session('ADMIN_ID', $result["id"]);
session('name', $result["user_login"]);
$result['last_login_ip'] = get_client_ip(0, true);
$result['last_login_time'] = time();
$token = cmf_generate_user_token($result["id"], 'web');
if (!empty($token)) {
session('token', $token);
}
Db::name('user')->update($result);
cookie("admin_username", $name, 3600 * 24 * 30);
session("__LOGIN_BY_CMF_ADMIN_PW__", null);
$this->success(lang('LOGIN_SUCCESS'), url("admin/Index/index"));
} else {
$this->error(lang('PASSWORD_NOT_RIGHT'));
}
} else {
$this->error(lang('USERNAME_NOT_EXIST'));
}
}
/**
* 后台管理员退出
*/
public function logout()
{
session('ADMIN_ID', null);
return redirect(url('/', [], false, true));
}
}
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 小夏 < 449134904@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use cmf\controller\AdminBaseController;
use think\Db;
use think\facade\Cache;
use tree\Tree;
use app\admin\model\AdminMenuModel;
class RbacController extends AdminBaseController
{
/**
* 角色管理列表
* @adminMenu(
* 'name' => '角色管理',
* 'parent' => 'admin/User/default',
* 'display'=> true,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '角色管理',
* 'param' => ''
* )
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index()
{
$content = hook_one('admin_rbac_index_view');
if (!empty($content)) {
return $content;
}
$data = Db::name('role')->order(["list_order" => "ASC", "id" => "DESC"])->select();
$this->assign("roles", $data);
return $this->fetch();
}
/**
* 添加角色
* @adminMenu(
* 'name' => '添加角色',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '添加角色',
* 'param' => ''
* )
* @return mixed
*/
public function roleAdd()
{
$content = hook_one('admin_rbac_role_add_view');
if (!empty($content)) {
return $content;
}
return $this->fetch();
}
/**
* 添加角色提交
* @adminMenu(
* 'name' => '添加角色提交',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '添加角色提交',
* 'param' => ''
* )
*/
public function roleAddPost()
{
if ($this->request->isPost()) {
$data = $this->request->param();
$result = $this->validate($data, 'role');
if ($result !== true) {
// 验证失败 输出错误信息
$this->error($result);
} else {
$result = Db::name('role')->insert($data);
if ($result) {
$this->success("添加角色成功", url("rbac/index"));
} else {
$this->error("添加角色失败");
}
}
}
}
/**
* 编辑角色
* @adminMenu(
* 'name' => '编辑角色',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '编辑角色',
* 'param' => ''
* )
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function roleEdit()
{
$content = hook_one('admin_rbac_role_edit_view');
if (!empty($content)) {
return $content;
}
$id = $this->request->param("id", 0, 'intval');
if ($id == 1) {
$this->error("超级管理员角色不能被修改!");
}
$data = Db::name('role')->where("id", $id)->find();
if (!$data) {
$this->error("该角色不存在!");
}
$this->assign("data", $data);
return $this->fetch();
}
/**
* 编辑角色提交
* @adminMenu(
* 'name' => '编辑角色提交',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '编辑角色提交',
* 'param' => ''
* )
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function roleEditPost()
{
$id = $this->request->param("id", 0, 'intval');
if ($id == 1) {
$this->error("超级管理员角色不能被修改!");
}
if ($this->request->isPost()) {
$data = $this->request->param();
$result = $this->validate($data, 'role');
if ($result !== true) {
// 验证失败 输出错误信息
$this->error($result);
} else {
if (Db::name('role')->update($data) !== false) {
$this->success("保存成功!", url('rbac/index'));
} else {
$this->error("保存失败!");
}
}
}
}
/**
* 删除角色
* @adminMenu(
* 'name' => '删除角色',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '删除角色',
* 'param' => ''
* )
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function roleDelete()
{
$id = $this->request->param("id", 0, 'intval');
if ($id == 1) {
$this->error("超级管理员角色不能被删除!");
}
$count = Db::name('RoleUser')->where('role_id', $id)->count();
if ($count > 0) {
$this->error("该角色已经有用户!");
} else {
$status = Db::name('role')->delete($id);
if (!empty($status)) {
$this->success("删除成功!", url('rbac/index'));
} else {
$this->error("删除失败!");
}
}
}
/**
* 设置角色权限
* @adminMenu(
* 'name' => '设置角色权限',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '设置角色权限',
* 'param' => ''
* )
* @return mixed
*/
public function authorize()
{
$content = hook_one('admin_rbac_authorize_view');
if (!empty($content)) {
return $content;
}
$AuthAccess = Db::name("AuthAccess");
$adminMenuModel = new AdminMenuModel();
//角色ID
$roleId = $this->request->param("id", 0, 'intval');
if (empty($roleId)) {
$this->error("参数错误!");
}
$tree = new Tree();
$tree->icon = ['│ ', '├─ ', '└─ '];
$tree->nbsp = '&nbsp;&nbsp;&nbsp;';
$result = $adminMenuModel->menuCache();
$newMenus = [];
$privilegeData = $AuthAccess->where("role_id", $roleId)->column("rule_name");//获取权限表数据
foreach ($result as $m) {
$newMenus[$m['id']] = $m;
}
foreach ($result as $n => $t) {
$result[$n]['checked'] = ($this->_isChecked($t, $privilegeData)) ? ' checked' : '';
$result[$n]['level'] = $this->_getLevel($t['id'], $newMenus);
$result[$n]['style'] = empty($t['parent_id']) ? '' : 'display:none;';
$result[$n]['parentIdNode'] = ($t['parent_id']) ? ' class="child-of-node-' . $t['parent_id'] . '"' : '';
}
$str = "<tr id='node-\$id'\$parentIdNode style='\$style'>
<td style='padding-left:30px;'>\$spacer<input type='checkbox' name='menuId[]' value='\$id' level='\$level' \$checked onclick='javascript:checknode(this);'> \$name</td>
</tr>";
$tree->init($result);
$category = $tree->getTree(0, $str);
$this->assign("category", $category);
$this->assign("roleId", $roleId);
return $this->fetch();
}
/**
* 角色授权提交
* @adminMenu(
* 'name' => '角色授权提交',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '角色授权提交',
* 'param' => ''
* )
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
public function authorizePost()
{
if ($this->request->isPost()) {
$roleId = $this->request->param("roleId", 0, 'intval');
if (!$roleId) {
$this->error("需要授权的角色不存在!");
}
if (is_array($this->request->param('menuId/a')) && count($this->request->param('menuId/a')) > 0) {
Db::name("authAccess")->where(["role_id" => $roleId, 'type' => 'admin_url'])->delete();
foreach ($_POST['menuId'] as $menuId) {
$menu = Db::name("adminMenu")->where("id", $menuId)->field("app,controller,action")->find();
if ($menu) {
$app = $menu['app'];
$model = $menu['controller'];
$action = $menu['action'];
$name = strtolower("$app/$model/$action");
Db::name("authAccess")->insert(["role_id" => $roleId, "rule_name" => $name, 'type' => 'admin_url']);
}
}
Cache::clear('admin_menus');// 删除后台菜单缓存
$this->success("授权成功!");
} else {
//当没有数据时,清除当前角色授权
Db::name("authAccess")->where("role_id", $roleId)->delete();
$this->error("没有接收到数据,执行清除授权成功!");
}
}
}
/**
* 检查指定菜单是否有权限
* @param array $menu menu表中数组
* @param $privData
* @return bool
*/
private function _isChecked($menu, $privData)
{
$app = $menu['app'];
$model = $menu['controller'];
$action = $menu['action'];
$name = strtolower("$app/$model/$action");
if ($privData) {
if (in_array($name, $privData)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
/**
* 获取菜单深度
* @param $id
* @param array $array
* @param int $i
* @return int
*/
protected function _getLevel($id, $array = [], $i = 0)
{
if ($array[$id]['parent_id'] == 0 || empty($array[$array[$id]['parent_id']]) || $array[$id]['parent_id'] == $id) {
return $i;
} else {
$i++;
return $this->_getLevel($array[$id]['parent_id'], $array, $i);
}
}
//角色成员管理
public function member()
{
//TODO 添加角色成员管理
}
}
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 小夏 < 449134904@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use app\admin\model\RecycleBinModel;
use app\admin\model\RouteModel;
use cmf\controller\AdminBaseController;
use think\Db;
class RecycleBinController extends AdminBaseController
{
/**
* 回收站
* @adminMenu(
* 'name' => '回收站',
* 'parent' => '',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '回收站',
* 'param' => ''
* )
*/
public function index()
{
$content = hook_one('admin_recycle_bin_index_view');
if (!empty($content)) {
return $content;
}
$recycleBinModel = new RecycleBinModel();
$list = $recycleBinModel->order('create_time desc')->paginate(10);
// 获取分页显示
$page = $list->render();
$this->assign('page', $page);
$this->assign('list', $list);
return $this->fetch();
}
/**
* 回收站还原
* @adminMenu(
* 'name' => '回收站还原',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '回收站还原',
* 'param' => ''
* )
*/
public function restore()
{
$id = $this->request->param('id', 0, 'intval');
$result = Db::name('recycleBin')->where('id', $id)->find();
$tableName = explode('#', $result['table_name']);
$tableName = $tableName[0];
//还原资源
if ($result) {
$res = Db::name($tableName)
->where('id', $result['object_id'])
->update(['delete_time' => '0']);
if ($tableName == 'portal_post') {
Db::name('portal_category_post')->where('post_id', $result['object_id'])->update(['status' => 1]);
Db::name('portal_tag_post')->where('post_id', $result['object_id'])->update(['status' => 1]);
}
if ($res) {
$re = Db::name('recycleBin')->where('id', $id)->delete();
if ($re) {
$this->success("还原成功!");
}
}
}
}
/**
* 回收站彻底删除
* @adminMenu(
* 'name' => '回收站彻底删除',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '回收站彻底删除',
* 'param' => ''
* )
*/
public function delete()
{
$id = $this->request->param('id');
$result = Db::name('recycleBin')->where('id', $id)->find();
//删除资源
if ($result) {
//页面没有单独的表.
if ($result['table_name'] === 'portal_post#page') {
$re = Db::name('portal_post')->where('id', $result['object_id'])->delete();
//消除路由
$routeModel = new RouteModel();
$routeModel->setRoute('', 'portal/Page/index', ['id' => $result['object_id']], 2, 5000);
$routeModel->getRoutes(true);
} else {
$re = Db::name($result['table_name'])->where('id', $result['object_id'])->delete();
}
if ($re) {
$res = Db::name('recycleBin')->where('id', $id)->delete();
if ($result['table_name'] === 'portal_post') {
Db::name('portal_category_post')->where('post_id', $result['object_id'])->delete();
Db::name('portal_tag_post')->where('post_id', $result['object_id'])->delete();
}
if ($res) {
$this->success("删除成功!");
}
}
}
}
}
\ No newline at end of file
... ...
<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2019 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 老猫 <thinkcmf@126.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use app\admin\model\RouteModel;
use cmf\controller\AdminBaseController;
use think\Db;
class RouteController extends AdminBaseController
{
/**
* 路由规则列表
* @adminMenu(
* 'name' => 'URL美化',
* 'parent' => 'admin/Setting/default',
* 'display'=> true,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => 'URL规则管理',
* 'param' => ''
* )
*/
public function index()
{
global $CMF_GV_routes;
$routeModel = new RouteModel();
$routes = Db::name('route')->order("list_order asc")->select();
$routeModel->getRoutes(true);
unset($CMF_GV_routes);
$this->assign("routes", $routes);
return $this->fetch();
}
/**
* 添加路由规则
* @adminMenu(
* 'name' => '添加路由规则',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '添加路由规则',
* 'param' => ''
* )
*/
public function add()
{
return $this->fetch();
}
/**
* 添加路由规则提交
* @adminMenu(
* 'name' => '添加路由规则提交',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '添加路由规则提交',
* 'param' => ''
* )
*/
public function addPost()
{
$data = $this->request->param();
$routeModel = new RouteModel();
$result = $this->validate($data, 'Route');
if ($result !== true) {
$this->error($result);
}
$routeModel->allowField(true)->save($data);
$this->success("添加成功!", url("Route/index", ['id' => $routeModel->id]));
}
/**
* 路由规则编辑
* @adminMenu(
* 'name' => '路由规则编辑',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '路由规则编辑',
* 'param' => ''
* )
*/
public function edit()
{
$id = $this->request->param("id", 0, 'intval');
$route = Db::name('route')->where('id', $id)->find();
$this->assign($route);
return $this->fetch();
}
/**
* 路由规则编辑提交
* @adminMenu(
* 'name' => '路由规则编辑提交',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '路由规则编辑提交',
* 'param' => ''
* )
*/
public function editPost()
{
$data = $this->request->param();
$routeModel = new RouteModel();
$result = $this->validate($data, 'Route');
if ($result !== true) {
$this->error($result);
}
$routeModel->allowField(true)->isUpdate(true)->save($data);
$this->success("保存成功!", url("Route/index"));
}
/**
* 路由规则删除
* @adminMenu(
* 'name' => '路由规则删除',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '路由规则删除',
* 'param' => ''
* )
*/
public function delete()
{
$id = $this->request->param('id', 0, 'intval');
RouteModel::destroy($id);
$this->success("删除成功!");
}
/**
* 路由规则禁用
* @adminMenu(
* 'name' => '路由规则禁用',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '路由规则禁用',
* 'param' => ''
* )
*/
public function ban()
{
$id = $this->request->param("id", 0, 'intval');
$data = [];
$data['status'] = 0;
$data['id'] = $id;
$routeModel = new RouteModel();
$routeModel->isUpdate(true)->save($data);
$this->success("禁用成功!");
}
/**
* 路由规则启用
* @adminMenu(
* 'name' => '路由规则启用',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '路由规则启用',
* 'param' => ''
* )
*/
public function open()
{
$id = $this->request->param("id", 0, 'intval');
$data = [];
$data['status'] = 1;
$data['id'] = $id;
$routeModel = new RouteModel();
$routeModel->isUpdate(true)->save($data);
$this->success("启用成功!");
}
/**
* 路由规则排序
* @adminMenu(
* 'name' => '路由规则排序',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> false,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '路由规则排序',
* 'param' => ''
* )
*/
public function listOrder()
{
$routeModel = new RouteModel();
parent::listOrders($routeModel);
$this->success("排序更新成功!");
}
/**
* 选择 URL
* @adminMenu(
* 'name' => '选择URL',
* 'parent' => 'index',
* 'display'=> false,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => '选择URL',
* 'param' => ''
* )
*/
public function select()
{
$routeModel = new RouteModel();
$urls = $routeModel->getAppUrls();
$this->assign('urls', $urls);
return $this->fetch();
}
function _suggest_url($action, $url)
{
$actionArr = explode('/', $action);
$params = array_keys($url['vars']);
$urlDepr1Params = [];
$urlDepr2Params = [];
if (!empty($params)) {
foreach ($params as $param) {
if (empty($url['vars'][$param]['require'])) {
array_push($urlDepr1Params, "[:$param]");
} else {
array_push($urlDepr1Params, ":$param");
}
array_push($urlDepr2Params, htmlspecialchars('<') . $param . htmlspecialchars('>'));
}
}
if ($actionArr[2] == 'index') {
$actionArr[1] = cmf_parse_name($actionArr[1]);
return empty($params) ? $actionArr[1] . '$' : ($actionArr[1] . '/' . implode('/', $urlDepr1Params) /*. '或' . $actionArr[1] . '-' . implode('-', $urlDepr2Params)*/);
} else {
$actionArr[2] = cmf_parse_name($actionArr[2]);
return empty($params) ? $actionArr[2] . '$' : ($actionArr[2] . '/' . implode('/', $urlDepr1Params) /*. '或' . $actionArr[2] . '-' . implode('-', $urlDepr2Params)*/);
}
}
function _url_vars($url)
{
if (!empty($url['vars'])) {
return implode(',', array_keys($url['vars']));
}
return '';
}
}
\ No newline at end of file
... ...