function commerce_registration_defer_form_submit in Commerce Registration 7.2
Submit callback for the registration deferral form.
File
- modules/
commerce_registration_defer/ commerce_registration_defer.module, line 152 - Module file for commerce_registration_defer.
Code
function commerce_registration_defer_form_submit($form, &$form_state) {
$original_registration = $form_state['build_info']['args'][0];
$line_item_type = $form_state['values']['line_item_type'];
$original_line_item = $form_state['values']['original_line_item'];
// The selected product.
$product = commerce_product_load_by_sku($form_state['values']['product_sku']);
$order = $form_state['build_info']['args'][1];
// Wrap the order for easy access to field data.
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
// Get the line item we created in the validation callback.
$line_item = $form_state['build_info']['new_line_item'];
// Wrap the line item too, we'll need it.
$line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
// Copy all the existing registration's data and update it with the new
// product info.
$new_registration = clone $original_registration;
$new_registration->entity_id = $product->product_id;
unset($new_registration->created);
$new_registration->registration_id = NULL;
$new_registration
->save();
// Now set the state of the original registration to deferred.
$original_registration->state = 'deferred';
$original_registration
->save();
$quantity = $original_registration->count;
// Reduce the original line item quantity by the registration count if the
// line item quantity is synced with the number of associated registrations.
$sync_original_quantity = isset($original_line_item->data['sync_registrations']) ? (bool) $original_line_item->data['sync_registrations'] : TRUE;
if ($sync_original_quantity && $original_line_item->quantity > 0) {
$original_line_item->quantity = $original_line_item->quantity < $quantity ? 0 : $original_line_item->quantity - $quantity;
commerce_line_item_save($original_line_item);
}
// If we should try and combine line items look for an existing line item to
// add the new registration to.
$combine = isset($original_line_item->data['context']['add_to_cart_combine']) ? $original_line_item->data['context']['add_to_cart_combine'] : TRUE;
// Determine if the product already exists on the order and increment its
// quantity instead of adding a new line if it does.
$matching_line_item = NULL;
// If we are supposed to look for a line item to combine into...
if ($combine) {
// Generate an array of properties and fields to compare.
$comparison_properties = array(
'type',
'commerce_product',
);
// Add any field that was exposed on the Add to Cart form to the array.
// TODO: Bypass combination when an exposed field is no longer available but
// the same base product is added to the cart.
foreach (field_info_instances('commerce_line_item', $line_item->type) as $info) {
if (!empty($info['commerce_cart_settings']['field_access'])) {
$comparison_properties[] = $info['field_name'];
}
}
// Allow other modules to specify what properties should be compared when
// determining whether or not to combine line items.
drupal_alter('commerce_cart_product_comparison_properties', $comparison_properties, clone $line_item);
// Loop over each line item on the order.
foreach ($order_wrapper->commerce_line_items as $delta => $matching_line_item_wrapper) {
// Unwrap the line item so we can compare its data parameter.
$existing_line_item = $matching_line_item_wrapper
->value();
// Check if the original line item and any matching line item share the
// same 'sync_registrations' settings.
$sync_matching_quantity = isset($existing_line_item->data['sync_registrations']) ? (bool) $existing_line_item->data['sync_registrations'] : TRUE;
if ($sync_original_quantity !== $sync_matching_quantity) {
continue;
}
// Examine each of the comparison properties on the line item.
foreach ($comparison_properties as $property) {
// If the property is not present on either line item, bypass it.
if (!isset($matching_line_item_wrapper
->value()->{$property}) && !isset($line_item_wrapper
->value()->{$property})) {
continue;
}
// If any property does not match the same property on the incoming line
// item or exists on one line item but not the other...
if (!isset($matching_line_item_wrapper
->value()->{$property}) && isset($line_item_wrapper
->value()->{$property}) || isset($matching_line_item_wrapper
->value()->{$property}) && !isset($line_item_wrapper
->value()->{$property}) || $matching_line_item_wrapper->{$property}
->raw() != $line_item_wrapper->{$property}
->raw()) {
// Continue the loop with the next line item.
continue 2;
}
}
// If every comparison line item matched, combine into this line item.
$matching_line_item = $existing_line_item;
break;
}
}
// If no matching line item was found...
if (empty($matching_line_item)) {
// Always use the quantity defined by the registration count...
$line_item->quantity = $quantity;
// However if the original line item was not set to sync its quantity with
// its number of registrations then we need someway to balance it out. So
// we will set the line items unit price to zero.
if (!$sync_original_quantity) {
$line_item->commerce_unit_price[$product->language][0]['amount'] = 0;
$line_item->commerce_unit_price[$product->language][0]['data']['components'] = array();
}
// Should the line item quantity be synced?
$line_item->data['sync_registrations'] = $sync_original_quantity;
// Save the incoming line item now so we get its ID.
commerce_line_item_save($line_item);
// Add it to the order's line item reference value.
$order_wrapper->commerce_line_items[] = $line_item;
}
else {
// Increment the quantity of the matching line item if its set to sync.
if ($sync_matching_quantity) {
$matching_line_item->quantity += $quantity;
}
// Update the data array and save it.
$matching_line_item->data = array_merge($line_item->data, $matching_line_item->data);
commerce_line_item_save($matching_line_item);
// Update the line item variable for use in the invocation and return value.
$line_item = $matching_line_item;
}
// Update the order with the new registration info.
$key = $line_item->line_item_id . 'prod-' . $product->sku;
$order->data['register_entities'][$key][] = $new_registration;
// Record the deferral in the order revision log.
$order->log = "Registration deferred: {$original_registration->registration_id} ==> {$new_registration->registration_id}.";
$order->revision = true;
// Save the updated order.
commerce_order_save($order);
$context = array(
'original' => array(
'registration' => $original_registration,
'line_item' => $original_line_item,
),
'new' => array(
'registration' => $new_registration,
'line_item' => $line_item,
),
'order' => $order,
);
// Invoke the hook.
module_invoke_all('commerce_registration_defer', $context);
// Invoke rules.
if (module_exists('rules')) {
rules_invoke_event('commerce_registration_defer', $original_registration, $new_registration);
}
// Display the confirmation message.
if (!empty($form['confirmation']['#value'])) {
drupal_set_message(filter_xss($form['confirmation']['#value']));
}
// Log the deferral to Drupal's watchdog.
$uri_options = entity_uri('commerce_order', $order);
watchdog('commerce registration', "Registration Deferred for order #!oid: !orig ==> !new.", array(
'!oid' => $order->order_id,
'!orig' => $original_registration->registration_id,
'!new' => $new_registration->registration_id,
), WATCHDOG_INFO, l(t('view order'), $uri_options['path'], $uri_options['options']));
}