I've been looking into using the Entity Metadata Wrapper classes (defined by the entity module in Drupal 7) to access field values, as this seems to be a clean way of doing so.
There a couple of things that make this a bit awkward however. Assume I have a wrapper for a content type that defines a field named field_something
as such:
$wrapper = entity_metadata_wrapper('node', node_load($nid));
$value = $wrapper->field_something->value();
The first problem I have is that I have no way of knowing before hand whether what I get is an actual value (a string, an entity, etc.), another metadata structure wrapper (when fields have multiple values) or an array (when fields have multiple properties).
I have found a way to answer those questions using the info()
method:
$info = $wrapper->field_something->info();
$is_multi_value = (strpos($info['type'], 'list<') === 0);
$has_multiple_properties = isset($info['property info']]);
However that is hardly practical. Whenever I want to use a field without knowing it's definition before hand, I must take into account several cases. This makes my code quite heavy.
In order to deal with this I have written some code which:
- Ensures we always get returned an array, even if it's a single value field ;
- When there are multiple properties, return the value of the first column.
Point 1. here will always work, unless the caller want to know whether this was a single value field or not. Point 2 works in some cases, not all, but is convenient when it applies.
Here is the code:
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;
}
So my question is: are there simpler/better ways to address this problem of getting values from the metadata wrapper when the field type is not known ?