Score:0

ปลั๊กอินบล็อกที่กำหนดเอง: ให้สิทธิ์ในการแก้ไขแบบฟอร์ม

ธง in

ฉันกำลังสร้างปลั๊กอินบล็อกแบบกำหนดเองพร้อมตัวเลือกการกำหนดค่าแบบกำหนดเอง (บล็อกฟอร์ม()).

ฉันต้องการอนุญาตให้ผู้แก้ไขเนื้อหาแก้ไขการกำหนดค่าของบล็อกนี้โดยไม่ต้องให้สิทธิ์ "ผู้ดูแลระบบบล็อก" นอกจากนี้ ฉันไม่ต้องการให้พวกเขาสร้างอินสแตนซ์บล็อกใหม่

ฉันต้องการหลีกเลี่ยงการติดตั้งโมดูลเพิ่มเติมเช่น block_permissionsเนื่องจากจะเป็นการแนะนำการตั้งค่าหรือการอนุญาตที่หลากหลายสำหรับบล็อกทั้งหมด ไม่ใช่แค่เฉพาะบล็อกที่ฉันกำลังสร้าง

ฉันไม่ต้องการให้สิ่งนี้เป็นบล็อก "เนื้อหา" ที่มี "ฟิลด์" ฉันต้องการทราบว่าสิ่งนี้สามารถทำได้ด้วยบล็อกที่ใช้ปลั๊กอินที่กำหนดเองได้อย่างไร

แก้ไข / ปรับปรุง
(ขึ้นอยู่กับการตอบสนองและการอภิปราย)

คำตอบที่มีอยู่นั้นตรงประเด็น หากเป้าหมายของคุณเป็นไปตามที่อธิบายไว้ในคำถาม

อย่างไรก็ตาม สมมติฐานทั้งหมดมีปัญหาเดียว: ตำแหน่งบล็อกทั้งหมดจะถูกส่งออกไปยังการกำหนดค่า และถูกเขียนทับในการปรับใช้ ซึ่งหมายความว่าการตั้งค่าที่ควบคุมโดยผู้ใช้จะถูกทำลายในรุ่นถัดไป สิ่งนี้จึงไม่ยั่งยืน สามารถใช้เอนทิตีบล็อกเนื้อหาเพื่ออนุญาตให้มีการแบ่งที่เหมาะสมได้

Score:1
ธง cn

หากผู้ใช้ไม่มีสิทธิ์ระดับผู้ดูแลระบบสำหรับประเภทเอนทิตี ไม่ได้หมายความว่าคุณไม่สามารถอนุญาตการดำเนินการบางอย่างกับเอนทิตีที่มีอยู่เฉพาะได้

ตัวอย่างเช่น โปรแกรมแก้ไขเนื้อหาที่คุณให้สิทธิ์ในการจัดการเนื้อหายังได้รับอนุญาตให้อัปเดตบล็อกของปลั๊กอินบล็อกที่กำหนดเองของคุณ:

ใช้ Drupal\block\Entity\Block;
ใช้ Drupal\Core\Access\AccessResult;
ใช้ Drupal\Core\Session\AccountInterface;

/**
 * ใช้ hook_ENTITY_TYPE_access() สำหรับเอนทิตีประเภท "บล็อก"
 */
ฟังก์ชัน mymodule_block_access (บล็อก $block, $operation, AccountInterface $account) {
  ถ้า ($operation == 'อัปเดต'
    && $block->getPluginId() == 'กำหนดเอง_block_plugin_id'
    // เงื่อนไขสุดท้ายจำเป็นก็ต่อเมื่อใช้เคล็ดลับจากด้านล่างกับ
    // `$block_entity->createDuplicate()->การเข้าถึง('update')`
    && $block->id() !== NULL
  ) {
    ส่งคืน AccessResult::allowedIfHasPermission($account, 'administer nodes');
  }
  กลับ AccessResult::เป็นกลาง ();
}

คุณต้องแก้ไขแบบฟอร์มไม่ให้เปลี่ยนเส้นทางเมื่อส่งไปยังหน้าที่ผู้ใช้ไม่มีสิทธิ์เข้าถึง หรือลิงก์ไปยังแบบฟอร์มแก้ไขด้วยสตริงข้อความค้นหาปลายทางที่ชี้ไปยังหน้าอื่น


(แก้ไขโดย @donquixote)

หากคุณต้องการจำกัดการเข้าถึงองค์ประกอบอื่นๆ บนเพจ คุณสามารถทำได้ดังนี้
สิ่งนี้ค่อนข้างเปราะบางเล็กน้อย เนื่องจากถือว่ามีโครงสร้างเฉพาะของแบบฟอร์ม

/**
 * ใช้ hook_form_FORM_ID_alter() สำหรับ 'block_form'
 */
