Typecho自动删除占用cid附件自动文章连贯插件


摘要由 AI 智能生成

早在24年就尝试解决文章id不连贯
解决Typecho新文章、页面uid排序错乱问题
出现不连贯的原因是所有内容(文章、页面、附件、草稿)都存在同一张contents表中,共用一个 “自增 ID”(AUTO_INCREMENT)为了解决这个问题我开发了 AutoIDSeq 插件,让 CID 能自动 “归位”。下面分享它的功能、核心代码

AutoIDSeq - 自动连贯文章id

AutoIDSeq 的目标很简单:确保新发布的文章、页面(及对应草稿)CID 连续且不冲突。它实现了这些关键能力:

  1. 自动同步 CID:新内容发布时,智能计算 “最大有效 CID + 1” 作为目标 ID;若被占用,自动避让(删除占用的附件,或对有效内容 +1)。
  2. 附件冲突处理:若目标 CID 被 “附件” 占用,直接删除该附件(附件 ID 通常不影响核心内容)。
  3. 自增 ID 管理:支持手动修改数据库表的自增 ID 起点,避免后续 ID “断层”。
  4. 多类型兼容:同时覆盖 文章(post)、文章草稿(post_draft)、页面(page)、页面草稿(page_draft),贯穿内容创作全流程。

插件的核心逻辑集中在 “发布前 CID 同步”“后台动作处理” 两部分

发布前自动同步 CID:beforePostPublish 方法

这个方法是 “自动排序 ID” 的核心,在内容发布 / 编辑的钩子中触发:



public static function beforePostPublish($content, $widget)
{
    $isNewContent = !isset($content['cid']); // 判断是否为“新内容”(非编辑已有内容)
    $contentType = $widget->type; // 获取内容类型(post 或 page)
    $db = Typecho_Db::get();
    $prefix = $db->getPrefix();
    $tableName = $prefix . 'contents';
    $targetCid = 0;

    if ($isNewContent) { // 仅处理“新发布”的内容,编辑已有内容不改动 ID
        // 步骤 1:查询“文章/页面及草稿”的最大 CID
        $validTypes = ['post', 'post_draft', 'page', 'page_draft'];
        $maxContentResult = $db->fetchRow($db->query(
            $db->select('MAX(cid) AS maxCid')
               ->from($tableName)
               ->where('type IN ?', $validTypes)
        ));
        $maxContentCid = $maxContentResult ? (int)$maxContentResult['maxCid'] : 0;
        $targetCid = $maxContentCid + 1; // 目标 CID 为“最大有效 ID + 1”

        // 步骤 2:检查目标 CID 是否被占用
        $occupiedCheck = $db->fetchRow($db->query(
            $db->select('cid', 'type', 'status')
               ->from($tableName)
               ->where('cid = ?', $targetCid)
        ));
        
        if ($occupiedCheck) {
            if ($occupiedCheck['type'] == 'attachment') {
                // 若被“附件”占用,直接删除该附件
                $db->query(
                    $db->delete($tableName)
                       ->where('cid = ?', $targetCid)
                );
            } else {
                // 若被“文章/页面/草稿”占用,CID 自动 +1 避让
                $targetCid += 1;
            }
        }

        // 步骤 3:同步数据库自增 ID,避免后续 ID 断层
        $db->query("ALTER TABLE `{$tableName}` AUTO_INCREMENT = " . ($targetCid + 1));

        // 步骤 4:为新内容设置最终 CID
        $content['cid'] = $targetCid;
    }

    return $content;
}

通过 4 个步骤保障 CID 连续性 —— 先找 “文章 / 页面 / 草稿” 的最大 ID、检查冲突、智能处理冲突(删附件 / 避让有效内容)、同步数据库自增 ID,最后给新内容赋值。

2. 后台动作处理:handleActions 方法

这个方法处理 “一键删除所有附件” 和 “修改自增 ID” 两个核心操作:

public static function handleActions()
{
    $request = Typecho_Request::getInstance();
    $db = Typecho_Db::get();
    $prefix = $db->getPrefix();
    $tableName = $prefix . 'contents';

    // 一键删除所有附件
    if ($request->isPost() && $request->action === 'deleteAllAttachments') {
        try {
            $db->query("DELETE FROM `{$tableName}` WHERE `type` = 'attachment'");
            Typecho_Widget::widget('Widget_Notice')->set(_t('所有附件已成功删除'), 'success');
        } catch (Exception $e) {
            Typecho_Widget::widget('Widget_Notice')->set(_t('删除失败:%s', $e->getMessage()), 'error');
        }
    }

    // 修改自增 ID
    if ($request->isPost() && $request->action === 'updateAutoIncrement') {
        $newValue = trim($request->newAutoIncrement);
        if (is_numeric($newValue) && (int)$newValue > 0) {
            try {
                $db->query("ALTER TABLE `{$tableName}` AUTO_INCREMENT = {$newValue}");
                Typecho_Widget::widget('Widget_Notice')->set(_t("自增ID已修改为:{$newValue}"), 'success');
            } catch (Exception $e) {
                Typecho_Widget::widget('Widget_Notice')->set(_t("修改失败:%s", $e->getMessage()), 'error');
            }
        } else {
            Typecho_Widget::widget('Widget_Notice')->set(_t('请输入有效的正整数'), 'error');
        }
    }
}

提供 “清理冗余附件” 和 “手动干预自增 ID” 的入口,让插件既能自动化又能手动控制

3. 可视化配置面板:config 方法

设计了后台界面,可以直观查看 “当前自增 ID”“最近内容”“附件数量” 等信息:

public static function config(Typecho_Widget_Helper_Form $form)
{
    // 自动同步开关(代码略,主要是 Checkbox 组件)

    // 自增 ID 管理区域
    echo '<div class="plugin-section">';
    echo '<h3>表自增 ID 管理</h3>';
    // 显示“当前自增 ID”“建议修改值”,并提供修改表单
    echo '</div>';

    // 最近内容区域(显示文章/页面及草稿的最近 5 条)
    echo '<div class="plugin-section">';
    echo '<h3>最近 5 篇内容(含文章/页面及对应草稿)</h3>';
    // 从数据库查询并展示最近内容
    echo '</div>';

    // 附件信息与操作区域
    echo '<div class="plugin-section">';
    echo '<h3>附件信息</h3>';
    // 显示附件数量、列表,以及“一键删除所有附件”按钮
    echo '</div>';

    // 调试日志展示区域
    echo '<div class="plugin-section log-section">';
    echo '<h3>最近一次自动同步日志</h3>';
    // 展示 debug.log 中的最近日志
    echo '</div>';
}

使用截图

mfc98928.png
mfc98wsz.png

项目地址 https://github.com/yunyanACE/AutoIDSeq

评论区
头像
    头像
    bvvutpihvy
      

    新盘 上车集合 留下 我要发发 立马进裙coinsrore.com

    头像

    删除没用的ID,后面文章递进,会不会造成错误

      头像
      云烟
        
      @天天下载ttzip

      只要分配的id不冲突就不会出现错误

文章目录