判断是否满足某个操作权限 "view" "update" "delete" "create"

node_access($op, $node, $account = NULL);

定制NODE访问权

定制权限需要使用hook_node_access_records与hook_node_grants
hook_node_grants为每个user定义realm和gid
hook_node_access_records为每个node定义realm和gid及访问权
如果user与node的realm和gid吻合,定制的访问权就会生效

function hook_node_grants($account, $op) {
  if (user_access('access private content', $account)) {
    $grants['example'] = array(1);
  }
  $grants['example_author'] = array($account->uid);
  return $grants;
}
function hook_node_access_records($node) {
  // We only care about the node if it has been marked private. If not, it is
  // treated just like any other node and we completely ignore it.
  if ($node->private) {
    $grants = array();
    // Only published nodes should be viewable to all users. If we allow access
    // blindly here, then all users could view an unpublished node.
    if ($node->status) {
      $grants[] = array(
        'realm' => 'example',
        'gid' => 1,
        'grant_view' => 1,
        'grant_update' => 0,
        'grant_delete' => 0,
        'priority' => 0,
      );
    }
    // For the example_author array, the GID is equivalent to a UID, which
    // means there are many groups of just 1 user.
    // Note that an author can always view his or her nodes, even if they
    // have status unpublished.
    $grants[] = array(
      'realm' => 'example_author',
      'gid' => $node->uid,
      'grant_view' => 1,
      'grant_update' => 1,
      'grant_delete' => 1,
      'priority' => 0,
    );

    return $grants;
  }
}

hook_node_access_records在node_access_rebuild()时被激活,会直接写入数据表node_access,在下次rebuild之前不会再被调用。hook_node_grants在用户登录后被激活,直接与node_access数据进行匹配。

通俗说明,hook_node_access_records就是为node设置锁孔,hook_node_grants是使用user手上的钥匙配对node锁孔的过程。node_access表即是存储锁孔的表,access rebuild时会把node_access表清空,再以hook_node_access_records作为工厂来生成锁孔。

直接写入权限声明

$record = array(
  'nid' => 0,
  'gid' => 888,
  'realm' => 'example_realm',
  'grant_view' => 1,
  'grant_update' => 0,
  'grant_delete' => 0,
);
drupal_write_record('node_access', $record);
  • gid的意义由module决定,它可以是role id,也可以是user id。

  • 权限声明可以用hook_node_grants()实现,但需要使用node_access_rebuild()才会入库

  • 如果需要马上写入node_access,可用node_access_write_grants()

if ($op == 'view') {
  $grants['example_realm'] = array(888);
}

让DB Query识别权限

$query = db_select('node', 'n')->addTag('node_access');

hook_node_grants与hook_node_access的不同之处

hook_node_grants不只是在node full view生效,在views list与menu上也同样生效,没有权限的node不会出现在node和menu中。
hook_node_access只作用于menu,是node_access的扩展功能。由于node的access callback指向node_access,所以hook_node_access直接影响MENU的可见性。
所以如果想彻底让NODE不可见,可以使用hook_node_grants与hook_node_access_records,否则可以使用hook_node_access

hook_node_grants 适合实现NODE VIEW权限
hook_node_access 适合实现NODE CREATE, UPDATE, DELETE

menu access

/* Implements hook_menu_alter(). */
function mymodule_menu_alter(&$items) {
    $items['node/%/edit']['access callback'] = 'mymodule_access_callback';
    $items['training/course/%/files-download']['access arguments'] = array(2);
}

node_access_acquire_grants

如果通过程序更新了NODE,但又需要同时更新它的权限,需要执行node_access_acquire_grants($node);

views custom access

在module里实现hook_views_plugins

/* Implements hook_views_plugins() */
function mymodule_views_plugins() {
$plugins = array(    
'access' => array(      
'nwst' => array(        
'title' => t('Custom Access'),        
'help' => t('this is a custom access plugin'),        
'handler' => 'mymodule_access_plugin',        
'path' => drupal_get_path('module', 'mymodule'),    
  ),  
  ), 
 );  return $plugins;
}

创建一个程序mymodule_access_plugin.inc代码如下:

/** Access plugin that provides router item-based access control.
* @ingroup views_access_plugins
*/
class mymodule_access_plugin extends views_plugin_access {
    function access($account) {    
        // your code    return true;  
    }
}

需要在mymodule.info包含它:
files[] = mymodule_access_plugin.inc

参考:http://dominiquedecooman.com/...


猫之良品
2.5k 声望139 粉丝

资深Drupal, magento与Joomla


引用和评论

0 条评论