AI摘要
Typecho分类计数修正插件解决了Typecho在草稿转发布时分类计数不准确的问题。插件通过注册钩子,在文章发布时自动调用onFinishPublish方法,仅针对草稿转发布场景。用户需在usr/plugins/目录下新建FixCategoryCount文件夹并创建Plugin.php文件,粘贴代码后在后台启用插件。

Typecho有一个小bug,在撰写文章保存草稿再发布的时候,会导致分类中文章计数不准确
原因是草稿转发布时,Typecho貌似没有自动触发分类计数的更新逻辑,导致count字段不同步
为了避免对源代码的改动影响后续版本更新,写了这个插件暂时解决这个问题

场景:typecho v1.3.0-rc,handsome 10.1.0(开发版),php 8.4.6

如果遇到了同样的情况可以试一下这个插件

<?php
/**
 * 草稿转发布自动修正分类计数 - 最终版
 * 
 * @package FixCategoryCount
 * @author Kev
 * @version 1.0.3
 * @link https://kev.fit
 * @description 解决Typecho草稿转发布和隐藏转发布时分类数量不同步的问题
 */
if (!defined('__TYPECHO_ROOT_DIR__')) exit;

class FixCategoryCount_Plugin implements Typecho_Plugin_Interface
{
    /**
     * 激活插件
     */
    public static function activate()
    {
        // 监听文章发布完成事件
        Typecho_Plugin::factory('Widget_Contents_Post_Edit')->finishPublish = array('FixCategoryCount_Plugin', 'onFinishPublish');
        
        // 监听文章更新完成事件
        Typecho_Plugin::factory('Widget_Contents_Post_Edit')->finishUpdate = array('FixCategoryCount_Plugin', 'onFinishUpdate');
        
        return _t('插件启用成功');
    }
    
    /**
     * 禁用插件
     */
    public static function deactivate()
    {
        return _t('插件已禁用');
    }
    
    /**
     * 获取插件配置面板
     */
    public static function config(Typecho_Widget_Helper_Form $form)
    {
        $enableLog = new Typecho_Widget_Helper_Form_Element_Checkbox(
            'enableLog',
            array('enable' => _t('启用调试日志')),
            array('enable'),
            _t('调试选项'),
            _t('启用后会在系统日志中记录分类修正的详细信息')
        );
        $form->addInput($enableLog);
        
        $fixAllStatus = new Typecho_Widget_Helper_Form_Element_Checkbox(
            'fixAllStatus',
            array('enable' => _t('修正所有状态变更')),
            array('enable'),
            _t('修正范围'),
            _t('启用后会修正所有状态变更时的分类计数(包括草稿、隐藏、私有转发布等)')
        );
        $form->addInput($fixAllStatus);
    }
    
    /**
     * 个人用户的配置面板
     */
    public static function personalConfig(Typecho_Widget_Helper_Form $form)
    {
        // 个人用户无需配置
    }
    
    /**
     * 处理文章发布完成事件
     */
    public static function onFinishPublish($contents, $widget)
    {
        self::fixCategoryCount($contents, $widget, 'publish');
    }
    
    /**
     * 处理文章更新完成事件
     */
    public static function onFinishUpdate($contents, $widget)
    {
        $newStatus = $contents['status'];
        
        // 获取配置
        $options = Helper::options();
        $pluginOptions = $options->plugin('FixCategoryCount');
        $fixAllStatus = isset($pluginOptions->fixAllStatus) && in_array('enable', $pluginOptions->fixAllStatus);
        
        if ($fixAllStatus) {
            // 如果启用了修正所有状态变更,则对所有状态变更都进行修正
            self::fixCategoryCount($contents, $widget, 'update');
        } else {
            // 只对转为发布状态的文章进行修正
            if ($newStatus == 'publish') {
                self::fixCategoryCount($contents, $widget, 'update');
            }
        }
    }
    
    /**
     * 修正分类计数的核心方法
     */
    private static function fixCategoryCount($contents, $widget, $action = 'publish')
    {
        try {
            $cid = $widget->cid;
            $categories = $widget->request->getArray('category');
            
            if (!$categories || empty($categories)) {
                return;
            }
            
            // 获取配置
            $options = Helper::options();
            $pluginOptions = $options->plugin('FixCategoryCount');
            $enableLog = isset($pluginOptions->enableLog) && in_array('enable', $pluginOptions->enableLog);
            
            if ($enableLog) {
                error_log("[FixCategoryCount] 开始修正文章 {$cid} 的分类计数");
                error_log("[FixCategoryCount] 操作类型: {$action}");
                error_log("[FixCategoryCount] 文章状态: " . $contents['status']);
                error_log("[FixCategoryCount] 分类列表: " . implode(',', $categories));
            }
            
            // 调用Typecho的分类设置方法,强制重新计算计数
            // 第三个参数为false表示不删除现有分类,第四个参数为true表示强制更新计数
            $widget->setCategories($cid, $categories, false, true);
            
            if ($enableLog) {
                error_log("[FixCategoryCount] 文章 {$cid} 分类计数修正完成");
            }
            
        } catch (Exception $e) {
            // 记录错误但不影响文章发布
            error_log("[FixCategoryCount] 修正分类计数时出错: " . $e->getMessage());
        }
    }
}


解决的问题

  • 草稿转发布:从草稿状态转为发布状态时,分类计数不更新
  • 隐藏转发布:从隐藏状态转为发布状态时,分类计数不更新
  • 私有转发布:从私有状态转为发布状态时,分类计数不更新
  • 其他状态变更:任何文章状态变更时的分类计数同步问题


食用方式:

  1. 在usr/plugins/目录下新建FixCategoryCount文件夹,在FixCategoryCount文件夹中新建Plugin.php
  2. 将上面的代码粘贴进去,在后台插件启用即可
最后修改:2025 年 07 月 20 日
如果觉得我的文章对你有用,请随意赞赏