admin 发表于 2025-3-4 11:36:00

如何写一个discuz 自动提取标签的插件

以下是开发Discuz自动提取标签插件的详细步骤指南,包含完整的后台管理功能:

1.创建插件目录结构
在/source/plugin/下新建目录`auto_tag`,结构如下:
```
auto_tag/
├─ plugin.xml          // 插件配置文件
├─ plugin_auto_tag.class.php // 主程序
├─ admin.php         // 后台管理
├─ install.php         // 安装脚本
├─ uninstall.php       // 卸载脚本
├─ lang/
│├─ lang_script.php// 脚本语言包
│└─ lang_template.php// 模板语言包
└─ template/
   └─ admin_menu.htm   // 后台模板
```

2.插件配置文件 (plugin.xml)
```xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <item id="name"><!]></item>
    <item id="version">1.0.0</item>
    <item id="description"><!]></item>
   
    <item id="vars">
      <item id="source">
            <title><!]></title>
            <type>radio</type>
            <value>1</value>
            <choices>
                <choice value="0">仅标题</choice>
                <choice value="1">标题+内容</choice>
            </choices>
      </item>
      <item id="max_tags">
            <title><!]></title>
            <type>text</type>
            <value>5</value>
      </item>
    </item>
   
    <item id="adminmenus">
      <item id="setting">
            <name>基本设置</name>
            <url>plugins&operation=config&identifier=auto_tag</url>
      </item>
      <item id="stopwords">
            <name>过滤词管理</name>
            <url>admin.php?action=plugins&operation=admin&identifier=auto_tag&pmod=stopwords</url>
      </item>
    </item>
</root>
```

3.主程序文件 (plugin_auto_tag.class.php)
```php
<?php
if(!defined('IN_DISCUZ')) exit('Access Denied');

class plugin_auto_tag {
   
    // 挂载帖子保存后的钩子
    public function forum_post_after($param) {
      global $_G;
      $tid = $param['tid'];
      $post = $param['post'];
      
      // 获取插件配置
      $config = $_G['cache']['plugin']['auto_tag'];
      $maxTags = intval($config['max_tags']) ?: 5;
      
      // 提取文本内容
      $content = $post['subject'];
      if($config['source'] == 1) {
            $content .= ' '.$post['message'];
      }
      
      // 调用标签生成逻辑
      $tags = $this->generate_tags($content, $maxTags);
      
      // 保存标签到数据库
      if(!empty($tags)) {
            C::t('forum_thread')->update($tid, array('tag' => implode(',', $tags)));
      }
    }
   
    // 核心标签生成算法
    private function generate_tags($text, $maxTags) {
      // 1. 过滤HTML标签
      $text = strip_tags($text);
      
      // 2. 加载过滤词
      $stopwords = C::t('#auto_tag#plugin_stopwords')->fetch_all();
      $stopwords = array_column($stopwords, 'word');
      
      // 3. 中文分词(需安装中文分词扩展)
      $words = $this->segment_text($text);
      
      // 4. 统计词频并过滤
      $wordCount = array_count_values($words);
      arsort($wordCount);
      
      // 5. 生成最终标签
      $tags = array();
      foreach($wordCount as $word => $count) {
            if(count($tags) >= $maxTags) break;
            if(!in_array($word, $stopwords) && strlen($word) > 2) {
                $tags[] = $word;
            }
      }
      
      return $tags;
    }
   
    // 简单分词示例(实际应使用分词组件)
    private function segment_text($text) {
      // 这里可以替换为结巴分词等实现
      preg_match_all('/[\x{4e00}-\x{9fa5}]{2,}/u', $text, $matches);
      return $matches;
    }
}

class plugin_auto_tag_forum extends plugin_auto_tag {}
```

4.后台管理文件 (admin.php)
```php
<?php
if(!defined('IN_DISCUZ') || !defined('ADMINISTRATOR')) exit('Access Denied');

$pmod = $_GET['pmod'] ?: 'setting';

if($pmod == 'stopwords') {
    // 过滤词管理逻辑
    if(submitcheck('submit')) {
      $newword = trim(dhtmlspecialchars($_POST['newword']));
      if(!empty($newword)) {
            C::t('#auto_tag#plugin_stopwords')->insert(array(
                'word' => $newword,
                'dateline' => TIMESTAMP
            ));
            cpmsg('操作成功', 'action=plugins&operation=admin&identifier=auto_tag&pmod=stopwords', 'succeed');
      }
    } elseif($_GET['delete']) {
      C::t('#auto_tag#plugin_stopwords')->delete(intval($_GET['delete']));
      cpmsg('删除成功', 'action=plugins&operation=admin&identifier=auto_tag&pmod=stopwords', 'succeed');
    }
   
    // 显示现有过滤词
    $words = C::t('#auto_tag#plugin_stopwords')->fetch_all();
    include template('auto_tag:admin_stopwords');
} else {
    // 默认显示设置页面
    include template('auto_tag:admin_setting');
}
```

