WordPress B2主题统计插件修复记录

B2 主题升级后统计插件出现后台样式错乱、签到/搜索/下载管理页无数据等问题。本文记录完整排查过程:外链 CDN 失效、用户数据容错、B2 5.x 签到表迁移,以及 PHP 8 下 REST 回调不可调用四类故障的修复方法。

B2 主题的统计插件(b2_tongji)本站一直在用。B2 主题升级到 5.9.x 之后,这个插件陆续出了问题:先是后台首页样式全乱,接着发现签到、搜索、下载三个管理页也一条数据都没有。

下面是完整的排查与修复记录。四条故障里,两条是插件本身的问题,一条是 B2 升级后数据表变更导致的,还有一条是排查过程中容易踩的坑。

环境

  • WordPress 6.x / PHP 8.2
  • B2 商业主题 5.9.x(加密分发)
  • 统计插件 b2_tongji,依赖 B2 主题内置的 CMB2 库

一、后台首页样式错乱:CDN 下线

插件首页是一个 Vue + Vuetify 写的管理面板,但它的前端资源用的是外链 CDN:

<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.11/vue.min.js"></script>
<link  href="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/vuetify/2.3.8/vuetify.min.css" rel="stylesheet">
<script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/vuetify/2.3.8/vuetify.min.js"></script>

这几个字节跳动系域名已经全局 404。Vue 加载失败,Vuetify 的自定义标签就不会被编译,页面退化成一大堆没有样式的原始标签——顶部统计卡片竖排、Sparkline 和图表区全空。

修复方式是把这三个文件下载到插件自己的目录里,改用相对路径引用:

<script src="<?php echo B2_TJ_URL.'assets/vendor/vue.min.js';?>"></script>
<link href="<?php echo B2_TJ_URL.'assets/vendor/vuetify.min.css';?>" rel="stylesheet">
<script src="<?php echo B2_TJ_URL.'assets/vendor/vuetify.min.js';?>"></script>

同一文件里还有两处错位的 </h2>,分别写在「今日登录」和「今日签到」卡片的 <span> 里,会破坏 DOM 结构,一并删掉。

二、页面报 Undefined array key:系统消息没有用户数据

私信记录等页面要显示用户昵称和主页链接,直接调用了 B2 的方法:

B2ModulesCommonUser::get_user_public_data( $user_id );

当 $user_id 为 0(系统消息)或用户已被删除时,这个方法返回的是 array( 'error' => ... ),不含 link 与 name 键,页面就会刷出一整屏 Undefined array key 警告,对应列显示空白。

加一层容错包装即可,对正常用户的行为与原方法完全一致:

function tj_user_data( $user_id ) {
    $d = B2ModulesCommonUser::get_user_public_data( $user_id );
    if ( ! is_array( $d ) ) { $d = array(); }
    if ( ! isset( $d['link'] ) ) { $d['link'] = ''; }
    if ( ! isset( $d['name'] ) ) {
        $d['name'] = $user_id ? ( '用户#' . $user_id ) : '系统';
    }
    return $d;
}

再把插件里 10 处 User::get_user_public_data(...) 统一替换成 tj_user_data(...),报错即归零。

三、签到管理没有数据:B2 换了记录表

这一条是升级导致的。B2 5.x 的 User::user_mission() 已经把签到记录从旧表改写到新表:

// 旧:写入 wp_zrz_message,msg_type = 16
Message::add_message( array(
    'user_id'  => $user_id,
    'msg_type' => 16,
    ...
) );

// 新:写入 wp_b2_gold,type = user_mission
Gold::update_data( array(
    ...
    'type'      => 'user_mission',
    'type_text' => __( '签到', 'b2' ),
) );

而插件仍在查询 wp_zrz_message WHERE msg_type = 16——这张表的最新数据停在 2022 年,所以列表永远是空的。真实签到数据已经全部落在 wp_b2_gold 里。

需要把查询源换掉,并做字段映射(字段名几乎全变了):

用途 旧字段(wp_zrz_message) 新字段(wp_b2_gold)
表名 wp_zrz_message wp_b2_gold
筛选条件 msg_type = 16 type = ‘user_mission’
排序 msg_id id
用户 user_id to
本次增加积分 msg_credit no
积分总数 msg_credit_total total
签到时间 msg_date date

改完后签到管理页恢复显示,分页统计的条数与 wp_b2_gold 中 type='user_mission' 的实际行数完全一致。

四、搜索管理没有数据:PHP 8 下 REST 回调不可调用

插件注册了一个 REST 路由用来记录搜索词:

