Tôi đã xem xét việc sử dụng các lớp Trình bao bọc siêu dữ liệu thực thể (được xác định bởi mô-đun thực thể trong Drupal 7) để truy cập các giá trị trường, vì đây dường như là một cách làm sạch.
Tuy nhiên, có một vài điều làm cho điều này hơi khó xử. Giả sử tôi có trình bao bọc cho loại nội dung xác định trường có tên field_something
như sau:
$wrapper = entity_metadata_wrapper('node', node_load($nid));
$value = $wrapper->field_something->value();
Vấn đề đầu tiên tôi gặp phải là tôi không có cách nào biết trước được liệu tôi nhận được là giá trị thực (chuỗi, thực thể, v.v.), một trình bao bọc cấu trúc siêu dữ liệu khác (khi các trường có nhiều giá trị) hoặc một mảng (khi các trường có nhiều thuộc tính).
Tôi đã tìm ra cách để trả lời những câu hỏi đó bằng info()
phương pháp:
$info = $wrapper->field_something->info();
$is_multi_value = (strpos($info['type'], 'list<') === 0);
$has_multiple_properties = isset($info['property info']]);
Tuy nhiên điều đó là khó thực tế. Bất cứ khi nào tôi muốn sử dụng một trường mà không biết định nghĩa của nó trước khi sử dụng, tôi phải tính đến một số trường hợp. Điều này làm cho mã của tôi khá nặng.
Để giải quyết vấn đề này, tôi đã viết một số mã:
- Đảm bảo chúng tôi luôn được trả về một mảng, ngay cả khi đó là một trường giá trị duy nhất;
- Khi có nhiều thuộc tính, trả về giá trị của cột đầu tiên.
Điểm 1. ở đây sẽ luôn hoạt động, trừ khi người gọi muốn biết liệu đây có phải là trường giá trị đơn hay không. Điểm 2 hoạt động trong một số trường hợp, không phải tất cả, nhưng thuận tiện khi áp dụng.
Đây là mã:
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;
}
Vì vậy, câu hỏi của tôi là: có cách nào đơn giản hơn / tốt hơn để giải quyết vấn đề nhận giá trị này từ trình bao bọc siêu dữ liệu khi loại trường không được biết?