ฟังก์ชัน mymodule_form_block_form_alter (อาร์เรย์ &$form, FormStateInterface $form_state, สตริง $form_id) {
  $form_object = $form_state->getFormObject();
  ถ้า (!$form_object อินสแตนซ์ของ BlockForm) {
    กลับ;
  }
  /** @var บล็อก $block_entity */
  $block_entity = $form_object->getEntity();
  ถ้า ($block_entity->getPluginId() !== 'custom_block_plugin_id') {
    กลับ;
  }
  ถ้า ($block_entity->createDuplicate()->การเข้าถึง('อัปเดต')) {
    // ผู้ใช้มีสิทธิ์ทั่วไปในการอัปเดตบล็อคนี้
    กลับ;
  }
  // ผู้ใช้ได้รับสิทธิ์เข้าถึงผ่าน mymodule_block_access() เท่านั้น
  // พวกเขาควรแก้ไขการตั้งค่าปลั๊กอินเฉพาะเท่านั้น ไม่เปลี่ยนตำแหน่ง
  // วางบล็อกแล้ว
  foreach (['visibility', 'id', 'weight', 'region'] เป็น $key) {
    ถ้า (isset($form[$key])) {
      $form[$key]['#access'] = FALSE;
    }
  }
  foreach (['label', 'label_display'] เป็น $key) {
    ถ้า (isset($form['settings'][$key])) {
      $form['settings'][$key]['#access'] = FALSE;
    }
  }
  foreach (['ลบ'] เป็น $key) {
    ถ้า (isset($form['actions'][$key])) {
      $form['actions'][$key]['#access'] = FALSE;
    }
  }
}
in flag
ขอบคุณ มันได้ผล! อย่างไรก็ตาม ตอนนี้ฉันต้องการ `hook_form_block_form_alter()` เพื่อตั้งค่า `'#access' => FALSE` ในองค์ประกอบทั้งหมดที่ฉันไม่ต้องการให้แก้ไข ซึ่งเป็นส่วนที่เหลือส่วนใหญ่ของแบบฟอร์มนี้
in flag
ปลายทางนั้นใช้ได้อยู่แล้ว เนื่องจากผู้ใช้จะเข้าถึงแบบฟอร์มนี้ผ่านลิงก์ตามบริบท
in flag
อ๊ะ ฉันเดาว่าคุณจะต้องยืนยันการแก้ไข..
in flag
แจ้งให้เราทราบหากแก้ไขได้ หรือปรับเปลี่ยนได้ตามสะดวก ฉันสามารถแยกคำตอบได้ แต่ฉันไม่ต้องการ "ขโมย" เครื่องหมายถูก "คำตอบที่ยอมรับ"
4uk4 avatar
cn flag
คุณสามารถแก้ไของค์ประกอบของฟอร์มในบล็อกปลั๊กอินแบบกำหนดเองได้โดยตรงโดยการแทนที่ buildConfigurationForm()
in flag
ซึ่งครอบคลุมเฉพาะองค์ประกอบภายในฟอร์มย่อย `$form['settings']` เท่านั้น การตั้งค่าการมองเห็น ตำแหน่งภูมิภาค และตัวเลือกในการลบบล็อกยังคงต้องได้รับการจัดการใน `hook_form_alter()`
in flag
Btw `\Drupal::currentUser()->hasPermission('administer Blocks')` ค่อนข้างอึดอัด ฉันต้องการตรวจสอบว่าผู้ใช้ _would_ มีการเข้าถึงการอัปเดตบล็อกหรือไม่ หากไม่ใช่สำหรับ `hook_block_access()` ที่กำหนดเอง
4uk4 avatar
cn flag
ตกลง ดังนั้นตะขอแก้ไขแบบฟอร์มน่าจะเป็นวิธีที่ง่ายที่สุดในการควบคุมองค์ประกอบของแบบฟอร์มทั้งหมด หากคุณต้องการปรับแต่งเพิ่มเติม ณ จุดใดจุดหนึ่ง อาจจำเป็นต้องขยายรูปแบบบล็อก ฉันเห็นว่าตัวสร้างเลย์เอาต์มีรูปแบบบล็อกที่แตกต่างกันมากมายสำหรับงานต่างๆ
4uk4 avatar
cn flag
ฉันคิดว่ามันใช้ได้ เอนทิตีการกำหนดค่าบล็อกกำลังใช้อันที่เรียบง่ายนี้สำหรับการอนุญาตทั้งหมดที่กำหนดไว้ในประเภทเอนทิตี
in flag
'บล็อกการจัดการ' อาจไม่เหมาะเมื่อใช้โมดูลเพิ่มเติมสำหรับการควบคุมการเข้าถึงที่ละเอียดมากขึ้น ฉันเพิ่มเคล็ดลับในโค้ดด้วย `$block_entity->createDuplicate()->access('update')` นี่ดูเหมือนจะเป็นการหลอกลวงและจะหลีกเลี่ยงแคช ฉันหวังว่า..
in flag
ผลลัพธ์การเข้าถึงถูกแคชไว้ต่อเอนทิตี หรือเราต้องเพิ่มแท็กแคชอื่น
in flag
ฉันสังเกตเห็นปัญหาอื่นเกี่ยวกับสิ่งนี้: ทั้งหมดนี้จะถูกส่งออกไปยังการกำหนดค่า ดังนั้นการเปลี่ยนแปลงใดๆ ของผู้ใช้จะถูกเขียนทับเมื่อนำเข้าการกำหนดค่าในการปรับใช้ครั้งถัดไป ตอนนี้ฉันเกือบจะเชื่อแล้วว่านี่เป็นวิธีที่ผิดในการทำสิ่งต่างๆ และฉันควรใช้บล็อกเนื้อหาจริงๆ..

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา