Drupal 客製化選單權限

在 Drupal 中,我們可以透過「角色」與「權限」的設計為網站建構出一個安全的使用環境,當核心模組提供的權限設定不符合需求時,我們還可以透過 Drupal 提供豐富的 API 來完成,本篇文章來為大家介紹如何透過客製化模組來自訂選單權限。

 

客製化選單權限

假設我們使用一個 Drupal 建立了包含主網域與數個子網域的網站,在這樣的情境下,通常會需要做更細緻的權限控管,這次我們以限定子網域是「sub.example.org」且角色為「Content Editor」或「Site Administrator」才有權限進行選單管理。

首先,我們先建立一個客製化模組(這裡以 Drupal 7 為例)的 .info ,由於本次我們是透過 Domain 模組來管理網域,客製化程式也會使用到相關函式,因此相依性要記得設定。

name = MY_MODULE_NAME
description = Limits menu management access based on roles and domain settings.
core = 7.x
package = Custom
dependencies[] = domain

 

接著來撰寫允許網域的檢查函式,我們可以先建立一個網域的白名單,將目前的網域與其比對。

/**
 * Checks if the current domain is in the allowed domains list.
 *
 * @return bool
 *   TRUE if the current domain is allowed, otherwise FALSE.
 */
function _MY_MODULE_NAME_allowed_domain() {
  $allowed_domains = array('sub.example.org');

  $current_domain = domain_get_domain();
  return in_array($current_domain['subdomain'], $allowed_domains);
}

 

接下來我們會建立一個檢查權限的函式,在這個函式中,我們會檢查使用者是否符合權限授予的條件,包含網域與角色的檢查。

/**
 * Custom access callback.
 */
function _MY_MODULE_NAME_access_check($menu) {
  $account = user_load($GLOBALS['user']->uid);

  // Always return TRUE for user 1 (the super admin).
  if ($account->uid == 1) {
    return TRUE;
  }

  // Check for specific roles.
  if (array_intersect(array('Content Editor', 'Site Administrator'), $account->roles)) {
    if (_MY_MODULE_NAME_allowed_domain()) {
      // Check user access to the domain
      $domain = domain_get_domain();
      $user_domain_access_list = domain_get_user_domains($account, FALSE);
      return isset($user_domain_access_list[$domain['domain_id']]);
    }
  }
  
  // Default to no access
  return FALSE;
}

 

最後,我們會需要透過 Drupal 提供的 hook_menu_alter 來進行選單權限的客製化設定。首先我們可以將選單相關路徑先逐一列出,接著透過迴圈來改寫每個路徑的「access callback」,「access callback」的對應函式就是我們上面撰寫好的「_MY_MODULE_NAME_access_check」,這樣就完成了!

/**
 * Implements hook_menu_alter().
 */
function MY_MODULE_NAME_menu_alter(&$items) {
  $restricted_paths = array(
    'admin/structure/menu/manage/%menu',
    'admin/structure/menu/manage/%menu/add',
    'admin/structure/menu/item/%menu_link/edit',
    'admin/structure/menu/item/%menu_link/reset',
    'admin/structure/menu/item/%menu_link/delete',
  );

  foreach ($restricted_paths as $path) {
    $items[$path]['access callback'] = '_MY_MODULE_NAME_access_check';
    $items[$path]['access arguments'] = array(4);
  }
}

 

同場加映

如果只是要單純將每一個選單的權限拆開來設定可以使用 Menu Admin per Menu 模組。

 

* 本文首張圖片由 Ideogram 生成

文章分類: