ฉันได้มองหาการใช้คลาสเอนทิตี้เมตาดาต้าแรปเปอร์ (กำหนดโดยโมดูลเอนทิตีใน 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 ใช้งานได้ในบางกรณีไม่ใช่ทั้งหมด แต่จะสะดวกเมื่อใช้งาน
นี่คือรหัส:
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 ข้อมูลเมตาเมื่อไม่ทราบประเภทเขตข้อมูลหรือไม่