Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 601|回复: 0

thinkcmf5更新模板代码分析,解决模板配置json出错导致数据库保存的配置项内容丢失问题

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-9-5 15:37:06 | 显示全部楼层 |阅读模式
     private function updateThemeFiles($theme, $suffix = 'html')
        {
            $dir                = 'themes/' . $theme; $themeDir = $dir; $tplFiles = []; $root_dir_tpl_files = cmf_scan_dir("$dir/*.$suffix"); //默认情况下返回 模板目录(w0s目录)下的所有html文件名数组 foreach ($root_dir_tpl_files as $root_tpl_file) { $root_tpl_file = "$dir/$root_tpl_file"; $configFile = preg_replace("/\.$suffix$/", '.json', $root_tpl_file); //获取当前$root_tpl_file对应json文件名 例如 index.json $root_tpl_file_no_suffix = preg_replace("/\.$suffix$/", '', $root_tpl_file); //获取对应文件名无后缀 if (is_file($root_tpl_file) && file_exists_case($configFile)) { //当前$root_tpl_file(例如:index.html)是个文件,并且index.json存在 array_push($tplFiles, $root_tpl_file_no_suffix); //把文件名存起来,不包含后缀。例如:index } } $subDirs = cmf_sub_dirs($dir); //子目录下文件,是不是只支持两级目录???? foreach ($subDirs as $dir) { $subDirTplFiles = cmf_scan_dir("$dir/*.$suffix"); foreach ($subDirTplFiles as $tplFile) { $tplFile = "$dir/$tplFile"; $configFile = preg_replace("/\.$suffix$/", '.json', $tplFile); $tplFileNoSuffix = preg_replace("/\.$suffix$/", '', $tplFile); if (is_file($tplFile) && file_exists_case($configFile)) { array_push($tplFiles, $tplFileNoSuffix); } } } foreach ($tplFiles as $tplFile) { //遍历所有文件json文件 $configFile = $tplFile . ".json"; $file = preg_replace('/^themes\/' . $theme . '\//', '', $tplFile); $file = strtolower($file); $config = json_decode(file_get_contents($configFile), true); $findFile = Db::name('theme_file')->where(['theme' => $theme, 'file' => $file])->find(); $isPublic = empty($config['is_public']) ? 0 : 1; $listOrder = empty($config['order']) ? 0 : floatval($config['order']); $configMore = empty($config['more']) ? [] : $config['more']; $more = $configMore; if (empty($findFile)) { //在数据表theme_file没有找到该模板 则插入 Db::name('theme_file')->insert([ 'theme' => $theme, 'action' => $config['action'], 'file' => $file, 'name' => $config['name'], 'more' => json_encode($more), 'config_more' => json_encode($configMore), 'description' => $config['description'], 'is_public' => $isPublic, 'list_order' => $listOrder ]); } else { // 更新文件 $moreInDb = json_decode($findFile['more'], true); //从数据库里读出来的more字段 $more = $this->updateThemeConfigMore($configMore, $moreInDb); //$configMore从index.json文件里读的json,$moreInDb从数据库里读的more字段的值 Db::name('theme_file')->where(['theme' => $theme, 'file' => $file])->update([ 'theme' => $theme, 'action' => $config['action'], 'file' => $file, 'name' => $config['name'], 'more' => json_encode($more), //json文件里有并且从数据里取值以后,这里如果$configMore没有正确读取的话应该是返回了一个空值,没有保存成功 'config_more' => json_encode($configMore), //从index.json来的配置文件 'description' => $config['description'], 'is_public' => $isPublic, 'list_order' => $listOrder ]); } } // 检查安装过的模板文件是否已经删除 $files = Db::name('theme_file')->where(['theme' => $theme])->select(); foreach ($files as $themeFile) { $tplFile = $themeDir . '/' . $themeFile['file'] . '.' . $suffix; $tplFileConfigFile = $themeDir . '/' . $themeFile['file'] . '.json'; if (!is_file($tplFile) || !file_exists_case($tplFileConfigFile)) { Db::name('theme_file')->where(['theme' => $theme, 'file' => $themeFile['file']])->delete(); } } }

     

    /**
     * 替代scan_dir的方法
     * @param string $pattern 检索模式 搜索模式 *.txt,*.doc; (同glog方法)
     * @param int $flags
     * @param $pattern
     * @return array
     */
    function cmf_scan_dir($pattern, $flags = null)
    {
        $files = glob($pattern, $flags); //函数返回匹配指定模式的文件名或目录。该函数返回一个包含有匹配文件 / 目录的数组。如果出错返回 false。http://www.w3school.com.cn/php/func_filesystem_glob.asp if (empty($files)) { $files = []; } else { $files = array_map('basename', $files); //函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组。 basename 函数返回路径中的文件名部分 } return $files; //指定规则的文件的文件名数组,在更新模板时,返回的是所有.html的文件名,带扩展名 http://www.w3school.com.cn/php/func_filesystem_basename.asp。 }

     

     private function updateThemeConfigMore($configMore, $moreInDb)
        {

    //echo empty($configMore);
    // print_r($configMore); 
    // return;

    if (!empty($configMore['vars'])) {
                foreach ($configMore['vars'] as $mVarName => $mVar) { if (isset($moreInDb['vars'][$mVarName]['value']) && $mVar['type'] == $moreInDb['vars'][$mVarName]['type']) { $configMore['vars'][$mVarName]['value'] = $moreInDb['vars'][$mVarName]['value']; //数据库里有这个vars,并且类型一样,则更新这个值到配置文件数组里。 if (isset($moreInDb['vars'][$mVarName]['valueText'])) { $configMore['vars'][$mVarName]['valueText'] = $moreInDb['vars'][$mVarName]['valueText']; } } } } if (!empty($configMore['widgets'])) { foreach ($configMore['widgets'] as $widgetName => $widget) { if (isset($moreInDb['widgets'][$widgetName]['title'])) { $configMore['widgets'][$widgetName]['title'] = $moreInDb['widgets'][$widgetName]['title']; } if (isset($moreInDb['widgets'][$widgetName]['display'])) { $configMore['widgets'][$widgetName]['display'] = $moreInDb['widgets'][$widgetName]['display']; } if (!empty($widget['vars'])) { foreach ($widget['vars'] as $widgetVarName => $widgetVar) { if (isset($moreInDb['widgets'][$widgetName]['vars'][$widgetVarName]['value']) && $widgetVar['type'] == $moreInDb['widgets'][$widgetName]['vars'][$widgetVarName]['type']) { $configMore['widgets'][$widgetName]['vars'][$widgetVarName]['value'] = $moreInDb['widgets'][$widgetName]['vars'][$widgetVarName]['value']; if (isset($moreInDb['widgets'][$widgetName]['vars'][$widgetVarName]['valueText'])) { $configMore['widgets'][$widgetName]['vars'][$widgetVarName]['valueText'] = $moreInDb['widgets'][$widgetName]['vars'][$widgetVarName]['valueText']; } } } } } } return $configMore; }

     

    问题关键在函数  updateThemeConfigMore($configMore, $moreInDb);   如果json文件有语法错误,$configMore没有正确读取。可能造成配置丢失。

    在函数updateThemeConfigMore开头加如下代码输出json生成的数组

    echo empty($configMore)."\n";
    print_r($configMore); 
    return;

     

    模板更新,当json文件有语法错误(如少一个逗号)时,$configMore的值是空数组,empty($configMore)值返回1。

    themes/w0s/portal/index
    1

    Array ( )

     

    解决方案 updateThemeFiles函数里增加对json转换结果的判断,转换成功再更新数据库。

    private function updateThemeFiles($theme, $suffix = 'html')
        {
            $dir                = 'themes/' . $theme; $themeDir = $dir; $tplFiles = []; $root_dir_tpl_files = cmf_scan_dir("$dir/*.$suffix"); foreach ($root_dir_tpl_files as $root_tpl_file) { $root_tpl_file = "$dir/$root_tpl_file"; $configFile = preg_replace("/\.$suffix$/", '.json', $root_tpl_file); $root_tpl_file_no_suffix = preg_replace("/\.$suffix$/", '', $root_tpl_file); if (is_file($root_tpl_file) && file_exists_case($configFile)) { array_push($tplFiles, $root_tpl_file_no_suffix); } } $subDirs = cmf_sub_dirs($dir); foreach ($subDirs as $dir) { $subDirTplFiles = cmf_scan_dir("$dir/*.$suffix"); foreach ($subDirTplFiles as $tplFile) { $tplFile = "$dir/$tplFile"; $configFile = preg_replace("/\.$suffix$/", '.json', $tplFile); $tplFileNoSuffix = preg_replace("/\.$suffix$/", '', $tplFile); if (is_file($tplFile) && file_exists_case($configFile)) { array_push($tplFiles, $tplFileNoSuffix); } } } foreach ($tplFiles as $tplFile) { $configFile = $tplFile . ".json"; $file = preg_replace('/^themes\/' . $theme . '\//', '', $tplFile); $file = strtolower($file); $config = json_decode(file_get_contents($configFile), true); $findFile = Db::name('theme_file')->where(['theme' => $theme, 'file' => $file])->find(); $isPublic = empty($config['is_public']) ? 0 : 1; $listOrder = empty($config['order']) ? 0 : floatval($config['order']); $configMore = empty($config['more']) ? [] : $config['more']; $more = $configMore; //json没有转换成功就不更新数据库 if(!empty($config)){ if (empty($findFile)) { Db::name('theme_file')->insert([ 'theme' => $theme, 'action' => $config['action'], 'file' => $file, 'name' => $config['name'], 'more' => json_encode($more), 'config_more' => json_encode($configMore), 'description' => $config['description'], 'is_public' => $isPublic, 'list_order' => $listOrder ]); } else { // 更新文件 $moreInDb = json_decode($findFile['more'], true); //echo "\n".$tplFile."\n"; $more = $this->updateThemeConfigMore($configMore, $moreInDb); //echo empty($more)."\n"; Db::name('theme_file')->where(['theme' => $theme, 'file' => $file])->update([ 'theme' => $theme, 'action' => $config['action'], 'file' => $file, 'name' => $config['name'], 'more' => json_encode($more), 'config_more' => json_encode($configMore), 'description' => $config['description'], 'is_public' => $isPublic, 'list_order' => $listOrder ]); } } }

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-21 23:58 , Processed in 0.176304 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表