WordPress 外掛開發、阻擋使用者停止特定外掛、進階 WordPress 外掛管理

累計人氣:27

WordPress 網站的外掛權限管理比較簡單,例如說:使用者能如果有停止外掛的權限,他就能停止網站上所有的外掛。但有時候網站希望讓使用者只能停止部分外掛,有些特殊功能的外掛我們不希望被無預警停止,例如寄 email,這時候就需要一些手法去阻擋,避免重要功能失效,使用者卻不知道是自己造成的情況。

記錄一下至今嘗試過的方法,踩過的坑不少,希望能幫到大家~

用現成外掛方法

目前試過多個現成外掛,但沒有找到合適的能夠同時兼顧「權限控管」、「特定外掛只能被特定使用者停止」的功能。

自己寫外掛處理

隱藏外掛的停止選項

這個方法有兩個大漏洞:

  1. 使用者可以通過 JetPack APP 去觀看到所有外掛,進而停止它。
  2. 可以用批次方式停止外掛。

▶ 部分外掛無法停用
file

▶ 還是可以批次停用
file

▶ APP 上能夠看到外掛
7C40852A 068C 49D9 AF90 C2ADA4757471 scaled

// 定義要保護的外掛檔名
const PROTECTD_PLUGINS = array(
    'redis-cache/redis-cache.php'
);

// 使用者無法從外掛頁面看到部分外掛的停止連結
add_filter('plugin_action_links', function ($actions, $plugin_file) {

    if (is_super_admin())
        return $actions;
    if (in_array($plugin_file, PROTECTD_PLUGINS)) {
        unset($actions['deactivate']);
    }
    return $actions;
}, 10, 2);

隱藏外掛

的確可以有效避免使用者在網頁上把重要外掛停掉,但是使用者可以通過 JetPack APP 去觀看到所有外掛,進而停止它。

const HIDE_PLUGINS = array(
    'adminimize/adminimize.php',
    'wp-smushit/wp-smush.php',
);

// 從外掛清單隱藏特定外掛 for 不是 admin
function hide_plugin_firstsun()
{
    if (is_super_admin())
        return;
    global $wp_list_table;
    $myplugins = $wp_list_table->items;
    foreach ($myplugins as $key => $val) {
        if (in_array($key, HIDE_PLUGINS)) {
            unset($wp_list_table->items[$key]);
        }
    }
}
add_action('pre_current_active_plugins', 'hide_plugin_firstsun');

增加 deactive_hook 的權限檢查

問題算是卡了一陣子才解決。
後來研究一陣子 WordPress 開發手冊,看了各種 hook 用法,覺得以下做法應該可行:

幫要保護的外掛註冊 hook functon,那隻 function 會檢查操作者是不是管理者,如果不是就跳錯誤訊息,並停止動作。

只需要在自己寫的外掛中加入以下程式即可 (如果要偷懶也可以寫在佈景主題的 functions.php中)。

// 定義要保護的外掛檔名
const PROTECTD_PLUGINS = array(
    'redis-cache/redis-cache.php'
);

// 使用者無法從外掛頁面看到部分外掛的停止連結
add_filter('plugin_action_links', function ($actions, $plugin_file) {

    if (is_super_admin())
        return $actions;
    if (in_array($plugin_file, PROTECTD_PLUGINS)) {
        unset($actions['deactivate']);
    }
    return $actions;
}, 10, 2);

// 禁止不是管理員停止保護的外掛
function protect_plugins_from_non_admin_deactive()
{
    if (!is_super_admin()) {
        wp_die("您沒有停止此外掛的權限", "無權限", 403);
    }
}

function init_protection_hooks()
{
    foreach (PROTECTD_PLUGINS as $plugin) {
        if (function_exists('protect_plugins_from_non_admin_deactive')) {
            register_deactivation_hook($plugin, 'protect_plugins_from_non_admin_deactive');
        }
    }
}
add_action('init', 'init_protection_hooks');

成果展示

▶ 阻擋在網頁上停止外掛
file

▶ 阻擋在 APP 上停止外掛
4EBF4440 6F99 428B BFD1 D8064A57E4F6 scaled

心得

這算是藥藥上手 WordPress 外掛開發的敲門磚,覺得最大困難點在於要讀懂 [WordPress 官方開發手冊](Hooks | Plugin Developer Handbook | WordPress Developer Resources hooks 觸發時機的描述,也是當中花最多時間 debug 的地方。
還有一些用法像是 wp_die("您沒有停止此外掛的權限", "無權限", 403);這種的,則是參考其他人的外掛去寫,感覺可以多看別人的外掛怎麼寫,當作借鏡。

如果有任何指教或問題,歡迎交流討論。

分享
藥藥
藥藥

一個兼具理性與感性的程式設計師,深耕於再生能源應用、研究網路通訊、資料中心建置。

喜愛追求心靈成長,也關注科學、電腦資訊領域的發展。

想在這個美好的空間與大家分享我對於生命的體悟、精油、畫畫、以及我在專業領域上解決了哪些問題。

如果您喜歡我的文章,歡迎在附上原始連結的情況下,轉載到其他地方。

聯絡我:[email protected]

文章: 20

2 則留言

我想說說話