Bagaimana cara menetapkan akses ke blok secara terprogram?

10

Saya telah membuat blok secara terprogram tetapi saya tidak tahu bagaimana saya bisa secara terprogram menentukan aksesnya. Bagaimana saya bisa mencapainya?

user5013
sumber
Bisakah Anda memperluas pertanyaan dan menunjukkan kode Anda?
Triskelion
Dalam kode blok itu sendiri Anda dapat mencari pengguna (pengguna $ global) dan memeriksa peran mereka menggunakan metode dalam tautan. bywombats.com/blog/ryan/10-25-2007/…
user6614
Modul Panel memiliki beberapa kontrol akses hebat menggunakan wilayah, bukan blok.
Louis

Jawaban:

10

Mengatur array "peran" dalam array yang dikembalikan dari hook_block_info()tidak berfungsi karena:

  • Peran yang diizinkan untuk melihat blok, dan yang diatur dalam antarmuka pengguna, disimpan dari block_admin_configure_submit () di tabel "block_role"

    $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();
  • Kode yang memutuskan blok mana yang harus ditampilkan kepada pengguna yang saat ini login terdapat di block_block_list_alter () , yang merupakan implementasi dari hook_block_list_alter () , dan hanya menggunakan konten dari tabel itu

    $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;
      }
    
      // …
    
    }
  • Tidak ada fungsi Drupal lain yang memeriksa properti peran dalam data yang dikembalikan hook_block_info(), juga konten tabel "block_role" digabung dengan apa yang dikembalikan dari hook_block_info()implementasi.

Anda dapat memverifikasi bahwa pengguna memiliki peran yang diperlukan untuk melihat blok tersebut hook_block_view(), tetapi pada saat itu Drupal sudah merender blok tersebut; itu berarti pengguna masih akan melihat judul blokir, jika sudah ditetapkan.

Yang dapat Anda lakukan adalah menerapkan hook_block_list_alter()untuk menghapus informasi tentang blok itu ketika pengguna tidak memiliki peran yang diperlukan.
Untuk menghindari kebingungan bagi pengguna yang mengelola blok, saya juga akan mengubah formulir yang digunakan untuk mengedit blok, dan menonaktifkan bidang formulir yang digunakan untuk mengatur peran mana yang dapat melihat blok itu, karena modul yang mengimplementasikannya akan menggunakan daftar sendiri. peran; kode minimal setidaknya harus menampilkan pesan tentang pengaturan peran yang tidak memiliki efek apa pun, tetapi saya juga akan menonaktifkan elemen formulir untuk pengaturan peran.

Karena modul Blok sudah memperlihatkan kolom formulir untuk memilih peran mana yang melihat blok, Anda juga bisa cukup menetapkan default untuk blok Anda, dan biarkan pengguna administrator mengubahnya jika perlu.

tangkapan layar

Seperti memeriksa peran yang dimiliki pengguna versus memeriksa izin yang dimiliki pengguna, yang terakhir lebih disukai, terutama ketika alternatifnya adalah pengodean keras daftar peran dalam modul.
Seperti yang ditunjukkan dari modul Block, menggunakan izin bukan satu-satunya alternatif: Modul dapat memiliki pengaturan untuk memutuskan peran mana yang diizinkan untuk melihat sesuatu.
Jelas, tidak selalu layak memiliki pengaturan yang perannya diizinkan untuk melakukan sesuatu. Saya membayangkan juga apa artinya bagi pengguna administrator jika 10 modul akan memiliki pengaturan sendiri untuk peran yang diizinkan untuk melakukan sesuatu, alih-alih menggunakan izin, dan memungkinkan pengguna administrator untuk menggunakan satu halaman untuk mengaturnya.

kiamlaluno
sumber
Yah saya jelas harus pergi dengan yang satu ini sebagai jawaban yang paling tepat. Terima kasih atas penjelasan terperinci karena sangat membantu untuk memahami bagaimana blok Drupal bekerja di belakang layar.
user5013
1

Di hook_block_info, Anda dapat mencoba sesuatu seperti:

$blocks['myblock'] = array(
   ...
   'roles' => array(
      'administrator' => '3',
      'authenticated user' => '2',
   )
Triskelion
sumber
Ini sepertinya cara terbaik untuk mengimplementasikan ini menggunakan pendekatan program saat Anda mendefinisikan peran mana yang memiliki akses dan kemudian membiarkan Drupal menentukan apakah pengguna dapat mengaksesnya atau tidak. Apakah saya kehilangan kelemahan untuk pendekatan ini?
user5013
Jika Anda harus melakukannya secara terprogram, ya. Tidak ada downside. Namun saya akan berasumsi akan ada kasus penggunaan yang sangat baik terhadap hanya pergi ke / admin / struktur / blok dan menetapkan peran ke blok.
Triskelion
Kasing akan secara otomatis melakukan pengaturan untuk pengguna sehingga mereka tidak perlu melakukannya. Masalah kenyamanan yang sebenarnya. Setelah diatur, mereka kemudian dapat mengubahnya sesuai dengan yang mereka inginkan jika tidak sesuai dengan kebutuhan khusus mereka.
user5013
1
Ini tidak berfungsi; lihat jawaban saya mengapa tidak.
kiamlaluno
0

Dengan asumsi bahwa Anda membuat blok sendiri dengan hook_block_info () maka Anda bisa melakukan user_access () di fungsi hook_block_view () Anda. Lihat dokumen api karena mereka punya contohnya.

jdwfly
sumber
Ya, saya seharusnya berpikir untuk menggunakan user_access. Benar-benar menyelinap dalam pikiranku - Doh. Saya berpikir tentang menggunakan akses peran tetapi mungkin akses izin mungkin merupakan cara yang lebih baik.
user5013
0

Tidak mungkin di hook_block_info (), tetapi Anda bisa menggunakan kueri ini untuk mencapainya. Ubah MODULE_NAME, BLOCK_DELTA, dan RID sesuai

$query = db_insert('block_role')
  ->fields(array(
    'module' => 'MODULE_NAME', 
    'delta' => 'BLOCK_DELTA', 
    'rid' => 2, // Authenticated User
  ))
  ->execute();
Paul Bönisch
sumber
0

Di hook_block_view, Anda dapat menggunakan global $useruntuk mendapatkan informasi tentang pengguna, kemudian berdasarkan peran pengguna Anda dapat menetapkan yang berbeda block['subject']dan block['content']atau bahkan tidak menetapkan subjek dan konten apa pun untuk diblokir jika tidak akan terlihat untuk peran itu. berikut ini sebuah contoh:

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;
}

menggunakan kode ini pengguna yang diautentikasi (bukan tamu) akan memiliki blok yang terlihat oleh pengguna yang diautentikasi.

Alireza Tabatabaeian
sumber