傳統 `[hide]` 標籤需發帖者手動包裹,易忘、繁瑣。本插件實現 **發帖即自動隱藏**,支援:
// 配置檔:source/plugin/kj_hide/config.inc.php
return [
'enable' => true, // 總開關
'mode' => 1, // 1=僅主題帖 2=全樓層 3=主題帖+回覆(非作者可見) 4=遊客預覽
'preview_length' => 200, // 預覽字節 (0=不預覽)
'allow_forums' => [], // 白名單版塊 fid 陣列,空=全站
'deny_forums' => [], // 黑名單版塊 fid 陣列
'exclude_announce' => true, // 排除公告/置頂
'fix_truncate' => 1, // 代碼截斷修復模式 1=移至 BBCode 解析前 2=不修復
];
// 找到 discuzcode() 呼叫處,在參數末尾新增 $post['first']
// DZ X3.4 範例 (約第 300 行)
$post['message'] = discuzcode($post['message'], $post['smileyoff'], $post['bbcodeoff'],
$post['htmlon'], $forum['allowsmilies'], $forum['allowbbcode'],
($forum['allowimgcode'] && $showimages ? 1 : 0), $forum['allowhtml'],
($forum['jammer'] && $post['authorid'] != $discuz_uid ? 1 : 0),
$pid, $post['authorid'], $post['first']); // ← 新增第 11 參數
// 1. 函數簽名新增 $first = 0
function discuzcode($message, $smileyoff, $bbcodeoff, $htmlon = 0,
$allowsmilies = 1, $allowbbcode = 1, $allowimgcode = 1, $allowhtml = 0,
$jammer = 0, $pid = 0, $authorid = 0, $first = 0) {
// 2. 全域變數引入插件配置
global $_G, $hide_config; // $hide_config 由 plugin 初始化載入
if (empty($hide_config)) {
require_once libfile('plugin/kj_hide', 'config'); // 載入 config.inc.php
$hide_config = kj_hide_config();
}
// 3. 核心邏輯:判斷是否需自動隱藏
$need_hide = false;
if ($hide_config['enable']) {
$fid = $_G['fid'];
// 版塊過濾
if ($hide_config['allow_forums'] && !in_array($fid, $hide_config['allow_forums'])) $need_hide = false;
elseif ($hide_config['deny_forums'] && in_array($fid, $hide_config['deny_forums'])) $need_hide = false;
else {
// 模式判斷
switch ($hide_config['mode']) {
case 1: $need_hide = (bool)$first; break; // 僅主題帖
case 2: $need_hide = true; break; // 全部
case 3: $need_hide = $first || $authorid != $_G['uid']; break; // 主題帖 + 非作者回覆
case 4: $need_hide = !$_G['uid']; break; // 遊客模式
}
}
}
// 4. 執行隱藏/預覽
if ($need_hide) {
$preview = $hide_config['preview_length'];
$msg_len = strlen($message);
if ($preview > 0 && $preview < $msg_len) {
// 產生預覽片段 (避開 BBCode 標籤截斷)
$preview_text = dhtmlspecialchars(cutstr($message, $preview));
$message = $preview_text . '
' . lang('plugin/kj_hide', 'hide_reply_hidden') . '';
} else {
// 完全隱藏
$message = '' . lang('plugin/kj_hide', 'hide_reply_hidden') . '';
}
// 作者/版主/回覆過用戶:顯示原文
$is_author = ($authorid == $_G['uid']);
$is_mod = $_G['forum']['ismoderator'];
$has_replied = false;
if (!$is_author && !$is_mod) {
$query = DB::query("SELECT pid FROM " . DB::table('forum_post') . " WHERE tid='{$_G['tid']}' AND authorid='{$_G['uid']}' LIMIT 1");
$has_replied = DB::result($query, 0);
}
if ($is_author || $is_mod || $has_replied) {
$message = $original_message; // 需在前面備份 $original_message = $message;
}
}
// 5. 原有 [hide] 標籤處理邏輯保持不變 (放在自動隱藏之後)
if (!in_array($parsetype, [1,2]) && preg_match("/\[hide=?\d*\].+?\[\/hide\]/is", $message)) {
// ... 原有 creditshide 處理 ...
}
<?php
$lang = [
'hide_reply' => '該內容已被隱藏,回覆本帖後可查看。',
'hide_reply_hidden' => '內容已隱藏,回覆後可見。',
'hide_limit' => '遊客只能預覽部分內容,完整內容請 登錄 或 註冊。',
];
問題:`cutstr()` 在 BBCode 標籤中間截斷 (如 `[url=...`、`[quote]`),導致頁面結構破壞。
| Discuz! 版本 | 掛點差異 | 注意事項 |
|---|---|---|
| X3.0 - X3.4 | `viewthread.php` 直接呼叫 `discuzcode()` | 直接修改參數列 |
| X3.5+ | 引入 `hook/viewthread_post_bottom` | 建議用 Hook 注入 `$post['first']`,免改核心,升級無痛 |
| X2.5 / 7.2 | 函數簽名參數順序不同 | 對照原始 `discuzcode` 簽名調整,原理相同 |
這個插件雖小,卻完整展示了 **Discuz! 插件開發的核心模式**:掛點注入 → 配置驅動 → 語言包國際化 → 核心邏輯隔離 → 相容性分層 → 安全效能雙顧。掌握此模式,你就能為任何 Discuz! 論壇快速交付高質量功能擴展。