Score:0

hook_forms() ไม่ทำงาน

ฉันกำลังพยายามเพิ่มปุ่มให้กับโหนดทุกรูปแบบผ่านการโทรกลับใน hook_forms ฉันได้รับข้อผิดพลาดที่คล้ายกัน ใครก็ได้ช่วยที

คำเตือน: call_user_func_array() คาดว่าพารามิเตอร์ 1 จะเป็นการโทรกลับที่ถูกต้อง ไม่พบคลาส 'my_dossier_form' ใน drupal_retrieve_form() (บรรทัดที่ 844 ของ /var/www/includes/form.inc)
ประกาศ: การแปลงอาร์เรย์เป็นสตริงใน drupal_prepare_form() (บรรทัดที่ 1094 ของ /var/www/includes/form.inc)
ประกาศ: การแปลงอาร์เรย์เป็นสตริงใน drupal_prepare_form() (บรรทัดที่ 1108 ของ /var/www/includes/form.inc)
ประกาศ: การแปลงอาร์เรย์เป็นสตริงใน drupal_prepare_form() (บรรทัดที่ 1128 ของ /var/www/includes/form.inc)

รหัส

ฟังก์ชัน my_dossier_forms($form_id, $args) {
  $forms = อาร์เรย์();
  ถ้า ($types = node_type_get_types()) {
    foreach (array_keys($types) เป็น $type) {
      $forms[$ประเภท '_node_form']['callback'] = 'my_dossier_form';
    }
  }

  ส่งคืน $forms;
}

ฟังก์ชัน my_dossier_form($form, &$form_state) {
  $form['delete'] = อาร์เรย์(
    '#type' => 'ส่ง',
    '#value' => t('ลบ'),
    '#น้ำหนัก' => 10,
  );
  คืนฟอร์ม $;
}
beltouche avatar
cn flag
คุณไม่ต้องการ `hook_form_alter` ใช่ไหม
Павел Герасюта avatar
ตามงาน ฉันต้องใช้ hook_forms โดยเฉพาะ
Jaypan avatar
de flag
รหัสของคุณดูดี แต่ไม่พบ `my_dossier_form()` ฟังก์ชันนี้อยู่ในไฟล์ใด คุณอาจต้องระบุอย่างชัดเจน
Павел Герасюта avatar
ในไฟล์ my_dossier.module
Павел Герасюта avatar
ฉันกำลังคิดที่จะใช้ module_load_include
apaderno avatar
us flag
@beltouche ฉันเห็นด้วย ตัวสร้างฟอร์มที่ตั้งค่าด้วย `hook_forms()` (หรือที่เรียกว่าค่า *callback*) ควรสร้างฟอร์มแบบเต็ม ไม่ใช่แค่ปุ่มส่ง ดูเหมือนว่างานของ OP กำลังแก้ไขรูปแบบการแก้ไขโหนดซึ่ง `hook_form_BASE_FORM_ID()` เป็นเบ็ดที่จะนำไปใช้
Score:1
ธง us

อะไร node_type_get_types() ส่งคืนเป็นอาร์เรย์ที่เชื่อมโยงของวัตถุประเภทโหนด คีย์ตามประเภท คำอธิบายของค่าที่ส่งคืนจะเข้าใจได้มากขึ้นใน _node_types_build() เอกสาร

การใช้งาน hook ที่ทำมาจากโมดูลหลักของ Drupal เป็นต้น comment_forms()ช่วยให้เข้าใจรหัสที่ถูกต้อง

ฟังก์ชัน comment_forms() {
  $forms = อาร์เรย์();
  foreach (node_type_get_types() เป็น $type) {
    $forms["comment_node_{$type->type}_form"]['callback'] = 'comment_form';
  }
  ส่งคืน $forms;
}

ในกรณีของคุณ รหัสควรคล้ายกับรหัสต่อไปนี้

