123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- <?php
- /**
- * Created by PhpStorm.
- * User: Administrator
- * Date: 2022/1/12
- * Time: 14:15
- */
- namespace app\common\service;
- use app\common\model\Article;
- use app\common\model\ArticleCate;
- use app\common\model\Catalog;
- use app\common\model\Templet;
- use app\common\model\Webconfig;
- use file\DirHelper;
- use file\FileHelper;
- use file\PathHelper;
- use paginate\Bootstrap;
- use think\Controller;
- use think\Log;
- use think\Request;
- class CmsService extends Controller
- {
- /**
- * 输出调试信息
- * @param $msg
- */
- public function info($msg)
- {
- if ($this->request->isCli()) {
- echo $msg . PHP_EOL;
- } else {
- Log::log($msg);
- }
- }
- /**
- * 记录错误信息日志
- * @param $e \Exception
- */
- public static function errorlog($e)
- {
- Log::error("异常信息:" . $e->getMessage());
- Log::error('请求数据:' . var_export(Request::instance()->param(), true));
- Log::error($e->getTraceAsString());
- }
- /**
- * 输出错误页面
- * @param $basePath
- * @return string
- */
- public static function errorHtml($basePath)
- {
- $basePath = str_replace(Templet::getRootDir(), '', $basePath);
- return "<html><head><meta charset=\"utf-8\"></head><body>" . $basePath . ",此栏目下没有文章,请添加文章后再尝试生成</body></html>";
- }
- /**
- * 替换预览内容
- * @return array
- */
- public static function getArticlePerViewReplace()
- {
- return [
- '_UPLOADS_' => '/uploads/q1464674022',
- '_ROOT_' => '/?path=',
- ];
- }
- /**
- * 替换生成内容
- * @return array
- */
- public static function getArticleReplace()
- {
- return [
- '_UPLOADS_' => '',
- '_ROOT_' => '',
- ];
- }
- /**
- * 导出上传目录
- */
- public function copyUploads()
- {
- //创建目录
- $destPath = Templet::getRootDir() . 'uploads';
- DirHelper::makeDir($destPath);
- $this->info("导出上传目录" . $destPath);
- $path = Templet::UPLOAD_PATH . 'admin';
- if (file_exists($path)) {
- DirHelper::copyDir($path, $destPath . DS . 'admin', false);//不覆盖同名文件
- }
- $path = Templet::UPLOAD_PATH . 'ueditor';
- if (file_exists($path)) {
- DirHelper::copyDir($path, $destPath . DS . 'ueditor', false);//不覆盖同名文件
- }
- //导出模板文件
- // $path = APP_PATH . 'admin' . DS . 'view' . DS . 'q1464674022';
- // if (file_exists($path)) {
- // copyDir($path, $destPath . DS . 'template');
- // }
- }
- /**
- * 执行文件生成
- * @param $filePath
- * @param $content
- */
- public function createFile($filePath, $content)
- {
- if (!ifContain($filePath, Templet::getRootDir())) {
- return;//不允许执行外部路径
- }
- if ($this->request->has('delete')) {
- if (file_exists($filePath)) {
- unlink($filePath);//删除
- }
- } elseif ($this->request->has('cover')) {
- FileHelper::save($filePath, $content);//覆盖
- } else {
- //默认不覆盖,文件不存在或内容修改才覆盖
- if (!file_exists($filePath)) {
- FileHelper::save($filePath, $content);
- } else {
- $change = str_replace(file_get_contents($filePath), '', $content);
- if (!empty($change)) {
- FileHelper::save($filePath, $content);
- }
- }
- }
- }
- /**
- * 分页url处理
- * @param $catalog
- * @param $tid
- * @return mixed
- */
- public static function getPaginatePath($catalog, $tid)
- {
- $rule = str_replace("{page}", "[PAGE]", $catalog->articlelist_rule);
- return replaceUrlDS(ArticleCate::getRulePath($catalog->path, $rule, $catalog->id, $tid));
- }
- /**
- * 栏目预览
- * @param $catalog Catalog
- * @param $cate ArticleCate
- * @param int $page
- * @return mixed|string
- */
- public function perviewCatalog($catalog, $cate = null, $page = 1)
- {
- $tid = $cate ? $cate->id : 0;
- if ($catalog) {
- try {
- $replace = self::getArticlePerViewReplace();
- //先预览静态文件
- // $filepath = Templet::getRootDir() . $catalog->getUri();
- // if (file_exists($filepath) && ifContain($filepath, '.html')) {
- // return $this->fetch($filepath, [], $replace);
- // }
- //全局对象
- $cataLogModel = new Catalog();
- $articleModel = new Article();
- $articleCateModel = new ArticleCate();
- $this->assign([
- 'cataLogModel' => $cataLogModel,
- 'articleCateModel' => $articleCateModel,
- 'articleModel' => $articleModel,
- ]);
- if ($catalog->type == Catalog::TYPE_CATALOG) {
- return $this->fetch($catalog->getCatalogTemplet()->getRealPath(), ['catalog' => $catalog], $replace);
- } elseif ($catalog->type == Catalog::TYPE_ARTICLE_LIST) {
- if ($catalog->article_cate_count > 0) {
- $where = [
- 'article_cate_id' => $tid,
- 'status' => $articleModel::STATUS_OPEN,
- ];
- } else {
- $where = [
- 'catalog_id' => $catalog->id,
- 'status' => $articleModel::STATUS_OPEN,
- ];
- }
- $total = $articleModel->where($where)->where($catalog->articlelist_where)->count();
- $listRows = $catalog->articlelist_rows??10;//分页
- $orderby = $catalog->articlelist_sort??'create_time desc';//排序
- $prefix = isset($replace['_ROOT_']) ? $replace['_ROOT_'] : '_ROOT_';
- $articleList = $articleModel->where($where)->where($catalog->articlelist_where)->page($page, $listRows)->order($orderby)->select();
- $paginate = new Bootstrap($articleList, $listRows, $page, $total, false, ["path" => $prefix . self::getPaginatePath($catalog, $tid)]);
- return $this->fetch($catalog->getCatalogTemplet()->getRealPath(), ['catalog' => $catalog, 'articleCate' => $cate, 'paginate' => $paginate], $replace);
- }
- return "";
- } catch (\Exception $e) {
- $this->error('预览失败:' . $e->getMessage());
- }
- }
- abort(404, "预览失败:catelog is null");
- }
- /**
- * 分类预览
- * @param $articleCate ArticleCate
- * @param int $page
- * @return mixed|string
- */
- public function perviewArticleCate($articleCate, $page = 1)
- {
- if ($articleCate) {
- try {
- //先预览静态文件
- // $filepath = Templet::getRootDir() . $articleCate->getUri();
- // if (file_exists($filepath)) {
- // return $this->fetch($filepath, [], $replace);
- // }
- $catalog = $articleCate->getFirstCatalog();
- return $this->perviewCatalog($catalog, $articleCate, $page);
- } catch (\Exception $e) {
- $this->error('预览失败:' . $e->getMessage());
- }
- }
- abort(404, "预览失败:articleCate is null");
- }
- /**
- * 文章预览
- * @param $article Article
- * @return mixed
- */
- public function perviewArticle($article)
- {
- if ($article) {
- try {
- $replace = self::getArticlePerViewReplace();
- //先预览静态文件
- // $filepath = Templet::getRootDir() . $article->getUri();
- // if (file_exists($filepath) && ifContain($filepath, '.html')) {
- // return $this->fetch($filepath, [], $replace);
- // }
- //全局对象
- $cataLogModel = new Catalog();
- $articleModel = new Article();
- $articleCateModel = new ArticleCate();
- $this->assign([
- 'cataLogModel' => $cataLogModel,
- 'articleCateModel' => $articleCateModel,
- 'articleModel' => $articleModel,
- ]);
- $catalog = $article->catalog_id ? $article->catalog : $article->getFirstCatalog();
- $cate = $article->catalog_id ? null : $article->cate;
- /** @var Catalog $catalog */
- return $this->fetch($catalog->getArticleTemplet()->getRealPath(), ['catalog' => $catalog, 'article' => $article, 'articleCate' => $cate], $replace);
- } catch (\Exception $e) {
- $this->error('预览失败:' . $e->getMessage());
- }
- }
- abort(404, "预览失败:article is null");
- }
- /**
- * 预览网站静态文件
- * @return string
- */
- public function perviewHtmlSite()
- {
- if ($this->request->has('path')) {
- $filepath = Templet::getRootDir() . $this->request->get('path');
- if (!ifContain($filepath, '.html')) {
- $filepath .= DS . 'index.html';
- }
- } else {
- $filepath = Templet::getRootDir() . 'index.html';
- }
- if (file_exists($filepath)) {
- $replace = self::getArticlePerViewReplace();
- $html = $this->fetch($filepath, [], $replace);
- //todo auto replace assets path
- exit($html);
- } else {
- if ($this->request->has('path'))
- abort(404);
- }
- }
- /**
- * 预览网站模板
- */
- public function perviewSite()
- {
- $path = $this->request->get('path', '/index.html');
- if (!ifContain($path, '.html')) {
- $path .= '/index.html';
- }
- $path = str_replace('//', '/', appendStartDS($path, '/'));
- $catalogModel = new Catalog();
- $catalog = $catalogModel->where('path', $path)->find();
- if ($catalog) {
- exit($this->perviewCatalog($catalog));
- }
- $path = deleteStartDS($path, '/');
- $catalogs = $catalogModel->field('article_rule,articlelist_rule')->distinct(true)->where('article_rule', '<>', '')->select();
- foreach ($catalogs as $catalog) {
- $matches = $this->matchePath($catalog->article_rule, $path);
- if ($matches) {
- if (isset($matches['{aid}'])) {
- $article = Article::get($matches['{aid}']);
- exit($this->perviewArticle($article));
- }
- }
- $matches = $this->matchePath($catalog->articlelist_rule, $path);
- if ($matches) {
- if (isset($matches['{tid}'])) {
- $articlecate = (new ArticleCate())->where('id', $matches['{tid}'])->find();
- } elseif (isset($matches['{tpath}'])) {
- $articlecate = (new ArticleCate())->where('en_name', $matches['{tpath}'])->find();
- } else {
- continue;
- }
- $page = $matches['{page}'] ?? 1;
- exit($this->perviewArticleCate($articlecate, $page));
- }
- }
- }
- /**
- * 解析path
- * @param $rule
- * @param $path
- * @return mixed
- */
- private function matchePath($rule, $path)
- {
- $rule_arr = explode('/', $rule);
- $path_arr = explode('/', $path);
- if (ifContain($path, 'index.html')) {
- array_pop($rule_arr);
- array_pop($path_arr);
- $rule = implode('/', $rule_arr);
- $path = implode('/', $path_arr);
- }
- $pattern2p = str_replace(['/', '{cpath}', '{tpath}', '{Y}', '{M}', '{D}', '{aid}', '{page}', '{cid}', '{tid}'], ['\/', '(.*?)', '(.*?)', '(\d{4})', '(\d{2})', '(\d{2})', '(\d*?)', '(\d*?)', '(\d*?)', '(\d*?)'], $rule);
- $pattern2r = str_replace(['/', '{cpath}', '{tpath}', '{Y}', '{M}', '{D}', '{aid}', '{page}', '{cid}', '{tid}'], ['\/', '({cpath})', '({tpath})', '({Y})', '({M})', '({D})', '({aid})', '({page})', '({cid})', '({tid})'], $rule);
- if (preg_match('/^' . $pattern2p . '$/', $path, $matches2p)) {
- if (preg_match('/^' . $pattern2r . '$/', $rule, $matches2r)) {
- $res = [];
- foreach ($matches2r as $i => $item) {
- if ($i > 0)
- $res[$item] = $matches2p[$i];
- }
- return $res;
- }
- }
- }
- }
|