利用短碼控制內容顯示:結合 MemberPress 權限判斷的實作範例

前言

在 WordPress 網站中,常見需求是根據使用者的會員權限來控制內容的顯示。這段 PHP 程式碼示範如何利用短碼(shortcode)結合 MemberPress 的存取規則,根據不同的權限狀態呈現不同內容。適合已有 WordPress 和 MemberPress 基礎,想自訂內容權限顯示的工程師或自學者。

短碼設計與參數說明

此短碼名稱為 ks_mepr_access_view,接受一個參數 type,用來決定顯示的內容類型:

  • public:公開內容,無需會員權限
  • member:會員專屬內容,需通過 MemberPress 規則授權
  • noaccess:未授權會員或訪客看到的內容

使用範例:

[ks_mepr_access_view type="member"]會員專屬內容[/ks_mepr_access_view]

權限判斷流程解析

取得文章與規則

$post = get_post();
$rules = MeprRule::get_rules($post);

先取得當前文章物件,再用 MemberPress API 取得該文章綁定的存取規則。

判斷使用者登入與權限

$user = wp_get_current_user();
$is_logged_in = is_user_logged_in();
$has_access = false;

if ($is_logged_in && !empty($rules)) {
    $member = new MeprUser($user->ID);
    foreach ($rules as $rule) {
        if ($member->has_access_from_rule($rule->ID)) {
            $has_access = true;
            break;
        }
    }
}

確認使用者是否登入,且文章有設定規則,接著檢查使用者是否符合任一規則,若符合即標記為有存取權限。

根據條件回傳內容

if (!$has_rule && $type === 'public') {
    return do_shortcode($content); // 無保護,公開內容
}

if ($has_rule && $has_access && $type === 'member') {
    return do_shortcode($content); // 有保護且有權限,顯示會員內容
}

if ($has_rule && !$has_access && $type === 'noaccess') {
    return do_shortcode($content); // 有保護但無權限,顯示無權限內容
}

return '';

依據是否有規則、是否有權限,以及 type 參數決定是否顯示內容,未符合條件則回傳空字串。

實務應用與擴充建議

  • 可用於文章、頁面或自訂文章類型中,靈活控制不同會員等級的內容呈現。
  • 可結合前端樣式或 JavaScript,提升使用者體驗,例如顯示提示訊息或引導登入。
  • 若需更複雜的權限判斷,可擴充短碼參數,或搭配其他會員系統 API。

常見問題與注意事項

  • 確保 MemberPress 已正確設定存取規則並綁定文章。
  • 使用者權限判斷依賴 MemberPress API,若插件更新需確認相容性。
  • 短碼內容內仍可使用其他短碼,do_shortcode 可確保內嵌短碼正常解析。

完整程式碼

<?php
function ks_mepr_access_view_shortcode($atts, $content = null) {
    $atts = shortcode_atts([
        'type' => 'public', // 可為 public, member, noaccess
    ], $atts);

    $post = get_post();
    if (!$post) {
        return '';
    }

    $type = strtolower($atts['type']);
    $rules = MeprRule::get_rules($post);
    $has_rule = !empty($rules);

    $user = wp_get_current_user();
    $is_logged_in = is_user_logged_in();
    $has_access = false;

    if ($is_logged_in && $has_rule) {
        $member = new MeprUser($user->ID);
        foreach ($rules as $rule) {
            if ($member->has_access_from_rule($rule->ID)) {
                $has_access = true;
                break;
            }
        }
    }

    // 顯示條件
    if (!$has_rule && $type === 'public') {
        return do_shortcode($content); // 沒有保護 → 公開
    }

    if ($has_rule && $has_access && $type === 'member') {
        return do_shortcode($content); // 有保護+通過 → 會員
    }

    if ($has_rule && !$has_access && $type === 'noaccess') {
        return do_shortcode($content); // 有保護+沒通過(不論登入與否)→ 無權限
    }

    return '';
}
add_shortcode('ks_mepr_access_view', 'ks_mepr_access_view_shortcode');