ฟังก์ชัน my_dossier_forms($form_id, $args) {
  $forms = อาร์เรย์();
  foreach (node_type_get_types() เป็น $type) {
    $forms["my_dossier_node_{$type->type}_form"]['callback'] = 'my_dossier_form';
  }

  ส่งคืน $forms;
}

รหัสนี้ไม่แตกต่างจากรหัสที่แสดงในคำถามมากนัก และจะไม่ทำให้เกิด ไม่พบคลาส 'my_dossier_form' ข้อผิดพลาด.

เดอะ สาย 844 คืออันต่อไปนี้.

$form = call_user_func_array(isset($callback) ? $callback : $form_id, $args);

$โทรกลับ เริ่มต้นจากรหัสต่อไปนี้

ถ้า (!isset($forms) || !isset($forms[$form_id])) {
  $forms = module_invoke_all('แบบฟอร์ม', $form_id, $args);
}
$form_definition = $forms[$form_id];
ถ้า (isset($form_definition['callback arguments'])) {
  $args = array_merge($form_definition['callback arguments'], $args);
}
ถ้า (isset($form_definition['callback'])) {
  $callback = $form_definition['callback'];
  $form_state['build_info']['base_form_id'] = isset($form_definition['base_form_id']) ? $form_definition['base_form_id'] : $callback;
}

สาย 844 คิดไม่ออก my_dossier_form เป็นคลาส ยกเว้นในกรณี $โทรกลับ มีอาร์เรย์เช่น อาร์เรย์ ('my_dossier_form', 'mymodule_form');หรือมีสตริงเช่น 'my_dossier_form::methodName'.

