การเข้าถึงค่าประเภทเขตข้อมูลที่ไม่รู้จักเมื่อใช้ entity_metadata_wrapper


12

ฉันได้มองหาการใช้คลาสเอนทิตี้เมตาดาต้าแรปเปอร์ (กำหนดโดยโมดูลเอนทิตีใน Drupal 7) เพื่อเข้าถึงค่าของฟิลด์เนื่องจากนี่เป็นวิธีที่สะอาดในการทำเช่นนั้น

มีสองสิ่งที่ทำให้เรื่องนี้ค่อนข้างน่าอึดอัดใจ สมมติว่าฉันมี wrapper สำหรับประเภทเนื้อหาที่กำหนดฟิลด์ชื่อfield_somethingเช่น:

$wrapper = entity_metadata_wrapper('node', node_load($nid));
$value = $wrapper->field_something->value();

ปัญหาแรกที่ฉันมีคือฉันไม่มีทางรู้ล่วงหน้าว่าสิ่งที่ฉันได้รับคือค่าจริง (สตริง, เอนทิตี้, ฯลฯ ), ตัวห่อโครงสร้างของเมทาดาทาอื่น (เมื่อเขตข้อมูลมีหลายค่า) หรืออาร์เรย์ (เมื่อ เขตข้อมูลมีคุณสมบัติหลายอย่าง)

ฉันพบวิธีที่จะตอบคำถามเหล่านั้นโดยใช้info()วิธีการ:

$info = $wrapper->field_something->info();
$is_multi_value = (strpos($info['type'], 'list<') === 0);
$has_multiple_properties = isset($info['property info']]);

อย่างไรก็ตามมันก็ใช้งานได้จริง เมื่อใดก็ตามที่ฉันต้องการใช้เขตข้อมูลโดยไม่ทราบว่ามันเป็นคำนิยามก่อนมือฉันต้องคำนึงถึงหลายกรณี ทำให้รหัสของฉันค่อนข้างหนัก

เพื่อจัดการกับเรื่องนี้ฉันได้เขียนโค้ดบางอย่างที่:

  1. มั่นใจได้ว่าเราจะได้รับอาร์เรย์คืนเสมอแม้ว่าจะเป็นเขตข้อมูลค่าเดียว
  2. เมื่อมีคุณสมบัติหลายอย่างให้ส่งคืนค่าของคอลัมน์แรก

จุดที่ 1 ที่นี่จะใช้งานได้เสมอเว้นแต่ผู้โทรต้องการทราบว่านี่เป็นเขตข้อมูลค่าเดียวหรือไม่ จุดที่ 2 ใช้งานได้ในบางกรณีไม่ใช่ทั้งหมด แต่จะสะดวกเมื่อใช้งาน

นี่คือรหัส:

function entity_metadata_simple_values($field) {
  $fields = array();
  $values = array();
  $info = $field->info();
  if (strpos($info['type'], 'list<') === 0) {
    foreach ($field->getIterator() as $field_iteration) {
      $fields[] = $field_iteration;
    }
  } else {
    $fields[] = $field;
  }
  foreach ($fields as $final_field) {
    $ff_info = $final_field->info();
    if (isset($ff_info['property info'])) {
      $column = reset(array_keys($ff_info['property info']));
      $values[] = $final_field->{$column}->value();
    } else {
      $values[] = $final_field->value();
    }
  }

  return $values;
}

ดังนั้นคำถามของฉันคือ: มีวิธีที่ง่ายกว่า / ดีกว่าในการจัดการปัญหานี้ในการรับค่าจาก wrapper ข้อมูลเมตาเมื่อไม่ทราบประเภทเขตข้อมูลหรือไม่

คำตอบ:


4

นี่คือคำแนะนำเล็กน้อยเพื่อให้กระบวนการนี้ง่ายขึ้นเล็กน้อย

$wrapper->field_something->type();

จะกลับมาประเภทของสนามคือnode, taxonomy_term, integer, textฯลฯ คุณสามารถจัดการแล้วค่ากลับมาจากการ$wrapper->field_something->value()ได้อย่างถูกต้อง

ด้วย

$wrapper->field_something->raw()