register_rest_route( 'b2/v1', '/tjsearch', array(
    ...
    'callback' => array( __CLASS__, 'tj_search' ),
) );

问题在于 tj_search 声明为 public function(非静态)。PHP 8 起,is_callable( array( 'ClassName', 'nonStaticMethod' ) ) 返回 false,于是 WordPress 直接判定处理器无效:

{"code":"rest_invalid_handler","message":"此路由的处理器无效。","data":{"status":500}}

前台每次搜索都会请求这个接口并失败,搜索记录表自然一直是空的。这两个方法体内都没有用到 $this,直接改成静态即可:

public static function tj_search( $request ) { ... }
public static function tj_search_fun( $request ) { ... }

改完接口恢复返回 success,写入正常。

五、下载管理没有数据:其实一切正常

下载统计用的是 B2 的 b2_download_file 钩子,实测触发一次 filter 就能正确写入一条记录,字段映射也没有问题。

表之所以是空的,有两个原因:

  • 站点近期确实没有下载行为;
  • 插件每天的定时任务会清理 8 天前的下载 / 搜索 / 异常记录。

所以这一项不需要改代码。如果希望记录保留更久,需要调整清理周期。

六、一个容易踩的坑:CMB2 回调收到的不是 box

插件的后台页面用 CMB2 的 options page 机制注册,回调函数里是这样取 tab 分组名的:

$tab_group = $cmb_options->cmb->prop( 'tab_group' );

看起来有点绕,但它是对的——CMB2 调用 display_cb 时传入的是 CMB2_Options_Hookup 实例,而不是 CMB2 box 本身:

// CMB2_Options_Hookup.php 中
call_user_func( $callback, $this );

CMB2_Options_Hookup::__get() 的可用属性白名单只有 object_type、option_key、cmb 三个。所以:

  • 取 box 上的属性,必须走 $cmb_options->cmb->prop( ... );
  • 取 option key,用 $cmb_options->option_key;
  • 改成 $cmb_options->prop( ... ) 或 $cmb_options->cmb_id 都会直接致命错误——前者方法不存在,后者不在 __get() 白名单里。

排查时要特别注意:如果只用一个「把 box 实例直接传给回调」的简易脚本去测,是测不出这个问题的,因为传参对象和真实运行时不一致。

七、验证方式

修复完成后,用两条路径交叉验证:

  • 真实管理后台引导路径:完整加载 wp-admin/admin.php(含鉴权、菜单注册、page hook),逐个渲染插件的 12 个后台页面,确认全部正常退出、无致命错误、无 PHP 警告。
  • 真实登录态 HTTP 请求:带正常登录 Cookie 直接访问各后台页面,返回 200,页面结构完整(Vue 挂载点、导航页签、图表画布齐全)。

只加载 wp-load.php 的简易验证会绕过 WordPress 的致命错误处理器,容易得出「一切正常」的错误结论,这一点值得注意。

八、后续注意

  1. 不要再把 Vue / Vuetify 改回 CDN 外链,继续用插件目录内的本地资源。
  2. 签到数据源是 wp_b2_gold(type='user_mission'),wp_zrz_message 已废弃,不要改回去。
  3. 任何新增读取用户公开数据的页面,统一使用 tj_user_data(),避免再出现数组键缺失。
  4. 插件依赖 B2 主题内置的 CMB2,B2 再次升级后若后台页面白屏,优先检查这里的兼容性。

小结

B2 生态里的插件大多是第三方个人维护,主题一升级就容易出现「明明没改代码却坏了」的情况。常见的原因集中在三类:外链资源失效、数据库表结构变更、PHP 版本升级带来的语法与反射行为变化。排查时先确认后端逻辑本身是否还能正常拿到数据,再往前端资源和框架兼容性上找,效率会高很多。

下载权限
查看
  • ¥
    免费下载
    评论并刷新后下载
    登录后下载
  • {{attr.name}}:
您当前的等级为
登录后免费下载登录 小黑屋反思中,不准下载! 评论后刷新页面下载评论 支付以后下载 请先登录 您今天的下载次数(次)用完了,请明天再来 支付积分以后下载立即支付 支付以后下载立即支付 您当前的用户组不允许下载升级会员
您已获得下载权限 您可以每天下载资源次,今日剩余次

给TA打赏
共{{data.count}}人
人已打赏
建站教程

Dedebiz织梦模板中使用ifeles语句

2025-7-8 15:35:11

电视节目

绝望主妇 第八季

2024-11-5 16:07:00

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
❯
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索