<?php // +---------------------------------------------------------------------- // | bronet [ 以客户为中心 以奋斗者为本 ] // +---------------------------------------------------------------------- // | Copyright (c) 2013-2017 http://www.bronet.cn 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\ThemeModel; use think\Db; use think\Validate; use tree\Tree; class ThemeController extends AdminBaseController { /** * 模板管理 * @adminMenu( * 'name' => '模板管理', * 'parent' => 'admin/Setting/default', * 'display'=> true, * 'hasView'=> true, * 'order' => 20, * 'icon' => '', * 'remark' => '模板管理', * 'param' => '' * ) */ public function index() { $themeModel = new ThemeModel(); $themes = $themeModel->select(); $this->assign("themes", $themes); $defaultTheme = config('cmf_default_theme'); if ($temp = session('cmf_default_theme')){ $defaultTheme = $temp; } $this->assign('default_theme', $defaultTheme); return $this->fetch(); } /** * 安装模板 * @adminMenu( * 'name' => '安装模板', * 'parent' => 'index', * 'display'=> false, * 'hasView'=> true, * 'order' => 10000, * 'icon' => '', * 'remark' => '安装模板', * 'param' => '' * ) */ public function install() { $themesDirs = cmf_scan_dir("themes/*", GLOB_ONLYDIR); $themeModel = new ThemeModel(); $themesInstalled = $themeModel->column('theme'); $themesDirs = array_diff($themesDirs, $themesInstalled); $themes = []; foreach ($themesDirs as $dir) { $manifest = "themes/$dir/manifest.json"; if (file_exists_case($manifest)) { $manifest = file_get_contents($manifest); $theme = json_decode($manifest, true); $theme['theme'] = $dir; array_push($themes, $theme); } } $this->assign('themes', $themes); return $this->fetch(); } /** * 卸载模板 * @adminMenu( * 'name' => '卸载模板', * 'parent' => 'index', * 'display'=> false, * 'hasView'=> false, * 'order' => 10000, * 'icon' => '', * 'remark' => '卸载模板', * 'param' => '' * ) */ public function uninstall() { $theme = $this->request->param('theme'); if ($theme == "simpleboot3" || config('cmf_default_theme') == $theme ){ $this->error("官方自带模板或当前使用中的模板不可以卸载"); } $themeModel = new ThemeModel(); $themeModel->transaction(function () use ($theme, $themeModel) { $themeModel->where(['theme' => $theme])->delete(); Db::name('theme_file')->where(['theme' => $theme])->delete(); }); $this->success("卸载成功", url("theme/index")); } /** * 模板安装 * @adminMenu( * 'name' => '模板安装', * 'parent' => 'index', * 'display'=> false, * 'hasView'=> false, * 'order' => 10000, * 'icon' => '', * 'remark' => '模板安装', * 'param' => '' * ) */ public function installTheme() { $theme = $this->request->param('theme'); $themeModel = new ThemeModel(); $themeCount = $themeModel->where('theme', $theme)->count(); if ($themeCount > 0) { $this->error('模板已经安装!'); } $result = $themeModel->installTheme($theme); if ($result === false) { $this->error('模板不存在!'); } $this->success("安装成功", url("theme/index")); } /** * 模板更新 * @adminMenu( * 'name' => '模板更新', * 'parent' => 'index', * 'display'=> false, * 'hasView'=> false, * 'order' => 10000, * 'icon' => '', * 'remark' => '模板更新', * 'param' => '' * ) */ public function update() { $theme = $this->request->param('theme'); $themeModel = new ThemeModel(); $themeCount = $themeModel->where('theme', $theme)->count(); if ($themeCount === 0) { $this->error('模板未安装!'); } $result = $themeModel->updateTheme($theme); if ($result === false) { $this->error('模板不存在!'); } $this->success("更新成功", url("theme/index")); } /** * 启用模板 * @adminMenu( * 'name' => '启用模板', * 'parent' => 'index', * 'display'=> false, * 'hasView'=> false, * 'order' => 10000, * 'icon' => '', * 'remark' => '启用模板', * 'param' => '' * ) */ public function active() { $theme = $this->request->param('theme'); if ($theme == config('cmf_default_theme')){ $this->error('模板已启用',url("theme/index")); } $themeModel = new ThemeModel(); $themeCount = $themeModel->where('theme', $theme)->count(); if ($themeCount === 0) { $this->error('模板未安装!'); } $result = cmf_set_dynamic_config(['cmf_default_theme' => $theme]); if ($result === false) { $this->error('配置写入失败!'); } session('cmf_default_theme',$theme); $this->success("模板启用成功",url("theme/index")); } /** * 模板文件列表 * @adminMenu( * 'name' => '模板文件列表', * 'parent' => 'index', * 'display'=> false, * 'hasView'=> true, * 'order' => 10000, * 'icon' => '', * 'remark' => '启用模板', * 'param' => '' * ) */ public function files() { $theme = $this->request->param('theme'); $files = Db::name('theme_file')->where(['theme' => $theme])->order('list_order ASC')->select()->toArray(); $this->assign('files', $files); return $this->fetch(); } /** * 模板文件设置 * @adminMenu( * 'name' => '模板文件设置', * 'parent' => 'index', * 'display'=> false, * 'hasView'=> true, * 'order' => 10000, * 'icon' => '', * 'remark' => '模板文件设置', * 'param' => '' * ) */ public function fileSetting() { $tab = $this->request->param('tab', 'widget'); $fileId = $this->request->param('file_id', 0, 'intval'); $file = Db::name('theme_file')->where(['id' => $fileId])->find(); $file['config_more'] = json_decode($file['config_more'], true); $file['more'] = json_decode($file['more'], true); $this->assign('tab', $tab); $this->assign('file', $file); $this->assign('file_id', $fileId); $tpl = 'file_widget_setting'; if ($tab == 'var') { $tpl = 'file_var_setting'; } return $this->fetch($tpl); } /** * 模板文件数组数据列表 * @adminMenu( * 'name' => '模板文件数组数据列表', * 'parent' => 'index', * 'display'=> false, * 'hasView'=> true, * 'order' => 10000, * 'icon' => '', * 'remark' => '模板文件数组数据列表', * 'param' => '' * ) */ public function fileArrayData() { $tab = $this->request->param('tab', 'widget'); $varName = $this->request->param('var'); $widgetName = $this->request->param('widget', ''); $fileId = $this->request->param('file_id', 0, 'intval'); $file = Db::name('theme_file')->where(['id' => $fileId])->find(); $file['config_more'] = json_decode($file['config_more'], true); $file['more'] = json_decode($file['more'], true); $oldMore = $file['more']; $items = []; $item = []; if ($tab == 'var' && !empty($oldMore['vars']) && is_array($oldMore['vars'])) { if (isset($oldMore['vars'][$varName]) && is_array($oldMore['vars'][$varName])) { $items = $oldMore['vars'][$varName]['value']; } if (isset($oldMore['vars'][$varName]['item'])) { $item = $oldMore['vars'][$varName]['item']; } } if ($tab == 'widget' && !empty($oldMore['widgets'][$widgetName]) && is_array($oldMore['widgets'][$widgetName])) { $widget = $oldMore['widgets'][$widgetName]; if (!empty($widget['vars']) && is_array($widget['vars'])) { foreach ($widget['vars'] as $mVarName => $mVar) { if ($mVarName == $varName) { if (is_array($mVar['value'])) { $items = $mVar['value']; } if (isset($mVar['item'])) { $item = $mVar['item']; } } } } } $this->assign('tab', $tab); $this->assign('var', $varName); $this->assign('widget', $widgetName); $this->assign('file_id', $fileId); $this->assign('array_items', $items); $this->assign('array_item', $item); return $this->fetch('file_array_data'); } /** * 模板文件数组数据添加编辑 * @adminMenu( * 'name' => '模板文件数组数据添加编辑', * 'parent' => 'index', * 'display'=> false, * 'hasView'=> false, * 'order' => 10000, * 'icon' => '', * 'remark' => '模板文件数组数据添加编辑', * 'param' => '' * ) */ public function fileArrayDataEdit() { $tab = $this->request->param('tab', 'widget'); $varName = $this->request->param('var'); $widgetName = $this->request->param('widget', ''); $fileId = $this->request->param('file_id', 0, 'intval'); $itemIndex = $this->request->param('item_index', ''); $file = Db::name('theme_file')->where(['id' => $fileId])->find(); $file['config_more'] = json_decode($file['config_more'], true); $file['more'] = json_decode($file['more'], true); $oldMore = $file['more']; $items = []; $item = []; if ($tab == 'var' && !empty($oldMore['vars']) && is_array($oldMore['vars'])) { if (isset($oldMore['vars'][$varName]) && is_array($oldMore['vars'][$varName])) { $items = $oldMore['vars'][$varName]['value']; } if (isset($oldMore['vars'][$varName]['item'])) { $item = $oldMore['vars'][$varName]['item']; } } if ($tab == 'widget') { if (empty($widgetName)) { $this->error('未指定控件!'); } if (!empty($oldMore['widgets']) && is_array($oldMore['widgets'])) { foreach ($oldMore['widgets'] as $mWidgetName => $widget) { if ($mWidgetName == $widgetName) { if (!empty($widget['vars']) && is_array($widget['vars'])) { foreach ($widget['vars'] as $widgetVarName => $widgetVar) { if ($widgetVarName == $varName && $widgetVar['type'] == 'array') { if (is_array($widgetVar['value'])) { $items = $widgetVar['value']; } if (isset($widgetVar['item'])) { $item = $widgetVar['item']; } break; } } } break; } } } } if ($itemIndex !== '') { $itemIndex = intval($itemIndex); if (!isset($items[$itemIndex])) { $this->error('数据不存在!'); } foreach ($item as $itemName => $vo) { if (isset($items[$itemIndex][$itemName])) { $item[$itemName]['value'] = $items[$itemIndex][$itemName]; } } } $this->assign('tab', $tab); $this->assign('var', $varName); $this->assign('widget', $widgetName); $this->assign('file_id', $fileId); $this->assign('array_items', $items); $this->assign('array_item', $item); $this->assign('item_index', $itemIndex); return $this->fetch('file_array_data_edit'); } /** * 模板文件数组数据添加编辑提交保存 * @adminMenu( * 'name' => '模板文件数组数据添加编辑提交保存', * 'parent' => 'index', * 'display'=> false, * 'hasView'=> false, * 'order' => 10000, * 'icon' => '', * 'remark' => '模板文件数组数据添加编辑提交保存', * 'param' => '' * ) */ public function fileArrayDataEditPost() { $tab = $this->request->param('tab', 'widget'); $varName = $this->request->param('var'); $widgetName = $this->request->param('widget', ''); $fileId = $this->request->param('file_id', 0, 'intval'); $itemIndex = $this->request->param('item_index', ''); $file = Db::name('theme_file')->where(['id' => $fileId])->find(); if ($this->request->isPost()) { $post = $this->request->param(); $more = json_decode($file['more'], true); if ($tab == 'var') { foreach ($more['vars'] as $mVarName => $mVar) { if ($mVarName == $varName && $mVar['type'] == 'array') { if ($itemIndex === '') { if (!empty($mVar['value']) && is_array($mVar['value'])) { array_push($more['vars'][$mVarName]['value'], $post['item']); } else { $more['vars'][$mVarName]['value'] = [$post['item']]; } } else { if (!empty($mVar['value']) && is_array($mVar['value']) && isset($mVar['value'][$itemIndex])) { $more['vars'][$mVarName]['value'][$itemIndex] = $post['item']; } } break; } } } if ($tab == 'widget') { foreach ($more['widgets'] as $mWidgetName => $widget) { if ($widgetName == $mWidgetName) { if (!empty($widget['vars']) && is_array($widget['vars'])) { foreach ($widget['vars'] as $widgetVarName => $widgetVar) { if ($widgetVarName == $varName && $widgetVar['type'] == 'array') { if ($itemIndex === '') { if (!empty($widgetVar['value']) && is_array($widgetVar['value'])) { array_push($more['widgets'][$widgetName]['vars'][$widgetVarName]['value'], $post['item']); } else { $more['widgets'][$widgetName]['vars'][$widgetVarName]['value'] = [$post['item']]; } } else { if (!empty($widgetVar['value']) && is_array($widgetVar['value']) && isset($widgetVar['value'][$itemIndex])) { $more['widgets'][$widgetName]['vars'][$widgetVarName]['value'][$itemIndex] = $post['item']; } } break; } } } break; } } } $more = json_encode($more); Db::name('theme_file')->where(['id' => $fileId])->update(['more' => $more]); $this->success("保存成功!", url('theme/fileArrayData', ['tab' => $tab, 'var' => $varName, 'file_id' => $fileId, 'widget' => $widgetName])); } } /** * 模板文件数组数据删除 * @adminMenu( * 'name' => '模板文件数组数据删除', * 'parent' => 'index', * 'display'=> false, * 'hasView'=> false, * 'order' => 10000, * 'icon' => '', * 'remark' => '模板文件数组数据删除', * 'param' => '' * ) */ public function fileArrayDataDelete() { $tab = $this->request->param('tab', 'widget'); $varName = $this->request->param('var'); $widgetName = $this->request->param('widget', ''); $fileId = $this->request->param('file_id', 0, 'intval'); $itemIndex = $this->request->param('item_index', ''); if ($itemIndex === '') { $this->error('未指定删除元素!'); } $file = Db::name('theme_file')->where(['id' => $fileId])->find(); $more = json_decode($file['more'], true); if ($tab == 'var') { foreach ($more['vars'] as $mVarName => $mVar) { if ($mVarName == $varName && $mVar['type'] == 'array') { if (!empty($var['value']) && is_array($var['value']) && isset($var['value'][$itemIndex])) { array_splice($more['vars'][$mVarName]['value'], $itemIndex, 1); } else { $this->error('指定数据不存在!'); } break; } } } if ($tab == 'widget') { foreach ($more['widgets'] as $mWidgetName => $widget) { if ($mWidgetName == $widgetName) { if (!empty($widget['vars']) && is_array($widget['vars'])) { foreach ($widget['vars'] as $widgetVarName => $widgetVar) { if ($widgetVarName == $varName && $widgetVar['type'] == 'array') { if (!empty($widgetVar['value']) && is_array($widgetVar['value']) && isset($widgetVar['value'][$itemIndex])) { array_splice($more['widgets'][$widgetName]['vars'][$widgetVarName]['value'], $itemIndex, 1); } else { $this->error('指定数据不存在!'); } break; } } } break; } } } $more = json_encode($more); Db::name('theme_file')->where(['id' => $fileId])->update(['more' => $more]); $this->success("删除成功!", url('theme/fileArrayData', ['tab' => $tab, 'var' => $varName, 'file_id' => $fileId, 'widget' => $widgetName])); } /** * 模板文件编辑提交保存 * @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'); $post = $this->request->param(); $file = Db::name('theme_file')->field('theme,more')->where(['id' => $id])->find(); $more = json_decode($file['more'], true); if (isset($post['vars'])) { $messages = []; $rules = []; foreach ($more['vars'] as $mVarName => $mVar) { if (!empty($mVar['rule'])) { $rules[$mVarName] = $this->_parseRules($mVar['rule']); } if (!empty($mVar['message'])) { foreach ($mVar['message'] as $rule => $msg) { $messages[$mVarName . '.' . $rule] = $msg; } } if (isset($post['vars'][$mVarName])) { $more['vars'][$mVarName]['value'] = $post['vars'][$mVarName]; } if (isset($post['vars'][$mVarName . '_text_'])) { $more['vars'][$mVarName]['valueText'] = $post['vars'][$mVarName . '_text_']; } } $validate = new Validate($rules, $messages); $result = $validate->check($post['vars']); if (!$result) { $this->error($validate->getError()); } } if (isset($post['widget_vars'])) { foreach ($more['widgets'] as $mWidgetName => $widget) { if (empty($post['widget'][$mWidgetName]['display'])) { $widget['display'] = 0; } else { $widget['display'] = 1; } if (!empty($post['widget'][$mWidgetName]['title'])) { $widget['title'] = $post['widget'][$mWidgetName]['title']; } $messages = []; $rules = []; foreach ($widget['vars'] as $mVarName => $mVar) { if (!empty($mVar['rule'])) { $rules[$mVarName] = $this->_parseRules($mVar['rule']); } if (!empty($mVar['message'])) { foreach ($mVar['message'] as $rule => $msg) { $messages[$mVarName . '.' . $rule] = $msg; } } if (isset($post['widget_vars'][$mWidgetName][$mVarName])) { $widget['vars'][$mVarName]['value'] = $post['widget_vars'][$mWidgetName][$mVarName]; } if (isset($post['widget_vars'][$mWidgetName][$mVarName . '_text_'])) { $widget['vars'][$mVarName]['valueText'] = $post['widget_vars'][$mWidgetName][$mVarName . '_text_']; } } if ($widget['display']) { $validate = new Validate($rules, $messages); $widgetVars = empty($post['widget_vars'][$mWidgetName]) ? [] : $post['widget_vars'][$mWidgetName]; $result = $validate->check($widgetVars); if (!$result) { $this->error($widget['title'] . ':' . $validate->getError()); } } $more['widgets'][$mWidgetName] = $widget; } } $more = json_encode($more); Db::name('theme_file')->where(['id' => $id])->update(['more' => $more]); $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'=> true, * 'order' => 10000, * 'icon' => '', * 'remark' => '模板文件设置数据源', * 'param' => '' * ) */ public function dataSource() { $dataSource = $this->request->param('data_source'); $this->assign('data_source', $dataSource); $ids = $this->request->param('ids'); $selectedIds = []; if (!empty($ids)) { $selectedIds = explode(',', $ids); } if (empty($dataSource)) { $this->error('数据源不能为空!'); } $dataSource = json_decode(base64_decode($dataSource), true); if ($dataSource === null || !isset($dataSource['api'])) { $this->error('数据源格式不正确!'); } $filters = []; if (isset($dataSource['filters']) && is_array($dataSource['filters'])) { $filters = $dataSource['filters']; foreach ($filters as $key => $filter) { if ($filter['type'] == 'select' && !empty($filter['api'])) { $filterData = []; try { $filterData = action($filter['api'], [], 'api'); if (!is_array($filterData)) { $filterData = $filterData->toArray(); } } catch (\Exception $e) { } if (empty($filterData)) { $filters[$key] = null; } else { $filters[$key]['options'] = $filterData; } } } if (count($filters) > 3) { $filters = array_slice($filters, 0, 3); } } $vars = []; if ($this->request->isPost()) { $form = $this->request->param(); $vars[0] = $form; $this->assign('form', $form); } $items = action($dataSource['api'], $vars, 'api'); if ($items instanceof \think\Collection) { $items = $items->toArray(); } $multi = empty($dataSource['multi']) ? false : $dataSource['multi']; foreach ($items as $key => $item) { if (empty($item['parent_id'])) { $item['parent_id'] = 0; } $item['checked'] = in_array($item['id'], $selectedIds) ? 'checked' : ''; $items[$key] = $item; } $tree = new Tree(); $tree->init($items); $tpl = "<tr class='data-item-tr'> <td> <input type='radio' class='js-select-box' name='ids[]' value='\$id' data-name='\$name' \$checked> </td> <td>\$id</td> <td>\$spacer \$name</td> </tr>"; if ($multi) { $tpl = "<tr class='data-item-tr'> <td> <input type='checkbox' class='js-check js-select-box' data-yid='js-check-y' data-xid='js-check-x' name='ids[]' value='\$id' data-name='\$name' \$checked> </td> <td>\$id</td> <td>\$spacer \$name</td> </tr>"; } $itemsTree = $tree->getTree(0, $tpl); $this->assign('multi', $multi); $this->assign('items_tree', $itemsTree); $this->assign('selected_ids', $selectedIds); $this->assign('filters', $filters); return $this->fetch(); } }