I've created a custom field and widget with the Field API. I've added this custom field to one of my node entities by using the Field UI and named it field_pec_uuid. However, when i try to access the values of this field by using entity_metadata_wrapper like so:
$node_wrapper = entity_metadata_wrapper('node', $nid);
print $node_wrapper->field_pec_uuid->value();
It will give me the following error:
EntityMetadataWrapperException: Unknown data property field_pec_uuid. in EntityStructureWrapper->getPropertyInfo() (regel 335 van /webroot/d7_root/sites/all/modules/contrib/entity/includes/entity.wrapper.inc).
When I print the values of $node_wrapper->value() I can clearly see the field exists and even has the value I've been giving it. However, when I print the values of $node_wrapper->getPropertyInfo() I can see the field name is not listed. What am I missing here? Anyone has any indications?
I can't for the life of me figure out how to get my field listed by $node_wrapper->getPropertyInfo(). Below is my code.
/**
* Field & Widget section
*/
/**
* Implementation of hook_field_info()
*
* @return [type] [description]
*/
function poh_eduref_field_info() {
return array(
'eduref_uuid' => array(
'label' => t('Eduref UUID Field'),
'description' => t('This field stores UUID values.'),
'settings' => array('allowed_values' => array(), 'allowed_values_function' => ''),
'default_widget' => 'poh_eduref_eduref_widget',
'default_formatter' => 'poh_eduref_field_formatter_view',
),
);
}
/**
* Implements hook_field_widget_info
*
* @return [type] [description]
*/
function poh_eduref_field_widget_info() {
return array(
'poh_eduref_eduref_widget' => array(
'label' => t('Education Reference Field'),
'field types' => array('eduref_uuid'),
'settings' => array(
'autocomplete_path' => 'eduref/autocomplete',
),
),
);
}
/**
* Implements hook_field_widget_form()
*
* @param [type] &$form [description]
* @param [type] &$form_state [description]
* @param [type] $field [description]
* @param [type] $instance [description]
* @param [type] $langcode [description]
* @param [type] $items [description]
* @param [type] $delta [description]
* @param [type] $element [description]
* @return [type] [description]
*/
function poh_eduref_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$item =& $items[$delta];
$element['uuid'] = array(
'#type' => 'fieldset',
'#title' => $element['#title'],
'#description' => t('This is the description.'),
);
$element['uuid']['value'] = array(
'#type' => 'textfield',
'#title' => 'Education Reference',
'#autocomplete_path' => $instance['widget']['settings']['autocomplete_path'],
'#default_value' => isset($item['value']) ? $item['value'] : '',
);
return $element;
}
function poh_eduref_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
if($field['type'] == 'eduref_uuid') {
foreach ($items as $delta => $item) {
if (isset($item['uuid']['value'])) {
$items[$delta]['value'] = $item['uuid']['value'];
}
}
}
}
/**
* [poh_eduref_autocomplete_callback description]
* @param [type] $string [description]
* @return [type] [description]
*/
function poh_eduref_autocomplete_callback($string) {
$query = new EntityFieldQuery();
$result = $query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'poheduref')
->fieldCondition('field_eduref_display_name', 'value', $string.'%', 'LIKE')
->execute();
if($result['node']) {
foreach(array_keys($result['node']) as $nid) {
$node = entity_metadata_wrapper('node', $nid);
if($node->field_eduref_uuid && $node->field_eduref_display_name) {
$json_array[$node->field_eduref_uuid->value()] = $node->field_eduref_disorder->value().'/'.$node->field_eduref_type->value().'/'.$node->field_eduref_display_name->value();
}
}
}
return drupal_json_output($json_array);
}
/**
* Implementation of hook_field_is_empty()
*
* @param [type] $item [description]
* @param [type] $field [description]
* @return [type] [description]
*/
function poh_eduref_field_is_empty($item, $field) {
$temp = array_keys($field['columns']);
$key = array_shift($temp);
return empty($item['uuid'][$key]);
}
function poh_eduref_field_formatter_info() {
return array(
'eduref_uuid' => array(
'label' => t('UUID'),
'field types' => array('eduref_uuid'),
),
);
}
function poh_eduref_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
switch ($display['type']) {
case 'eduref_uuid' :
foreach ($items as $delta => $item) {
if (isset($item['value'])) {
$element[$delta]['#markup'] = $item['value'];
}
}
break;
}
return $element;
}
/**
* [poh_eduref_field_validate description]
* @param [type] $entity_type [description]
* @param [type] $entity [description]
* @param [type] $field [description]
* @param [type] $instance [description]
* @param [type] $langcode [description]
* @param [type] $items [description]
* @param [type] $errors [description]
* @return [type] [description]
*/
function poh_eduref_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
foreach ($items as $delta => $item) {
if(empty($item['field_pec_uuid'])) {
//$errors[$field['field_name']][$langcode][$delta][] = array('error' => 'uuid_empty_error', 'message' => t('Field empty.'));
}
}
}
EDIT: For anyone who stumbles into the same issue; the solution as provided by Clive was to add a property_type key to the hook_field_info implementation, like so:
function poh_eduref_field_info() {
return array(
'eduref_uuid' => array(
'label' => t('Eduref UUID Field'),
'description' => t('This field stores UUID values.'),
'settings' => array('allowed_values' => array(), 'allowed_values_function' => ''),
'default_widget' => 'poh_eduref_eduref_widget',
'default_formatter' => 'poh_eduref_field_formatter_view',
'property_type' => 'text',
),
);
}
In my case 'text' as value will suffice, as its a simple textfield. If you need more advanced examples I recommend reading the links Clive provided.