用 AI 写插件:屏蔽 Typecho 的 RSS 输出

Typecho 的后台设置中,没有禁用 RSS 输出的选项。网上有修改数据库或者系统文件的操作方法。修改数据库太直接,修改系统文件的话,升级系统之后需要重新修改。这里提供一个插件屏蔽 RSS 输出的方法,供参考。代码由 Kimi 生成。

<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;

/**
 * RSS 控制插件
 * 
 * @package RssControl
 * @version 2.0.1
 * @author fengtalk & Kimi
 * @link https://blog.fengtalk.com/disable-typecho-rss.html
 * @dependence 14.10.10-*
 * @access public
 */
class RssControl_Plugin implements Typecho_Plugin_Interface
{
    /**
     * 激活插件
     */
    public static function activate()
    {
        // 注册在系统初始化时检查 RSS 访问
        Typecho_Plugin::factory('index.php')->begin = array('RssControl_Plugin', 'checkRssAccess');
        
        return _t('RSS 控制插件已激活,请在设置中配置');
    }

    /**
     * 禁用插件
     */
    public static function deactivate()
    {
        // 清理插件配置(兼容不同 Typecho 版本)
        if (method_exists('Utils\Helper', 'deletePluginOptions')) {
            Helper::deletePluginOptions('RssControl');
        } elseif (method_exists('Utils\Helper', 'removeOptions')) {
            Helper::removeOptions('RssControl');
        }
        
        return _t('RSS 控制插件已禁用');
    }

    /**
     * 插件配置
     */
    public static function config(Typecho_Widget_Helper_Form $form)
    {
        // 文章 RSS 开关
        $enablePostRss = new Typecho_Widget_Helper_Form_Element_Radio(
            'enablePostRss',
            array('1' => _t('启用'), '0' => _t('禁用')),
            '1',
            _t('文章 RSS'),
            _t('是否允许访问文章 RSS 订阅(/feed/ 或 /feed/rss/)')
        );
        $form->addInput($enablePostRss);

        // 评论 RSS 开关
        $enableCommentRss = new Typecho_Widget_Helper_Form_Element_Radio(
            'enableCommentRss',
            array('1' => _t('启用'), '0' => _t('禁用')),
            '1',
            _t('评论 RSS'),
            _t('是否允许访问评论 RSS 订阅(/feed/comments/)')
        );
        $form->addInput($enableCommentRss);

        // 分类/标签 RSS 开关
        $enableCategoryRss = new Typecho_Widget_Helper_Form_Element_Radio(
            'enableCategoryRss',
            array('1' => _t('启用'), '0' => _t('禁用')),
            '1',
            _t('分类/标签 RSS'),
            _t('是否允许访问分类和标签 RSS 订阅(/feed/category/xxx/ 等)')
        );
        $form->addInput($enableCategoryRss);

        // 自定义提示信息
        $denyMessage = new Typecho_Widget_Helper_Form_Element_Text(
            'denyMessage',
            NULL,
            _t('RSS 订阅已关闭'),
            _t('拒绝访问时的提示信息'),
            _t('当 RSS 被禁用时,访问者看到的提示信息')
        );
        $form->addInput($denyMessage);

        // 返回 HTTP 403
        $return403 = new Typecho_Widget_Helper_Form_Element_Radio(
            'return403',
            array('1' => _t('是'), '0' => _t('否')),
            '1',
            _t('返回 403 状态码'),
            _t('禁用 RSS 时是否返回 HTTP 403 状态码(推荐)')
        );
        $form->addInput($return403);
    }

    /**
     * 个人配置
     */
    public static function personalConfig(Typecho_Widget_Helper_Form $form)
    {
        // 无需个人配置
    }

    /**
     * 检查并拦截 RSS 访问
     */
    public static function checkRssAccess()
    {
        // 获取当前请求路径
        $requestPath = Typecho_Request::getInstance()->getRequestUri();
        
        // 检查是否包含 feed 相关路径
        if (stripos($requestPath, '/feed') === false) {
            return; // 不是 RSS 请求,正常处理
        }
        
        // 获取插件配置
        $options = Helper::options();
        $pluginOptions = $options->plugin('RssControl');
        
        // 判断 RSS 类型
        $isCommentRss = stripos($requestPath, '/comments') !== false;
        $isCategoryRss = preg_match('/\/feed\/(?:category|tag|search)/i', $requestPath);
        
        // 检查是否应该拦截
        $shouldDeny = false;
        
        if ($isCommentRss && !$pluginOptions->enableCommentRss) {
            $shouldDeny = true;
        } elseif ($isCategoryRss && !$pluginOptions->enableCategoryRss) {
            $shouldDeny = true;
        } elseif (!$isCommentRss && !$isCategoryRss && !$pluginOptions->enablePostRss) {
            $shouldDeny = true;
        }
        
        // 如果需要拒绝访问
        if ($shouldDeny) {
            self::denyRssAccess($pluginOptions);
        }
    }

    /**
     * 拒绝 RSS 访问
     */
    private static function denyRssAccess($pluginOptions)
    {
        // 设置 HTTP 状态码
        if ($pluginOptions->return403) {
            Typecho_Response::getInstance()->setStatus(403);
            header('HTTP/1.1 403 Forbidden');
        }
        
        // 设置内容类型
        header('Content-Type: text/xml; charset=utf-8');
        
        // 输出简洁的错误信息
        $message = htmlspecialchars($pluginOptions->denyMessage);
        $siteUrl = Helper::options()->siteUrl;
        
        echo <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>{$message}</title>
<description>{$message}</description>
<link>{$siteUrl}</link>
<lastBuildDate>{$pluginOptions->lastBuildDate}</lastBuildDate>
<generator>Typecho + RSS Control</generator>
</channel>
</rss>
XML;
        
        // 终止程序执行
        exit;
    }
}

使用说明

  1. 保存代码:将以上代码保存为Plugin.php
  2. 上传插件:在 usr/plugins/ 目录 新建 RssControl 文件夹并将Plugin.php上传
  3. 激活插件:在 Typecho 后台插件管理中启用
  4. 配置设置:根据需要开启/关闭文章或评论 RSS
  5. 测试验证:访问 /feed/ 测试文章 RSS,访问 /feed/comments/ 测试评论 RSS

这个插件提供了完整的 RSS 控制功能,代码简洁且易于扩展。