我一直在研究使用实体元数据包装程序类(由Drupal 7中的实体模块定义)来访问字段值,因为这样做似乎是一种干净的方法。
但是,有几件事情使这有些尴尬。假设我有一个内容类型的包装器,该包装器定义了一个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.这里始终有效,除非调用者想知道这是否是单个值字段。Point 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;
}
所以我的问题是:当字段类型未知时,是否有更简单/更好的方法来解决从元数据包装中获取值的问题?