Điểm:0

Plugin khối tùy chỉnh: Cấp quyền truy cập để chỉnh sửa biểu mẫu

lá cờ in

Tôi đang tạo plugin khối tùy chỉnh với các tùy chọn cấu hình tùy chỉnh (khốiForm()).

Tôi muốn cho phép người chỉnh sửa nội dung chỉnh sửa cấu hình của khối này mà không cấp cho họ quyền "quản trị khối". Ngoài ra, tôi không muốn họ tạo các phiên bản khối mới..

Tôi muốn tránh cài đặt một mô-đun bổ sung như block_permissions, vì điều này sẽ giới thiệu một loạt các cài đặt hoặc quyền cho tất cả các khối, không chỉ khối cụ thể mà tôi đang tạo.

Tôi cũng không muốn đây là một khối "nội dung" với "các trường". Tôi muốn biết làm thế nào điều này có thể được thực hiện với một khối dựa trên plugin tùy chỉnh.

CHỈNH SỬA/CẬP NHẬT
(dựa trên câu trả lời và thảo luận)

Câu trả lời hiện có là ngay lập tức, nếu mục tiêu của bạn được mô tả trong câu hỏi.

Tuy nhiên, toàn bộ tiền đề có một vấn đề: Toàn bộ vị trí khối sẽ được xuất sang cấu hình và bị ghi đè khi triển khai. Điều này có nghĩa là mọi cài đặt do người dùng kiểm soát sẽ bị hủy trong lần phát hành tiếp theo. Vì vậy, điều này là không bền vững. Một thực thể khối nội dung có thể được sử dụng để cho phép phân chia thích hợp.

Điểm:1
lá cờ cn

Nếu người dùng không có quyền quản trị đối với một loại thực thể, điều này không có nghĩa là bạn không thể cho phép các hoạt động cụ thể trên các thực thể cụ thể hiện có.

Ví dụ: trình chỉnh sửa nội dung mà bạn đã cấp quyền quản lý nội dung cũng được phép cập nhật các khối của plugin khối tùy chỉnh của bạn:

sử dụng Drupal\block\Entity\Block;
sử dụng Drupal\Core\Access\AccessResult;
sử dụng Drupal\Core\Session\AccountInterface;

/**
 * Triển khai hook_ENTITY_TYPE_access() cho loại thực thể "khối".
 */
function mymodule_block_access(Khối $block, $operation, AccountInterface $account) {
  nếu ($hoạt động == 'cập nhật'
    && $block->getPluginId() == 'custom_block_plugin_id'
    // Điều kiện cuối cùng chỉ cần thiết nếu thủ thuật bên dưới được sử dụng với
    // `$block_entity->createDuplicate()->access('update')`.
    && $block->id() !== NULL
  ) {
    trả lại AccessResult::allowedIfHasPermission($account, 'quản lý các nút');
  }
  trả về AccessResult::neutral();
}

Bạn cũng cần thay đổi biểu mẫu để không chuyển hướng khi gửi tới trang mà người dùng không có quyền truy cập. Hoặc liên kết đến biểu mẫu chỉnh sửa bằng chuỗi truy vấn đích trỏ đến một trang khác.


(CHỈNH SỬA bởi @donquixote)

Nếu bạn muốn hạn chế quyền truy cập vào các thành phần khác trên trang, bạn có thể thực hiện như bên dưới.
Đây là một chút mong manh, bởi vì nó giả định một cấu trúc rất cụ thể của hình thức.

/**
 * Triển khai hook_form_FORM_ID_alter() cho 'block_form'.
 */
