Normally, you can set the field value on an entity by wrapping it in entity_metadata_wrapper() and then assigning the field value, such as $wrapped_entity->field_custom = $my_new_value. On a custom field, you need to add a 'property_type' in hook_field_info in order for this to work. This is working fine for a single-column field.

For a field module that saves data to multiple columns, it looks like you can use a property_type of 'struct' or 'something_else', and then define the data in 'property_callback'. Within this callback, it appears that you can return a 'property_info' array, with the array keys matching the name of the database column, and then you should be able to save to these columns using entity_metadata_wrapper($entity)->my_field->column_name.

I can't get this to work; is there a piece I am missing? I am following the docs at https://drupal.org/node/1021556 with no result.

/**
 * Implements hook_field_info().
 */
function device_id_field_info() {
  return array(
    'device_id' => array(
      'label' => t('Device ID'),
      'description' => t('Converts the input device ID and saves it to the 
        database in various formats.'),
      'default_widget' => 'device_id_simple',
      'default_formatter' => 'device_id_raw',
      'default_token_formatter' => 'device_id_combined',
      'property_type' => 'device_id',
      'property_callback' => array('_device_id_property_callback'),
      ),
  );
}

/**
 * Callback to alter the property info of device id fields.
 *
 * @see device_id_field_info().
 */
function _device_id_property_callback(&$info, $entity_type, $field, $instance, $field_type) {
  $name = $field['field_name'];
  $property = &$info[$entity_type]['bundles'][$instance['bundle']]['properties'][$name];

  $property['type'] = ($field['cardinality'] != 1) ? 'list<deviceid>' : 'deviceid';
  $property['getter callback'] = 'entity_metadata_field_verbatim_get';
  $property['setter callback'] = 'entity_metadata_field_verbatim_set';
  $property['property info'] = device_id_property_info();

  unset($property['query callback']);
}

/**
 * Defines info for the properties of the address field data structure.
 */
function device_id_property_info($name = NULL) {
  // Build an array of basic property information for the address field.
  $properties = array(
    'raw_id' => array(
      'label' => t('Raw input ID'),
    ),
    'esn_hex' => array(
      'label' => t('Converted ESN in hexadecimal format'),
    ),
    'esn_dec' => array(
      'label' => t('Converted ESN in decimal format'),
    ),
    'meid_hex' => array(
      'label' => t('Converted MEID in hexadecimal format'),
    ),
    'meid_dec' => array(
      'label' => t('Converted MEID in decimal format'),
    ),
    'imei_hex' => array(
      'label' => t('Converted IMEI in hexadecimal format'),
    ),
    'imei_dec' => array(
      'label' => t('Converted IMEI in decimal format'),
    ),
    'iccid_hex' => array(
      'label' => t('Converted ICCID in hexadecimal format'),
    ),
    'iccid_dec' => array(
      'label' => t('Converted ICCID in decimal format'),
    ),
  );
}

An example of how I intend to use entity_metadata_wrapper to create the entity and assign the field value is:

<?php

$id = '25512345687';
$model = '216';

$ent = entity_create('node', array(
      'uid' => 1,
      'type' => 'equipment',
    ));
    $wrapped_ent = entity_metadata_wrapper('node', $ent);
    $wrapped_ent->title = $id;
    $wrapped_ent->field_device_id->esn_dec = $id;
    $wrapped_ent->save();
dpm($wrapped_ent->getPropertyInfo());
?>

Comments

micromegas’s picture

Issue summary: View changes

removed irrelevant link

micromegas’s picture

Status: Active » Closed (outdated)

I'm guessing that nobody has any ideas on this one: closing.