function commerce_order_commerce_customer_profile_presave in Commerce Core 7
Implements hook_commerce_customer_profile_presave().
The Order module prevents customer profile deletion for any profile that is referenced by a non-cart order via hook_commerce_customer_profile_can_delete(). The same logic applies when updating a customer profile to determine whether or not the update should be allowed on the same profile or if it should be handled as a clone of the original profile. This ensures that editing a profile on a separate order or through the admin UI after completing an order will not cause the original order to lose essential data.
File
- modules/
order/ commerce_order.module, line 509 - Defines the core Commerce order entity and API functions to manage orders and interact with them.
Code
function commerce_order_commerce_customer_profile_presave($profile) {
// Only perform this check when updating an existing profile.
if (!empty($profile->profile_id)) {
$original_profile = $profile->original;
$field_change = FALSE;
// Compare against the field values.
foreach (field_info_instances('commerce_customer_profile', $profile->type) as $field_name => $instance) {
$langcode = field_language('commerce_customer_profile', $profile, $field_name);
// Make sure that empty fields have a consistent structure.
if (empty($profile->{$field_name})) {
$profile->{$field_name}[$langcode] = array();
}
if (empty($original_profile->{$field_name})) {
$original_profile->{$field_name}[$langcode] = array();
}
// Extract the items from the field value that need to be compared.
$items = $profile->{$field_name}[$langcode];
$original_items = $original_profile->{$field_name}[$langcode];
// If the number of items has changed, mark the field change.
if (count($items) != count($original_items)) {
$field_change = TRUE;
break;
}
// Loop over each item in the field value.
foreach ($items as $delta => $item) {
// Find the supposedly matching original item.
$original_item = $original_items[$delta];
// Compare columns common to both arrays.
$item = array_intersect_key($item, $original_item);
$original_item = array_intersect_key($original_item, $item);
if ($item != $original_item) {
$field_change = TRUE;
break;
}
// Provide special handling for the addressfield to accommodate the fact
// that the field as loaded from the database may contain additional
// keys that aren't included in the profile being saved because their
// corresponding form elements weren't included on the edit form.
// If those additional keys contain data, the field needs to be
// marked as changed.
if ($field_name == 'commerce_customer_address') {
foreach ($original_items[$delta] as $key => $value) {
if (!array_key_exists($key, $item) && !empty($value)) {
$field_change = TRUE;
break 2;
}
}
}
}
}
// If we did in fact detect significant changes and this profile has been
// referenced by a non-cart order...
if ($field_change && !commerce_order_commerce_customer_profile_can_delete($profile)) {
// Update various properties of the profile so it gets saved as new.
$profile->profile_id = '';
$profile->revision_id = '';
$profile->created = REQUEST_TIME;
$profile->log = '';
}
}
}