function mymodule_form_block_form_alter(mảng &$form, FormStateInterface $form_state, chuỗi $form_id) {
  $form_object = $form_state->getFormObject();
  if (!$form_object instanceof BlockForm) {
    trở lại;
  }
  /** @var Khối $block_entity */
  $block_entity = $form_object->getEntity();
  if ($block_entity->getPluginId() !== 'custom_block_plugin_id') {
    trở lại;
  }
  if ($block_entity->createDuplicate()->access('update')) {
    // Người dùng có quyền truy cập chung để cập nhật khối này.
    trở lại;
  }
  // Người dùng chỉ được cấp quyền truy cập qua mymodule_block_access().
  // Họ chỉ nên chỉnh sửa cài đặt plugin cụ thể, không thay đổi vị trí của plugin
  // khối được đặt.
  foreach (['visibility', 'id', 'weight', 'region'] as $key) {
    if (isset($form[$key])) {
      $form[$key]['#access'] = FALSE;
    }
  }
  foreach (['nhãn', 'nhãn_hiển thị'] là $key) {
    if (isset($form['settings'][$key])) {
      $form['settings'][$key]['#access'] = FALSE;
    }
  }
  foreach (['xóa'] dưới dạng khóa $) {
    if (isset($form['actions'][$key])) {
      $form['actions'][$key]['#access'] = FALSE;
    }
  }
}
lá cờ in
Cảm ơn, điều này hoạt động! Tuy nhiên, bây giờ tôi cũng cần `hook_form_block_form_alter()` để đặt `'#access' => FALSE` trên tất cả các thành phần mà tôi không muốn họ chỉnh sửa. Đó là hầu hết phần còn lại của hình thức này.
lá cờ in
Đích đến đã ổn rồi, bởi vì người dùng sẽ truy cập biểu mẫu này thông qua các liên kết theo ngữ cảnh.
lá cờ in
Rất tiếc, tôi đã cho rằng bạn sẽ phải xác nhận các chỉnh sửa..
lá cờ in
Hãy cho tôi biết nếu bản chỉnh sửa ổn, hoặc vui lòng sửa đổi nó. Tôi cũng có thể biến nó thành một câu trả lời riêng, nhưng tôi không muốn "ăn cắp" dấu kiểm "câu trả lời được chấp nhận".
4uk4 avatar
lá cờ cn
Nếu muốn, bạn có thể thay đổi trực tiếp các thành phần biểu mẫu trong plugin khối tùy chỉnh bằng cách ghi đè buildConfigurationForm().
lá cờ in
Điều này chỉ bao gồm các phần tử trong biểu mẫu con `$form['settings']`. Cài đặt khả năng hiển thị, vị trí khu vực và tùy chọn xóa khối vẫn cần được xử lý trong `hook_form_alter()`.
lá cờ in
Nhân tiện, `\Drupal::currentUser()->hasPermission('administer blocks')` hơi khó xử. Thay vào đó, tôi muốn kiểm tra xem người dùng _would_ có chặn quyền truy cập cập nhật hay không nếu nó không dành cho `hook_block_access()` tùy chỉnh.
4uk4 avatar
lá cờ cn
OK, do đó, móc thay đổi biểu mẫu dường như là cách dễ nhất để kiểm soát tất cả các phần tử biểu mẫu. Nếu bạn cần thực hiện nhiều điều chỉnh hơn tại một thời điểm, có thể cần phải mở rộng dạng khối. Tôi đã thấy trình tạo bố cục có rất nhiều dạng khối khác nhau cho các tác vụ khác nhau.
4uk4 avatar
lá cờ cn
Tôi nghĩ điều này ổn, thực thể cấu hình khối đang sử dụng thực thể đơn giản hóa này cho tất cả các quyền được xác định trong loại thực thể.
lá cờ in
'Khối quản trị' có thể không phù hợp khi sử dụng mô-đun bổ sung để kiểm soát truy cập chi tiết hơn. Tôi đã thêm một mẹo vào mã với `$block_entity->createDuplicate()->access('update')`. Điều này dường như thực hiện thủ thuật và cũng sẽ phá vỡ bộ nhớ cache, tôi hy vọng..
lá cờ in
Kết quả truy cập có được lưu trong bộ nhớ cache cho mỗi thực thể hay chúng tôi cần thêm một thẻ bộ nhớ cache khác?
lá cờ in
Tôi nhận thấy một vấn đề khác với điều này: Tất cả những thứ này được xuất sang cấu hình, vì vậy mọi thay đổi của người dùng sẽ bị ghi đè khi cấu hình được nhập vào lần triển khai tiếp theo. Bây giờ tôi gần như bị thuyết phục rằng đây là cách làm sai và tôi thực sự nên sử dụng khối nội dung..

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.