2

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.

1
  • OK, you stated some facts, posted some code... But I can't see where you actually ask a question.
    – Mołot
    Jun 18, 2015 at 11:46

1 Answer 1

3

EntityMetadataWrapper comes from the Entity API module; by default it only knows about core field types, you have to explicitly tell it how to handle custom fields.

That involves adding property_type and possibly property_callbacks keys to your field info array.

See What does the 'property_type' key do in hook_field_info()? for a bit more information, and here for a code sample.

2
  • Hi Clive! Thank you dear sir! Adding property_type = 'text' to my hook_field_info has solved the issue (its a simple text field)! I can access the field using entity_metadata_wrapper now!
    – Gevarya
    Jun 18, 2015 at 12:17
  • Happy to help :)
    – Clive
    Jun 18, 2015 at 12:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.