Split full name fields in customer profiles

Drupal Commerce Tip
Update historical commerce customer profiles to use first and last name
Fri, June 13th, 2014
andyg5000
commerce

There have been several times now where I've been required to switch a commerce customer profile to use independent first and last name lines instead of the combined name line. This is an easy switch to make for new orders. Just change the field settings for commerce_customer_address field on the profile entity to use the separate form fields. However, you're then stuck with historical data that doesn't have a value set in the first and last name fields the following script will loop through all of your billing profiles and make a best guess attempt at updating the first and last name fields.

One tricky thing to note is that commerce_order_commerce_customer_profile_presave() prevents you from saving changes to a profile attached to an order. Usually that is a good thing, but in this case we actually want that to happen. We use db_update instead of the entity save method. If you want to use this for shipping profiles as well, just change the bundle condition to 'shipping' or whatever your other bundle name is.

<?php

// Build an entity field query to load all customer billing profiles.
$efq = new EntityFieldQuery();
$results = $efq->entityCondition('entity_type', 'commerce_customer_profile')
  ->entityCondition('bundle', 'billing')
  ->execute();

foreach ($results['commerce_customer_profile'] as $result) {

  // Grab the address value and split the name into two parts.
  $profile = commerce_customer_profile_load($result->profile_id);
  $wrapper = entity_metadata_wrapper('commerce_customer_profile', $profile);
  $address = $wrapper->commerce_customer_address->value();
  $names = explode(' ', $address['name_line']);
  $first = array_shift($names);
  $last = implode(' ', $names);

  // Use db_update to get around the presave function that prevents updating
  // profiles attached to orders.
  // @see commerce_order_commerce_customer_profile_presave().
  $update = db_update('field_data_commerce_customer_address')
    ->fields(array(
      'commerce_customer_address_first_name' => $first,
      'commerce_customer_address_last_name' => $last,
    ))
    ->condition('entity_id', $profile->profile_id)
    ->execute();

  // Reset the cache for this entity so that a fresh query is made when viewing.
  entity_get_controller('commerce_customer_profile')->resetCache(array($profile->profile_id));

}

?>