我已经以编程方式创建了一个块,但是我不知道如何以编程方式分配对该块的访问。我该如何实现?
我已经以编程方式创建了一个块,但是我不知道如何以编程方式分配对该块的访问。我该如何实现?
Answers:
在从返回的数组中设置“角色”数组hook_block_info()
不起作用,因为:
从用户块中的block_admin_configure_submit()中保存了允许查看块以及在用户界面中设置的角色。
$query = db_insert('block_role')->fields(array('rid', 'module', 'delta'));
foreach (array_filter($form_state['values']['roles']) as $rid) {
$query->values(array(
'rid' => $rid,
'module' => $form_state['values']['module'],
'delta' => $form_state['values']['delta'],
));
}
$query->execute();
决定应向当前登录用户显示哪些块的代码包含在block_block_list_alter()中,该代码是hook_block_list_alter()的实现,并且仅使用该表的内容
$result = db_query('SELECT module, delta, rid FROM {block_role}');
foreach ($result as $record) {
$block_roles[$record->module][$record->delta][] = $record->rid;
}
foreach ($blocks as $key => $block) {
if (!isset($block->theme) || !isset($block->status) || $block->theme != $theme_key || $block->status != 1) {
// This block was added by a contrib module, leave it in the list.
continue;
}
// If a block has no roles associated, it is displayed for every role.
// For blocks with roles associated, if none of the user's roles matches
// the settings from this block, remove it from the block list.
if (isset($block_roles[$block->module][$block->delta]) && !array_intersect($block_roles[$block->module][$block->delta], array_keys($user->roles))) {
// No match.
unset($blocks[$key]);
continue;
}
// …
}
没有另一个Drupal函数检查从返回的数据中的role属性,hook_block_info()
“ block_role”表的内容也不会与hook_block_info()
实现返回的内容合并。
您可以验证用户是否具有查看中的块所需的角色hook_block_view()
,但是那时Drupal已经在渲染该块;这意味着如果已经设置,则用户仍会看到块标题。
您可以做的就是hook_block_list_alter()
在用户没有所需角色时实现删除有关该块的信息。
为了避免与管理区块的用户混淆,我还将更改用于编辑区块的表单,并禁用用于设置哪些角色可以看到该区块的表单字段,因为实现该区块的模块将使用自己的列表角色;最少的代码至少应该显示一条有关角色设置没有任何作用的消息,但是我还将禁用角色设置的表单元素。
由于“阻止”模块已经显示了表单字段,用于选择查看角色的角色,因此您也可以简单地为阻止设置默认值,并让管理员用户在必要时进行更改。
根据检查用户所具有的角色与检查用户所具有的权限相比,最后一个方法更为可取,尤其是当备选方法是对模块中的角色列表进行硬编码时。
如“阻止”模块所示,使用权限不是唯一的选择:模块可以具有用于确定允许哪些角色看到内容的设置。
显然,设置角色被允许执行某项操作并不总是值得的。我想对于管理员用户来说,如果10个模块具有自己的设置,这些角色允许角色执行某些操作(而不使用权限),并允许管理员用户使用单个页面进行设置,这对于管理员用户来说意味着什么。
在您的hook_block_info中,您可以尝试以下操作:
$blocks['myblock'] = array(
...
'roles' => array(
'administrator' => '3',
'authenticated user' => '2',
)
假设您是使用hook_block_info()自己制作块,则可以在hook_block_view()函数中执行user_access()。查看api文档,因为他们有此示例。
在hook_block_view中,您可以global $user
用来获取有关用户的信息,然后根据用户的角色,您可以分配不同的对象block['subject']
,block['content']
甚至不分配任何要阻止的主题和内容(如果该角色对于该角色而言是不可见的)。这是一个例子:
function ModuleNAME_block_view($delta = '') {
switch ($delta) {
case 'Your_BLOCK' :
Global $user;
if($user->uid != '0') {
$block['subject'] = 'SUBJECT';
$block['content'] = 'SOME CONTENT OR A FUNCTION FOR BLOCK';
}
break;
}
return $block;
}
使用此代码,经过身份验证的用户(而非访客)将对已身份验证的用户可见块。