docsdata = Service::getDocsData(false); $config = get_addon_config('docs'); $this->typeList = $this->typeColor = []; $langs = $config['lang']; $colors = ["primary", "success", "danger", "warning", "info"]; foreach ($this->docsdata as $type => $pages) { $this->typeList[$type] = $langs[$type] ?? $type; $this->typeColor[$type] = array_pop($colors); } $this->view->assign('typeList', $this->typeList); $this->assignconfig('typeList', $this->typeList); $this->view->assign('typeColor', $this->typeColor); $this->assignconfig('typeColor', $this->typeColor); $this->assignconfig('htmlDetect', (bool)($config['htmldetect'] ?? false)); } /** * 查看 */ public function index() { //设置过滤方法 $this->request->filter(['strip_tags']); if ($this->request->isAjax()) { $filter = $this->request->request('filter', ''); $filter = (array)json_decode($filter, true); $filter['type'] = isset($filter['type']) && $filter['type'] ? $filter['type'] : ''; $search = $this->request->request("search"); list($where, $sort, $order, $offset, $limit) = $this->buildparams(); $list = []; $docsdata = $this->docsdata; if ($filter['type']) { $docsdata = isset($docsdata[$filter['type']]) ? [$filter['type'] => $docsdata[$filter['type']]] : []; } foreach ($docsdata as $index => $docsdatum) { $tree = Tree::instance(); $data = $tree->init($docsdatum, 'parent')->getTreeArray(''); $list = array_merge($list, $tree->getTreeList($data, 'title')); } $ids = []; foreach ($list as $index => $item) { $ids[] = $item['id']; } foreach ($docsdata as $index => $docsdatum) { foreach ($docsdatum as $key => $item) { if (!in_array($item['id'], $ids)) { $list[] = $item; } } } //foreach ($this->docsdata as $type => $pages) { // if ($filter['type'] && $type != $filter['type']) { // continue; // } // foreach ($pages as $index => $page) { // if (!$search || stripos($page['relative'], $search) !== false || stripos($page['title'], $search) !== false) { // $list[] = $page; // } // } //} $total = count($list); $result = array("total" => $total, "rows" => array_slice($list, $offset, $limit)); return json($result); } return $this->view->fetch(); } /** * 添加 */ public function add() { if ($this->request->isPost()) { $params = $this->request->post("row/a"); if ($params) { try { if (!$params['md']) { throw new Exception("MD文件不能为空"); } $config = get_addon_config('docs'); $params['md'] = trim($params['md']); //未设置后缀 if (stripos($params['md'], ".{$config['suffix']}") === false) { $params['md'] .= ".{$config['suffix']}"; } if (mb_substr_count($params['md'], "/") > 1) { throw new Exception("MD文件中只能包含一个/字符"); } if (mb_substr_count($params['md'], ".") > 1) { throw new Exception("MD文件中只能包含一个.字符"); } if (!Validate::is($params['md'], "/^[A-Za-z0-9\-\_\.\/]+$/")) { throw new Exception("MD文件只能是字母数字下划线"); } $exist = Service::getMarkdownData($params['md']); if ($exist) { throw new Exception("对应的MD文件已经存在"); } $parent = $params['parent'] ?? ''; $type = $params['type'] ?? ''; if ($parent) { if ($parent == str_replace(".md", "", $params['md'])) { $this->error("父级不能为当前文件"); } if (!isset($this->docsdata[$type])) { $this->error("未找到指定分类"); } $nameArr = []; foreach ($this->docsdata[$type] as $index => $docsdatum) { $nameArr[] = $docsdatum['name']; } if (!in_array($parent, $nameArr)) { $this->error("未找到指定父级数据"); } } Service::setMarkdownData($params['md'], $params); } catch (Exception $e) { $this->error($e->getMessage()); } $this->success(); } $this->error(__('Parameter %s can not be empty', '')); } return $this->view->fetch(); } /** * 编辑 */ public function edit($ids = null) { $ids = $ids ? $ids : $this->request->request('ids'); $row = Service::getMarkdownData($ids, true, false); if (!$row) { $this->error(__('No Results were found')); } if ($this->request->isPost()) { $params = $this->request->post("row/a"); if ($params) { $config = get_addon_config('docs'); $params['md'] = trim(isset($params['md']) && $params['md'] ? $params['md'] : $row['relative']); $md = $params['md']; $parent = $params['parent'] ?? ''; $type = $params['type'] ?? ''; if ($parent) { if ($parent == str_replace(".md", "", $ids)) { $this->error("父级不能为当前文件"); } if (!isset($this->docsdata[$type])) { $this->error("未找到指定分类"); } $nameArr = []; foreach ($this->docsdata[$type] as $index => $docsdatum) { $nameArr[] = $docsdatum['name']; } if (!in_array($parent, $nameArr)) { $this->error("未找到指定父级数据"); } } //如果文件名有变更,删除原文件 if ($md != $row['relative']) { //未设置后缀 if (stripos($params['md'], ".{$config['suffix']}") === false) { $params['md'] .= ".{$config['suffix']}"; } if (mb_substr_count($params['md'], "/") > 1) { throw new Exception("MD文件中只能包含一个/字符"); } if (mb_substr_count($params['md'], ".") > 1) { throw new Exception("MD文件中只能包含一个.字符"); } if (!Validate::is($params['md'], "/^[A-Za-z0-9\-\_\.\/]+$/")) { throw new Exception("MD文件只能是字母数字下划线"); } $exist = Service::getMarkdownData($params['md']); if ($exist) { throw new Exception("对应的MD文件已经存在"); } } try { //如果变更了分类,则所有子文档分类都需要变更 if ($type != $row['type']) { $docs = $this->docsdata[$row['type']] ?? []; $childrenList = Tree::instance()->init($docs, 'parent')->getChildren($row['id']); foreach ($childrenList as $index => $item) { $data = Service::getMarkdownData($item['relative'], true); $data['type'] = $type; Service::setMarkdownData($item['relative'], $data); } } Service::setMarkdownData($md, $params); //如果文件名有变更,删除原文件 if ($md != $row['relative']) { unlink(Service::getDocsSourceDir() . $row['relative']); } } catch (Exception $e) { $this->error($e->getMessage()); } $this->success(); } $this->error(__('Parameter %s can not be empty', '')); } $allowEditName = true; $parentList = isset($this->docsdata[$row['type']]) ? $this->docsdata[$row['type']] : []; foreach ($parentList as $index => $item) { if ($item['parent'] == $row['name']) { $allowEditName = false; break; } } $parentOptions = $this->getParentList($row['type'], $row['id'], $row['parent']); $this->view->assign("parentOptions", $parentOptions); $this->view->assign("allowEditName", $allowEditName); $this->view->assign("row", $row); return $this->view->fetch(); } /** * 删除 */ public function del($ids = "") { if (!$this->request->isPost()) { $this->error(__("Invalid parameters")); } $ids = $ids ? $ids : $this->request->post("ids"); if ($ids) { if (stripos($ids, ',') !== false) { $this->error("文档不支持批量删除"); } $row = Service::getMarkdownData($ids, false, false); if (!$row) { $this->error(__('No Results were found')); } try { unlink(Service::getDocsSourceDir() . $row['relative']); Service::refreshDocsData(); } catch (Exception $e) { $this->error($e->getMessage()); } $this->success(); } $this->error(__('Parameter %s can not be empty', 'ids')); } /** * 刷新 */ public function refresh() { Service::refreshDocsData(); $this->success(); } /** * 导出 */ public function export() { try { //重新生成一次文档 Service::build(); } catch (\Exception $e) { $this->error($e->getMessage()); } $distDir = Service::getDocsDistDir(); $zipFile = RUNTIME_PATH . 'addons' . DS . 'export-docs-' . date('YmdHis') . '.zip'; $rootPath = realpath($distDir); $zip = new ZipArchive(); $zip->open($zipFile, ZipArchive::CREATE | ZipArchive::OVERWRITE); $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($rootPath), RecursiveIteratorIterator::LEAVES_ONLY ); foreach ($files as $name => $file) { if (!$file->isDir()) { $filePath = $file->getRealPath(); $relativePath = substr($filePath, strlen($rootPath) + 1); $relativePath = str_replace('\\', '/', $relativePath); $zip->addFile($filePath, $relativePath); } } $zip->close(); Http::sendToBrowser($zipFile); } /** * 批量更新 * @internal */ public function status($ids = "") { $ids = $ids ? $ids : $this->request->param("ids"); if ($ids) { if ($this->request->has('params')) { parse_str($this->request->post("params"), $values); if ($values && isset($values['isnew'])) { $row = Service::getMarkdownData($ids, true, false); $row = array_merge($row, $values); try { Service::setMarkdownData($ids, $row); } catch (Exception $e) { $this->error($e->getMessage()); } $this->success(); } else { $this->error(__('You have no permission')); } } } $this->error(__('Parameter %s can not be empty', 'ids')); } /** * 批量更新 * @internal */ public function multi($ids = "") { return; } /** * 动态下拉选择类型 * @internal */ public function selectpage_type() { $list = []; $word = (array)$this->request->request("q_word/a"); $field = $this->request->request('showField'); $keyValue = $this->request->request('keyValue'); $config = get_addon_config('docs'); $typeList = []; $langs = $config['lang']; foreach ($this->docsdata as $type => $pages) { $typeList[$type] = isset($langs[$type]) ? $langs[$type] : $type; } $typeArr = $typeList; if (!$keyValue) { if (array_filter($word)) { foreach ($word as $k => $v) { $list[] = ['id' => $v, $field => $v]; } } foreach ($typeArr as $index => $item) { $list[] = ['id' => $index, $field => $item]; } } else { $list[] = ['id' => $keyValue, $field => $typeArr[$keyValue] ?? $keyValue]; } return json(['total' => count($list), 'list' => $list]); } /** * 获取父级options * @internal */ public function get_parent_options() { $type = $this->request->request('type'); $origintype = $this->request->request('origintype'); $id = $parent = null; if ($type == $origintype) { $id = $this->request->request('id'); $parent = $this->request->request('parent'); } $parentOptions = ''; if ($type) { $parentOptions .= $this->getParentList($type, $id, $parent); } $this->success("", '', ['options' => $parentOptions]); } protected function getParentList($type, $id = null, $parent = null) { $parentList = []; $parentOptions = ''; if (!isset($this->docsdata[$type])) { return $parentOptions; } foreach ($this->docsdata[$type] as $index => $item) { $parentList[] = ['id' => $item['id'], 'pid' => $item['parent'], 'name' => $item['title']]; } if ($parentList) { $tree = Tree::instance()->init($parentList); $disableIds = $id ? $tree->getChildrenIds($id, true) : []; $selectIds = $parent ? [$parent] : []; $parentOptions = $tree->getTree('', '', $selectIds, $disableIds); } return $parentOptions; } }