プログラムでブロックを作成しましたが、プログラムでブロックにアクセスを割り当てる方法がわかりません。どうすればそれを達成できますか?
hook_block_info()
から返された配列に「roles」配列を設定すると、次の理由で機能しません。
ブロックの表示を許可され、ユーザーインターフェースで設定されるロールは、「block_role」テーブルの 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;
}
// …
}
hook_block_info()
から返されたデータのrolesプロパティをチェックする別のDrupal関数はありません。また、「block_role」テーブルの内容は、hook_block_info()
実装から返されたものとマージされません。
ユーザーがhook_block_view()
でブロックを表示するために必要な役割を持っていることを確認できますが、その時点でDrupalはすでにブロックをレンダリングしているため、ユーザーは引き続きブロックを表示しますタイトル(既に設定されている場合)。
あなたができることは、hook_block_list_alter()
を実装して、ユーザーが必要な役割を持っていないときにそのブロックに関する情報を削除することです。
ブロックを管理するユーザーの混乱を避けるために、ブロックを編集するために使用されるフォームを変更し、そのブロックを表示できるロールを設定するために使用されるフォームフィールドを無効にします。独自の役割のリストを使用する。最小限のコードでは、役割の設定が何の効果もないというメッセージを少なくとも表示する必要がありますが、役割の設定のフォーム要素も無効にします。
ブロックモジュールにはすでにブロックを表示するロールを選択するフォームフィールドが表示されているため、ブロックのデフォルトを設定して、必要に応じて管理者ユーザーが変更できるようにすることもできます。
ユーザーが持つ役割をチェックすることと、ユーザーが持つ権限をチェックすることの両方に関して、最後の方法が推奨されます。特に、代替手段がモジュール内のロールのリストをハードコーディングする場合はそうです。
Blockモジュールからわかるように、許可を使用することが唯一の代替手段ではありません。モジュールは、どのロールが何かを見ることを許可されるかを決定するための設定を持つことができます。
明らかに、どのロールが何かを実行できるかを設定することは常に価値があるとは限りません。また、10個のモジュールに、権限を使用する代わりに役割が何かを実行するための独自の設定を持ち、管理者ユーザーが単一のページを使用してそれらを設定できるようにする場合、管理者ユーザーにとって何が意味するかについても想像します。
あなたのhook_block_infoであなたは次のようなことを試すことができます:
$blocks['myblock'] = array(
...
'roles' => array(
'administrator' => '3',
'authenticated user' => '2',
)
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;
}
このコードを使用すると、認証されたユーザー(ゲストではない)が、認証されたユーザーに対してブロックされます。
Hook_block_info()では不可能ですが、このクエリを使用してこれを実現できます。 MODULE_NAME、BLOCK_DELTA、RIDを適宜変更します
$query = db_insert('block_role')
->fields(array(
'module' => 'MODULE_NAME',
'delta' => 'BLOCK_DELTA',
'rid' => 2, // Authenticated User
))
->execute();
Hook_block_info()を使用して自分でブロックを作成していると仮定すると、hook_block_view()関数でuser_access()を実行できます。 api docs を確認してください。この例があるからです。