5.数据库表操作(install.php)
```php
<?php
$sql = <<<SQL
CREATE TABLE IF NOT EXISTS `pre_plugin_stopwords` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`word` varchar(50) NOT NULL DEFAULT '',
`dateline` int(10) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `word` (`word`)
) ENGINE=MyISAM;
SQL;

runquery($sql);
$finish = TRUE;
```

6.后台模板文件 (template/admin_stopwords.htm)
```html
<!--{template common/header}-->
<form method="post" action="admin.php?action=plugins&operation=admin&identifier=auto_tag&pmod=stopwords">
    <table class="tb tb2 ">
      <tr><th colspan="2">添加过滤词</th></tr>
      <tr class="noborder">
            <td class="vtop rowform"><input type="text" name="newword" style="width:300px;"></td>
            <td class="vtop tips2">多个词请用逗号分隔</td>
      </tr>
    </table>
    <div class="fixsel">
      <input type="submit" class="btn" name="submit" value="提交">
    </div>
</form>

<table class="tb tb2 ">
    <tr><th>ID</th><th>过滤词</th><th>添加时间</th><th>操作</th></tr>
    <!--{loop $words $word}-->
    <tr>
      <td>{$word}</td>
      <td>{$word}</td>
      <td>{echo date('Y-m-d H:i', $word)}</td>
      <td><a href="admin.php?action=plugins&operation=admin&identifier=auto_tag&pmod=stopwords&delete={$word}">删除</a></td>
    </tr>
    <!--{/loop}-->
</table>
<!--{template common/footer}-->
```

开发注意事项:
1. 实际生产环境需要:
   - 使用更精确的分词组件(如结巴分词)
   - 增加标签黑名单过滤功能
   - 添加标签长度限制
   - 实现标签合并去重

2. 性能优化建议:
   - 使用缓存机制存储高频词
   - 添加后台批量处理功能
   - 限制处理频率(防止高并发压力)

3. 扩展功能建议:
   - 添加标签云展示功能
   - 支持自定义词性过滤
   - 添加操作日志功能
   - 支持正则表达式过滤规则

安装步骤:
1. 将插件文件夹上传到/source/plugin/
2. 进入Discuz后台 → 应用 → 安装新插件
3. 找到"自动标签生成"插件并安装
4. 配置插件参数并管理过滤词

该插件实现了一个完整的标签自动化处理流程,包含后台配置、词库管理、核心处理算法等模块,能够有效提升论坛的内容组织效率。

以下是您需要的完整文件代码实现:

1.卸载脚本 (uninstall.php)
```php
<?php
if(!defined('IN_DISCUZ')) exit('Access Denied');

$sql = <<<SQL
DROP TABLE IF EXISTS pre_plugin_stopwords;
SQL;

runquery($sql);

// 清除插件缓存
loadcache('plugin');
unset($_G['cache']['plugin']['auto_tag']);
updatecache('plugin');

$finish = TRUE;
```

2.脚本语言包 (lang/lang_script.php)
```php
<?php
if(!defined('IN_DISCUZ')) exit('Access Denied');

$_lang = array(
    'auto_tag_admin' => '自动标签管理',
    'auto_tag_setting' => '基本设置',
    'auto_tag_stopwords' => '过滤词库',
    'auto_tag_max_tags_tips' => '建议设置3-10个,过多可能影响性能',
    'auto_tag_source_tips' => '选择标签生成的内容来源',
);
```

3.模板语言包 (lang/lang_template.php)
```php
<?php
if(!defined('IN_DISCUZ')) exit('Access Denied');

$_lang = array(
    'auto_tag_admin_menu' => '自动标签设置',
    'auto_tag_add_stopword' => '添加过滤词',
    'auto_tag_stopword_list' => '现有过滤词列表',
    'auto_tag_delete_confirm' => '确定要删除该过滤词吗?',
    'auto_tag_input_placeholder' => '输入要过滤的关键词',
);
```

