From 17ff18da78c7a3b0140aab04cbb9013395c6eda3 Mon Sep 17 00:00:00 2001 From: filesite Date: Wed, 8 May 2024 09:41:08 +0000 Subject: [PATCH] tag manage done --- lib/DirScanner.php | 24 ++- .../tajian/controller/FrontapiController.php | 143 +++++++++++++++++- themes/tajian/controller/SiteController.php | 86 ++++++++++- themes/tajian/views/my/tags.php | 9 +- www/js/tajian.js | 32 +++- 5 files changed, 278 insertions(+), 16 deletions(-) diff --git a/lib/DirScanner.php b/lib/DirScanner.php index d5e95d6..bb16294 100644 --- a/lib/DirScanner.php +++ b/lib/DirScanner.php @@ -285,10 +285,10 @@ Class DirScanner { //try to find the md file $targetFile = ''; - $targetFile_md = preg_replace('/_?[a-z0-9]+\.txt$/iU', '.md', $realpath); - $targetFile_mp4 = preg_replace('/_?[a-z0-9]+\.txt$/iU', '.mp4', $realpath); - $targetFile_m3u8 = preg_replace('/_?[a-z0-9]+\.txt$/iU', '.m3u8', $realpath); - $targetFile_url = preg_replace('/_?[a-z0-9]+\.txt$/iU', '.url', $realpath); + $targetFile_md = preg_replace('/_?[a-z0-9]+\.txt$/U', '.md', $realpath); + $targetFile_mp4 = preg_replace('/_?[a-z0-9]+\.txt$/U', '.mp4', $realpath); + $targetFile_m3u8 = preg_replace('/_?[a-z0-9]+\.txt$/U', '.m3u8', $realpath); + $targetFile_url = preg_replace('/_?[a-z0-9]+\.txt$/U', '.url', $realpath); if (file_exists($targetFile_md)) { $targetFile = $targetFile_md; }else if (file_exists($targetFile_mp4)) { @@ -299,7 +299,7 @@ Class DirScanner { $targetFile = $targetFile_url; } - if (!empty($targetFile)) { + if (!empty($targetFile) && $targetFile != $realpath) { $fileId = $this->getId($targetFile); if (empty($this->scanResults[$fileId])) { $ext['id'] = $fileId; @@ -312,7 +312,7 @@ Class DirScanner { } }else { //try to merge to the parent directory - $targetDir = preg_replace('/\/[a-z0-9]+\.txt$/i', '', $realpath); + $targetDir = preg_replace('/\/[a-z0-9]+\.txt$/U', '', $realpath); if (is_dir($targetDir)) { $dirId = $this->getId($targetDir); if (empty($this->scanResults[$dirId])) { @@ -324,6 +324,18 @@ Class DirScanner { $data = array_merge($data, $ext); $this->scanResults[$dirId] = $data; } + }else { + //keep it in files + $fileId = $this->getId($realpath); + if (empty($this->scanResults[$fileId])) { + $ext['id'] = $fileId; + $this->scanResults[$fileId] = $ext; + $data = $ext; + }else { + $data = $this->scanResults[$fileId]; + $data = array_merge($data, $ext); + $this->scanResults[$fileId] = $data; + } } } diff --git a/themes/tajian/controller/FrontapiController.php b/themes/tajian/controller/FrontapiController.php index db3abf6..7f77852 100644 --- a/themes/tajian/controller/FrontapiController.php +++ b/themes/tajian/controller/FrontapiController.php @@ -712,9 +712,150 @@ eof; return $this->renderJson(compact('code', 'msg', 'err')); } + //分类管理 + public function actionSavetags() { + $ip = $this->getUserIp(); + $check_time = 120; //2 分钟内 + $max_time_in_minutes = 10; //最多 10 次 + + $isUserGotRequestLimit = $this->requestLimit($ip, $max_time_in_minutes, $check_time); + if ($isUserGotRequestLimit) { + $this->logError("Request limit got, ip: {$ip}"); + throw new Exception('Oops,操作太快了,请喝杯咖啡休息会吧...'); + } + + //只允许修改自己的数据 + $loginedUser = Common::getUserFromSession(); + if (empty($loginedUser['username'])) { + throw new Exception('Oops,你还没登录哦'); + }else if ( + !empty(FSC::$app['config']['multipleUserUriParse']) + && (empty(FSC::$app['user_id']) || FSC::$app['user_id'] != $loginedUser['username']) + ) { + throw new Exception('Oops,请求地址有误'); + } + + + //返回给视图的变量 + $code = 0; + $msg = ''; + $err = ''; + + //用户提交的数据检查 + $postParams = $this->post(); + if (!empty($postParams)) { + $tags = $this->post('tags', ''); + + if (empty($tags)) { + $err = "请至少保留一个分类"; + }else { + $tags_ok = array(); + foreach($tags as $index => $tag) { + $tag = Common::cleanSpecialChars($tag); + if (!empty($tag) && !is_numeric($tag)) { + array_push($tags_ok, mb_substr($tag, 0, 5, 'utf-8')); + } + } + + if (empty($tags_ok)) { + $err = "请按规则填写分类:2 - 5 个汉字、数字、英文字符"; + }else { + $tags = $tags_ok; + } + } + + if (empty($err)) { //如果数据检查通过,尝试保存 + //获取已有的分类 + $scanner = new DirScanner(); + $scanner->setWebRoot(FSC::$app['config']['content_directory']); + $dirTree = $scanner->scan(__DIR__ . '/../../../www/' . FSC::$app['config']['content_directory'], 3); + + $menus_sorted = array(); //Readme_sort.txt 说明文件内容,一级目录菜单从上到下的排序 + $readmeFile = $scanner->getDefaultReadme(); + if (!empty($readmeFile)) { + if (!empty($readmeFile['sort'])) { + $menus_sorted = explode("\n", $readmeFile['sort']); + } + } - //TODO: 分类管理 + //获取tags分类 + $tags_current = $this->getTags($dirTree); + //排序 + if (!empty($menus_sorted) && !empty($tags_current)) { + $tags_current = $this->sortTags($menus_sorted, $tags_current); + } + //获取只包含分类名的数组 + $tmp_arr = array(); + foreach ($tags_current as $id => $tag) { + array_push($tmp_arr, $tag['name']); + } + //保存 + $saved = $this->saveTags($tags, $tmp_arr); + if (!empty($saved)) { + $msg = "分类已保存"; + $code = 1; + }else { + $err = '分类保存失败,请稍后重试'; + } + } + } + + return $this->renderJson(compact('code', 'msg', 'err')); + } + + //删除管理 + public function actionDeletetag() { + $ip = $this->getUserIp(); + $check_time = 120; //2 分钟内 + $max_time_in_minutes = 10; //最多 10 次 + + $isUserGotRequestLimit = $this->requestLimit($ip, $max_time_in_minutes, $check_time); + if ($isUserGotRequestLimit) { + $this->logError("Request limit got, ip: {$ip}"); + throw new Exception('Oops,操作太快了,请喝杯咖啡休息会吧...'); + } + + //只允许修改自己的数据 + $loginedUser = Common::getUserFromSession(); + if (empty($loginedUser['username'])) { + throw new Exception('Oops,你还没登录哦'); + }else if ( + !empty(FSC::$app['config']['multipleUserUriParse']) + && (empty(FSC::$app['user_id']) || FSC::$app['user_id'] != $loginedUser['username']) + ) { + throw new Exception('Oops,请求地址有误'); + } + + + //返回给视图的变量 + $code = 0; + $msg = ''; + $err = ''; + + //用户提交的数据检查 + $postParams = $this->post(); + if (!empty($postParams)) { + $tag_to_delete = $this->post('tag', ''); + + if (empty($tag_to_delete)) { + $err = "参数错误,缺少tag传参"; + } + + if (empty($err)) { //如果数据检查通过,尝试保存 + //保存 + $saved = $this->deleteTag($tag_to_delete); + if (!empty($saved)) { + $msg = "分类已删除"; + $code = 1; + }else { + $err = '分类删除失败,请稍后重试'; + } + } + } + + return $this->renderJson(compact('code', 'msg', 'err')); + } //TODO: 视频管理 diff --git a/themes/tajian/controller/SiteController.php b/themes/tajian/controller/SiteController.php index bf293dd..cb2ebec 100644 --- a/themes/tajian/controller/SiteController.php +++ b/themes/tajian/controller/SiteController.php @@ -30,7 +30,7 @@ Class SiteController extends Controller { $scanner = new DirScanner(); $scanner->setWebRoot(FSC::$app['config']['content_directory']); - $dirTree = $scanner->scan(__DIR__ . '/../../../www/' . FSC::$app['config']['content_directory'], 4); + $dirTree = $scanner->scan(__DIR__ . '/../../../www/' . FSC::$app['config']['content_directory'], 3); $scanResults = $scanner->getScanResults(); //获取目录 @@ -129,7 +129,7 @@ Class SiteController extends Controller { }else { $tag['name'] = $name; if ($noFiles == false) { - $tag['files'] = explode("\n", $item); + $tag['files'] = !empty($item) ? explode("\n", trim($item)) : array(); } } } @@ -167,6 +167,86 @@ Class SiteController extends Controller { return $files; } + //保存分类,如果tag是纯英文,则自动把首字母改为大写 + //@tags 新分类数组 + //@tags_current 当前分类数组 + protected function saveTags($tags, $tags_current) { + $done = false; + + try { + $rootDir = FSC::$app['config']['content_directory']; + $tagSaveDirName = str_replace('/', '', FSC::$app['config']['tajian']['tag_dir']); + + //添加新分类 + foreach ($tags as $index => $tag) { + //首字母转大写 + $tag = ucfirst($tag); + $tags[$index] = $tag; + + if (in_array($tag, $tags_current)) {continue;} //忽略已存在的分类 + + $tagFile = "{$rootDir}{$tagSaveDirName}/{$tag}.txt"; + if (file_exists($tagFile) == false) { //添加新分类 + touch($tagFile); + } + } + + //删除或者改名新分类中被移除的老分类 + foreach ($tags_current as $index => $tag) { + if (in_array($tag, $tags)) {continue;} //跳过新分类中保留的 + + $tagFile = "{$rootDir}{$tagSaveDirName}/{$tag}.txt"; + if (file_exists($tagFile)) { + if (!empty($tags[$index])) { + $newTagFile = "{$rootDir}{$tagSaveDirName}/{$tags[$index]}.txt"; + rename($tagFile, $newTagFile); + }else { + unlink($tagFile); + } + } + } + + //更新排序文件 + $sortFile = "{$rootDir}README_sort.txt"; + file_put_contents($sortFile, implode("\n", $tags)); + + $done = true; + }catch(Exception $e) { + $this->logError('Save tags failed: ' . $e->getMessage()); + } + + return $done; + } + + //删除分类 + protected function deleteTag($tag) { + $done = false; + + try { + $rootDir = FSC::$app['config']['content_directory']; + $tagSaveDirName = str_replace('/', '', FSC::$app['config']['tajian']['tag_dir']); + + $tagFile = "{$rootDir}{$tagSaveDirName}/{$tag}.txt"; + if (file_exists($tagFile)) { + unlink($tagFile); + } + + //更新排序文件 + $sortFile = "{$rootDir}README_sort.txt"; + if (file_exists($sortFile)) { + $content = file_get_contents($sortFile); + $content = preg_replace("/{$tag}\n?/", '', $content); + file_put_contents($sortFile, $content); + } + + $done = true; + }catch(Exception $e) { + $this->logError("Delete tag {$tag} failed: " . $e->getMessage()); + } + + return $done; + } + protected function getNickname($readmeFile) { $nickname = ''; @@ -216,7 +296,7 @@ Class SiteController extends Controller { $scanner = new DirScanner(); $scanner->setWebRoot(FSC::$app['config']['content_directory']); - $dirTree = $scanner->scan(__DIR__ . '/../../../www/' . FSC::$app['config']['content_directory'], 4); + $dirTree = $scanner->scan(__DIR__ . '/../../../www/' . FSC::$app['config']['content_directory'], 3); $scanResults = $scanner->getScanResults(); $titles = array(); diff --git a/themes/tajian/views/my/tags.php b/themes/tajian/views/my/tags.php index ff044be..fb94e59 100644 --- a/themes/tajian/views/my/tags.php +++ b/themes/tajian/views/my/tags.php @@ -17,7 +17,7 @@ if (!empty(FSC::$app['config']['multipleUserUriParse']) && !empty(FSC::$app['use foreach($viewData['tags'] as $id => $tag) { $upIconCls = $index == 0 ? 'hide' : ''; $downIconCls = $index < $tagsTotal - 1 ? '' : 'hide'; - + $index ++; echo << @@ -31,6 +31,13 @@ eof; } ?> +

+ 说明: +
+ 分类名请填 2 - 5 个汉字、数字、英文字符; +
+ 点击上下箭头图标改变分类顺序,删除某个分类并不会删除这个分类里的视频。 +