Because the address field has a complex schema, we need to expose all of our columns to the Entity API for use in comparing against / updating address field data in Rules and via the entity_metadata_wrapper(). This involves adding property info to the field info array in hook_field_info() and adding the appropriate callback.

For an example, refer to the Price module code:

function commerce_price_field_info() {
  return array(
    'commerce_price' => array(
      'label' => t('Price'),
      'description' => t('This field stores prices for products consisting of an amount and a currency.'),
      'settings' => array(),
      'instance_settings' => array(),
      'default_widget' => 'commerce_price_simple',
      'default_formatter' => 'commerce_price_default',
      'property_type' => 'commerce_price',
      'property_callbacks' => array('commerce_price_property_info_callback'),
    ),
  );
}

function commerce_price_property_info_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<commerce_price>' : 'commerce_price';
  $property['getter callback'] = 'entity_metadata_field_verbatim_get';
  $property['setter callback'] = 'entity_metadata_field_verbatim_set';
  $property['auto creation'] = 'commerce_price_field_data_auto_creation';
  $property['property info'] = commerce_price_field_data_property_info();

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

function commerce_price_field_data_auto_creation() {
  return array('amount' => 0, 'currency_code' => commerce_default_currency(), 'data' => array());
}

function commerce_price_field_data_property_info($name = NULL) {
  return array(
    'amount' => array(
      'label' => t('Amount'),
      'description' => !empty($name) ? t('Amount value of field %name', array('%name' => $name)) : '',
      'type' => 'decimal',
      'getter callback' => 'entity_property_verbatim_get',
      'setter callback' => 'entity_property_verbatim_set',
    ),
    'currency_code' => array(
      'label' => t('Currency'),
      'description' => !empty($name) ? t('Currency code of field %name', array('%name' => $name)) : '',
      'type' => 'text',
      'getter callback' => 'entity_property_verbatim_get',
      'setter callback' => 'entity_property_verbatim_set',
      'options list' => 'commerce_currency_code_options_list',
    ),
    // Still needs to describe the data array. :-/
  );
}

Comments

tema’s picture

Subscribing.

rszrama’s picture

Status: Active » Fixed

Just committed, but it's next to impossible to test in the context of Drupal Commerce because of Rules data selector limitations. Hopefully that will be addressed through #1065496: Data selectors only don't include fields of child entities.

Status: Fixed » Closed (fixed)
Issue tags: -dcsprint5

Automatically closed -- issue fixed for 2 weeks with no activity.