You are here

function commerce_shipping_pane_checkout_form in Commerce Shipping 7.2

Same name and namespace in other branches
  1. 7 includes/commerce_shipping.checkout_pane.inc \commerce_shipping_pane_checkout_form()

Checkout pane callback: builds a shipping quote selection form.

File

includes/commerce_shipping.checkout_pane.inc, line 33
Callback functions for the shipping module's checkout panes.

Code

function commerce_shipping_pane_checkout_form($form, &$form_state, $checkout_pane, $order) {

  // Ensure this include file is loaded when the form is rebuilt from the cache.
  $form_state['build_info']['files']['form'] = drupal_get_path('module', 'commerce_shipping') . '/includes/commerce_shipping.checkout_pane.inc';
  $pane_form = array(
    '#prefix' => '<div id="commerce-shipping-service-ajax-wrapper">',
    '#suffix' => '</div>',
  );
  $pane_form['shipping_rates'] = array(
    '#type' => 'value',
    '#value' => FALSE,
  );

  // TODO: integrate with Commerce Physical Product to ensure an order contains
  // physical products before attempting to quote shipping rates.
  // Collect shipping rates for the order.
  commerce_shipping_collect_rates($order);

  // Generate an array of shipping service rate options.
  $options = commerce_shipping_service_rate_options($order, $form_state);

  // If at least one shipping option is available...
  if (!empty($options)) {

    // Store the shipping methods in the form for validation purposes.
    $pane_form['shipping_rates'] = array(
      '#type' => 'value',
      '#value' => $order->shipping_rates,
    );

    // Add a radios element to let the customer select a shipping service.
    $pane_form['shipping_service'] = array(
      '#type' => 'radios',
      '#options' => $options,
      '#ajax' => array(
        'callback' => 'commerce_shipping_pane_service_details_refresh',
        'wrapper' => 'commerce-shipping-service-details',
      ),
    );
    foreach ($options as $key => $option) {
      $pane_form['shipping_service'][$key] = array(
        '#description' => $order->shipping_rates[$key]->data['shipping_service']['description'],
      );
    }

    // Find the default shipping method using either the pre-selected value
    // stored as a line item on the order or the first available method.
    $pane_values = !empty($form_state['values'][$checkout_pane['pane_id']]) ? $form_state['values'][$checkout_pane['pane_id']] : array();
    $pane_values['service_details'] = !empty($form_state['values'][$checkout_pane['pane_id']]['service_details']) ? $form_state['values'][$checkout_pane['pane_id']]['service_details'] : array();

    // First check for a shipping service selection in the pane values.
    if (!empty($pane_values['shipping_service']) && !empty($options[$pane_values['shipping_service']])) {
      $default_value = $pane_values['shipping_service'];
    }
    else {

      // Then look for one in a line item on the order already.
      $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
      foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
        if ($line_item_wrapper
          ->value() && $line_item_wrapper->type
          ->value() == 'shipping' && !empty($options[$line_item_wrapper->commerce_shipping_service
          ->value()])) {
          $default_value = $line_item_wrapper->commerce_shipping_service
            ->value();

          // If the service details value is empty, see if there are any values
          // in the line item to merge into the array as defaults.
          if (empty($pane_values['service_details']) && !empty($line_item_wrapper
            ->value()->data['service_details'])) {
            $pane_values['service_details'] = $line_item_wrapper
              ->value()->data['service_details'];
          }
          break;
        }
      }
    }

    // If we still don't have a default value, use the first available and clear
    // any related input from the form state.
    if (empty($default_value) || empty($pane_form['shipping_service']['#options'][$default_value])) {
      $default_value = key($options);
      unset($form_state['input']['commerce_shipping']['shipping_service']);
    }

    // Set the default value for the shipping method radios.
    $pane_form['shipping_service']['#default_value'] = $default_value;
    $shipping_service = commerce_shipping_service_load($default_value);
    $pane_form['service_details'] = array(
      '#type' => 'container',
    );

    // If the service specifies a details form callback...
    if ($callback = commerce_shipping_service_callback($shipping_service, 'details_form')) {

      // Look for a form array from the callback.
      $details_form = $callback($pane_form, $pane_values, $checkout_pane, $order, $shipping_service);

      // If a details form array was actually returned...
      if (!empty($details_form)) {

        // Add it to the form now.
        $pane_form['service_details'] += $details_form;
      }
    }
    $pane_form['service_details']['#prefix'] = '<div id="commerce-shipping-service-details">';
    $pane_form['service_details']['#suffix'] = '</div>';
  }
  else {

    // Otherwise display a message indicating whether or not we need a shipping
    // service to be selected to complete checkout.
    if (variable_get('commerce_shipping_pane_require_service', FALSE)) {
      $message = t('No valid shipping rates found for your order, and we require shipping service selection to complete checkout.') . '<br /><strong>' . t('Please verify you have supplied all required information or contact us to resolve the issue.') . '</strong>';
    }
    else {

      // If live shipping rate recalculation is required, check if we can show
      // shipping options.
      if (commerce_shipping_recalculate_services($form, NULL, TRUE) && empty($form_state['recalculate'])) {
        $message = t('Please supply all of the required information requested above to reveal your shipping options.');
      }
      else {
        $message = t('No shipping rates found for your order. Please continue the checkout process.');
      }
    }
    $pane_form['message'] = array(
      '#markup' => '<div>' . $message . '</div>',
      '#weight' => -20,
    );
  }
  return $pane_form;
}