คำเตือนเกี่ยวกับการแปลงอาร์เรย์เป็นสตริงหมายความว่า Drupal กำลังรับอาร์เรย์เมื่อต้องการสตริง เช่น จากบรรทัดต่อไปนี้ (สาย 1094).

    elseif (isset($form_state['build_info']['base_form_id']) && function_exists($form_state['build_info']['base_form_id'] . '_validate')) {

ฉันจะหลีกเลี่ยงการส่งคืน ID แบบฟอร์มที่ขึ้นต้นด้วย $ประเภท เนื่องจากอาจสร้างความขัดแย้งกับโมดูลอื่น ๆ ที่ใช้งานอยู่ hook_forms()ซึ่งคาดว่าจะส่งคืน ID ฟอร์มที่ไม่ซ้ำกันแต่ละรายการ ดู module_invoke_all() เพื่อทำความเข้าใจว่าจะเกิดอะไรขึ้นเมื่อสองคน hook_forms() การใช้งานส่งคืนข้อมูลสำหรับ ID แบบฟอร์มเดียวกัน

  foreach (module_implements($hook) เป็น $module) {
    $ฟังก์ชั่น = $โมดูล '_' . $เบ็ด;
    ถ้า (function_exists($function)) {
      $result = call_user_func_array($ฟังก์ชั่น, $args);

      // ในกรณีของ hook_forms() $result มีอาร์เรย์
      ถ้า (isset($result) && is_array($result)) {
        $return = array_merge_recursive($return, $result);
      }

      อื่น (isset (ผลลัพธ์ $)) {
        $return[] = ผลลัพธ์ $;
      }
    }
  }

เพื่อให้แม่นยำยิ่งขึ้น โมดูลสองโมดูลที่ส่งคืนค่าสำหรับ ID ฟอร์มเดียวกันอย่างน้อยอาจทำให้ call_user_func_array() คาดว่าพารามิเตอร์ 1 จะเป็นการโทรกลับที่ถูกต้อง ไม่พบคลาส '[callback]' เมื่อทั้งคู่ตั้งค่าสำหรับการเรียกกลับเดียวกัน ดูผลลัพธ์ของโค้ดต่อไปนี้ เพื่อทำความเข้าใจว่าเกิดอะไรขึ้นกันแน่

$return["type_node_form"]["callback"] = "my_dossier_form";
$result["type_node_form"]["callback"] = "mymodule_form";
print_r(array_merge_recursive($return,$result));

เดอะ โทรกลับ ค่าจะกลายเป็นอาร์เรย์ของสองสายซึ่ง call_user_func_array() ตีความเป็นอาร์เรย์ที่มีชื่อคลาสและชื่อเมธอด

อาร์เรย์
(
    [type_node_form] => อาร์เรย์
        (
            [โทรกลับ] => อาร์เรย์
                (
                    [0] => my_dossier_form
                    [1] => mymodule_form
                )

        )

)

ในกรณีนี้ ข้อขัดแย้งเกิดขึ้นกับโมดูลโหนด ซึ่งใช้โค้ดต่อไปนี้สำหรับ ของมัน hook_forms() การนำไปใช้งาน.

ฟังก์ชั่น node_forms () {
  $forms = อาร์เรย์();
  ถ้า ($types = node_type_get_types()) {
    foreach (array_keys($types) เป็น $type) {
      $forms[$ประเภท '_node_form']['callback'] = 'node_form';
    }
  }
  ส่งคืน $forms;

อย่างที่ทราบกันดีว่า hook_forms() จุดประสงค์คือการจัดเตรียมตัวสร้างฟอร์มเดียวกันสำหรับกลุ่มของฟอร์มที่มี ID ตามสคีมา เช่น ในกรณีของฟอร์มแก้ไขความคิดเห็น ซึ่งมี ID คือ comment_node_[ประเภทโหนด]_form. เมื่อระบุ ตัวสร้างแบบฟอร์มจะเรียกกลับ (ผ่านเป็น โทรกลับ ค่า) ควรสร้างแบบเต็ม ไม่ใช่บางส่วน
ข้อเท็จจริง my_dossier_form() สร้างเพียงปุ่มส่งและ my_dossier_forms() กำลังใช้รหัสเดียวกันกับที่ใช้โดย node_forms() ทำให้ฉันคิดว่าจุดประสงค์ของโค้ดคือการเปลี่ยนแปลงรูปแบบการแก้ไขโหนด ซึ่งควรทำให้สำเร็จได้โดยการนำไปใช้ hook_form_BASE_FORM_ID_alter(). นั่นคือสิ่งที่โมดูลหนังสือทำ book_form_node_form_alter()ซึ่งเรียกใช้สำหรับรูปแบบการแก้ไขโหนดของเนื้อหาทุกประเภท

ฟังก์ชัน book_form_node_form_alter(&$form, &$form_state, $form_id) {
  $node = $form['#node'];
  $access = user_access('โครงร่างสมุดบัญชี');
  ถ้า (! $ การเข้าถึง) {
    ถ้า (user_access('เพิ่มเนื้อหาในหนังสือ') && (!empty($node->book['mlid']) && !empty($node->nid) || book_type_is_allowed($node->type))) {

      // อยู่ในลำดับชั้นของหนังสือแล้ว หรือโหนดประเภทนี้ได้รับอนุญาต
      $การเข้าถึง = จริง;
    }
  }
  ถ้า (การเข้าถึง $) {
    _book_add_form_elements($form, $form_state, $node);

    // เนื่องจากเมนูแบบเลื่อนลงของ "หนังสือ" ไม่สามารถเรียกใช้การส่งแบบฟอร์มได้เมื่อใด
    // JavaScript ถูกปิดใช้งาน เพิ่มปุ่มส่งเพื่อดำเนินการดังกล่าว book.css ซ่อน
    // ปุ่มนี้เมื่อเปิดใช้งาน JavaScript
    $form['book']['pick-book'] = array(
      '#type' => 'ส่ง',
      '#value' => t('เปลี่ยนสมุด (อัพเดทรายชื่อผู้ปกครอง)'),
      '#submit' => อาร์เรย์(
        'book_pick_book_nojs_submit',
      ),
      '#น้ำหนัก' => 20,
    );
  }
}

หาก hook จำเป็นต้องใช้ชื่อประเภทเนื้อหาซึ่งมีให้ใน $form['#node']->type.

โพสต์คำตอบ

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