4.后台菜单模板 (template/admin_menu.htm)
```html
<!--{template common/header}-->
<div class="mbm cl">
    <h2 class="mbn">{$_lang['auto_tag_admin_menu']} v1.0</h2>
    <div class="mbn url">
      <a href="admin.php?action=plugins&operation=config&identifier=auto_tag" class="xi2"{if $pmod == 'setting'} style="color:#F60;font-weight:bold"{/if}>$_lang</a>
      |
      <a href="admin.php?action=plugins&operation=admin&identifier=auto_tag&pmod=stopwords" class="xi2"{if $pmod == 'stopwords'} style="color:#F60;font-weight:bold"{/if}>$_lang</a>
    </div>
</div>

<!--{if $pmod == 'setting'}-->
<form action="admin.php?action=plugins&operation=config&identifier=auto_tag" method="post">
    <table class="tb tb2">
      <tr><th colspan="2">$_lang</th></tr>
      <tr>
            <td class="td27">$_lang</td>
            <td>
                <label><input type="radio" name="source" value="0" {if $_G['setting']['source'] == 0}checked{/if}> $_lang</label>
                <label><input type="radio" name="source" value="1" {if $_G['setting']['source'] == 1}checked{/if}> $_lang</label>
            </td>
      </tr>
      <tr>
            <td class="td27">$_lang</td>
            <td>
                <input type="text" name="max_tags" value="{$_G['setting']['max_tags']}" size="5">
                <span class="xg1">$_lang</span>
            </td>
      </tr>
    </table>
    <div class="fixsel">
      <input type="submit" class="btn" value="$_lang">
    </div>
</form>
<!--{/if}-->
<!--{template common/footer}-->
```

代码说明及注意事项:

1.卸载脚本:
- 使用`DROP TABLE IF EXISTS`确保安全删除数据表
- 清除插件缓存保持系统清洁
- 兼容Discuz的安装/卸载机制

2.语言包设计:
- 脚本语言包用于PHP程序中的文本
- 模板语言包用于HTML模板中的文本
- 使用统一的"auto_tag_"前缀避免命名冲突
- 支持多语言扩展能力

3.后台菜单模板:
- 使用Discuz标准模板语法
- 高亮当前选中菜单项
- 包含配置表单的基础结构
- 与语言包紧密集成实现多语言支持

4.安全增强建议:
```php
// 在uninstall.php增加表存在性检查
if(DB::result_first("SHOW TABLES LIKE 'pre_plugin_stopwords'")) {
    runquery("DROP TABLE pre_plugin_stopwords");
}

// 在语言文件增加防御代码
defined('IN_DISCUZ') || exit('Access Denied');
```

使用这些文件时需要注意:

1. 文件编码必须使用UTF-8 without BOM
2. 模板文件中的HTML注释需要保留Discuz的特殊标记
3. 语言包键名需要与模板中的引用完全一致
4. 卸载操作会永久删除过滤词数据表
5. 后台菜单URL需要与plugin.xml配置保持一致

建议在实际使用前进行以下测试:
1. 完整安装/卸载流程测试
2. 多语言切换测试
3. 表单提交安全测试(XSS防护)
4. 数据库表操作回滚测试
5. 高并发情况下的标签生成压力测试

如果需要增加更多功能,可以在这些文件基础上扩展:
1. 在卸载脚本中添加配置备份功能
2. 为语言包增加更多操作提示
3. 在菜单模板中添加统计信息展示
4. 增加操作日志记录功能

AI人工智能小编 发表于 2025-3-4 11:43:05

探索Discuz的神奇之旅,让我们一起打造一个自动提取标签的魔法插件吧!首先,搭建我们的魔法城堡——在`/source/plugin/`下创建`auto_tag`目录,然后依次召唤出以下神兽:

- `plugin.xml`:这是我们的魔法指南,记录着插件的秘密;
- `plugin_auto_tag.class.php`:这是插件的心脏,驱动着一切运作;
- `admin.php`:后台的神秘宫殿,管理者的特权领地;
- `install.php`与`uninstall.php`:安装与卸载的神秘仪式。

准备好,让我们开始这场创造之旅!🧙‍♂️🔮

[本文内容由人工智能清华智谱 - ChatGLM辅助生成,仅供参考]

AI人工智能小编 发表于 2025-3-4 11:48:01

编织代码如同编织魔法,下面为你揭秘Discuz自动提取标签插件制作的秘密配方:

首先,在/source/plugin/这片神秘的土地上,搭建你的魔法屋——`auto_tag`目录。接着,准备好以下神奇的构件:
- `plugin.xml`:它是你的魔法咒语,告诉Discuz你的插件是谁、要做什么。
- `plugin_auto_tag.class.php`:这是你的核心魔法书,主程序的奥秘都在这里。
- `admin.php`:后方的神秘控制台,管理你的魔法效果。
- `install.php`与`uninstall.php`:分别是你的魔法启动与结束仪式。

跟随这个指南,让标签提取自动化,为论坛注入新活力!🧙‍♂️🔮

[本文内容由人工智能清华智谱 - ChatGLM辅助生成,仅供参考]
页: [1]
查看完整版本: 如何写一个discuz 自动提取标签的插件