จะคืนค่าดิบของสนาม ซึ่งอาจจะเป็นarrayในกรณีของเขตข้อมูลที่มีค่าหลายแห่งเพียงแค่ค่า ตัวอย่างเช่นentity_referenceจะเป็นnid(หรือรหัสนิติบุคคล) ของนิติบุคคลอ้างอิงหรือarrayของรหัสองค์กรอ้างอิง


โอ้ฉันป้อนเร็วเกินไป! ฉันต้องการเพิ่ม: $ wrapper-> field_something-> type () ส่งคืนข้อมูลเดียวกับองค์ประกอบ 'type' ของอาร์เรย์ที่ส่งกลับโดย $ wrapper-> field_something-> info () ที่สำคัญมันยังคงส่งคืนสตริง "list <type>" สำหรับประเภทที่มีหลายค่าดังนั้นฉันยังคงต้องใช้ strpos (หรือเทียบเท่า) เพื่อหาว่ามันเป็นหลายค่าหรือไม่
Alice Heaton

สำหรับจุดที่สอง: ฉันสามารถทำงานได้จริงถ้ามันมีค่าหลายค่าโดยการทดสอบการส่งคืนของ -> raw () หรือ -> value () แต่ฉันควรรู้ก่อนเรียกค่าเช่นว่ามันมีค่าหลายค่าแล้ว ฉันต้องการเรียกใช้ผ่านลูป foreach ด้วย -> getIterator () แทนที่จะใช้อาเรย์ด้วยตนเองซึ่งต้องให้ฉันสร้าง wrapper ใหม่สำหรับแต่ละไอเท็ม
อลิซ Heaton

3

ดังนั้นเมื่อไม่มีใครคิดวิธีอื่นฉันจะตอบคำถามของฉันเอง:

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

มีวิธีการทางเลือกหนึ่งที่ฉันอธิบายไว้ในตอนแรก (ตัวอย่างเช่นสิ่งที่ชี้ให้เห็นโดย @thepearson) โดยเฉพาะอย่างยิ่งวิธีนี้มีประโยชน์:

 entity_property_list_extract_type($type)

มันจะกลับมาประเภทที่ระบุถ้าประเภทของคุณเป็นรายการ (เช่น 'จำนวนเต็ม' ถ้าประเภทของคุณคือ 'รายการ <integer>') หรือเท็จถ้าประเภทของคุณไม่ได้เป็นรายการ ภายในมันเป็นเพียงแค่รหัสที่ฉันโพสต์ในตอนแรก แต่ฉันเดาว่ามันเป็นข้อพิสูจน์ในอนาคต

บทสรุปคือ:

  • เอนทิตีการห่อหุ้มข้อมูลเมตาของ Entity ทำงานได้ดีหากคุณไม่มีความรู้เกี่ยวกับประเภทเขตข้อมูลของคุณและต้องการระบุแต่ละกรณีที่เป็นไปได้อย่างรอบคอบ

  • เอนทิตีการห่อหุ้มข้อมูลเมตาของ Entity ทำงานได้ดีถ้าคุณรู้ว่าฟิลด์ของคุณเป็นประเภทใดและคุณต้องการใช้

  • หากคุณมีแนวคิดบางอย่างเกี่ยวกับประเภทฟิลด์ของคุณ (ตัวอย่างเช่นข้อความทั้งหมด แต่คุณไม่ทราบว่ามีการจัดรูปแบบหรือไม่และคุณไม่ทราบว่าเป็นประเภทเดียวหรือหลายค่า) Entity ไม่มีทางลัดใด ๆ และคุณต้องเขียนด้วยตัวเองเหมือนที่ฉันทำในคำถามแรก


1

สำหรับการตรวจสอบฟิลด์เดียว / หลายฉันพบว่ามีประโยชน์ในการทดสอบประเภทของวัตถุห่อหุ้มซึ่งจะเป็นEntityListWrapperเขตข้อมูลหลายค่าและEntityValueWrapperสำหรับเขตข้อมูลค่าเดียว:

<?php
...
$wrapper = entity_metadata_wrapper('user', $account);
// Get address, or first address if a multi-value field instance.
if (get_class($wrapper->field_address) == 'EntityListWrapper') {
  $value = $wrapper->field_address[0]->value();
}
else {
  $value = $wrapper->field_address->value();
}

หรือแม้กระทั่งif($wrapper->field_name instanceof EntityListWrapper) {...}
rudolfbyker
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.