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());
}
}
}
解决的问题
- 草稿转发布:从草稿状态转为发布状态时,分类计数不更新
- 隐藏转发布:从隐藏状态转为发布状态时,分类计数不更新
- 私有转发布:从私有状态转为发布状态时,分类计数不更新
- 其他状态变更:任何文章状态变更时的分类计数同步问题
食用方式:
- 在usr/plugins/目录下新建FixCategoryCount文件夹,在FixCategoryCount文件夹中新建Plugin.php
- 将上面的代码粘贴进去,在后台插件启用即可