You are here

function commerce_addressbook_pane_checkout_form in Commerce Addressbook 7.3

Checkout pane callback: returns a customer profile edit form.

File

./commerce_addressbook.checkout_pane.inc, line 79
Based on commerce/modules/customer/commerce_customer.checkout_pane.inc

Code

function commerce_addressbook_pane_checkout_form($form, &$form_state, $checkout_pane, $order) {
  global $user;

  // Ensure this include file is loaded when the form is rebuilt from the cache.
  $form_state['build_info']['files']['pane'] = drupal_get_path('module', 'commerce_addressbook') . '/commerce_addressbook.checkout_pane.inc';
  $pane_id = $checkout_pane['pane_id'];

  // Extract the type of profile represented by this pane from its ID.
  $type = substr($pane_id, 17);

  // Removes 'customer_profile_'
  $field_name = variable_get('commerce_' . $pane_id . '_field', '');

  // The specified profile reference field doesn't exist on this order type.
  // A consequence of the checkout settings applying for all order types.
  if ($field_name && !field_info_instance('commerce_order', $field_name, $order->type)) {
    return array();
  }

  // Find the referenced profile using the related reference field...
  $wrapper = entity_metadata_wrapper('commerce_order', $order);
  $profile = NULL;
  $mode = 'view';

  // If the associated order field has been set...
  if ($field_name) {
    $profile = $wrapper->{$field_name}
      ->value();
  }
  else {

    // Or try the association stored in the order's data array if no field is set.
    if (!empty($order->data['profiles'][$checkout_pane['pane_id']])) {
      $profile = commerce_customer_profile_load($order->data['profiles'][$pane_id]);
    }
  }

  // If an AJAX rebuild happened, we might have our data in form state
  if (!empty($form_state['pane_' . $pane_id])) {
    $profile = $form_state['pane_' . $pane_id]['profile'];
    $mode = $form_state['pane_' . $pane_id]['mode'];
  }
  $valid_profiles = array();
  $incomplete_profiles = array();

  // Load the active user profiles.
  if ($user->uid && ($active_profiles = commerce_addressbook_get_active_profiles($user->uid, $type))) {
    foreach ($active_profiles as $active_profile) {
      if (commerce_addressbook_profile_is_incomplete($active_profile)) {
        $incomplete_profiles[$active_profile->profile_id] = $active_profile;
      }
      else {
        $valid_profiles[$active_profile->profile_id] = $active_profile;
      }
    }
  }

  // No profile set yet. First check if one exists already.
  if (empty($profile)) {
    if (!$valid_profiles) {

      // Incomplete profiles need to go into edit mode.
      if ($incomplete_profiles) {
        $mode = 'edit';
        $profile = reset($incomplete_profiles);
      }
      else {

        // No profiles found. Create a new one.
        $profile = commerce_customer_profile_new($type, $order->uid);
        $mode = 'new';
      }
    }
    else {
      $default_profile_id = commerce_addressbook_get_default_profile_id($user->uid, $type);

      // Try to see if the default profile is in the valid profiles array.
      if (isset($valid_profiles[$default_profile_id])) {
        $profile = $valid_profiles[$default_profile_id];
      }
      else {

        // Otherwise, just select the first one.
        $profile = reset($valid_profiles);
      }
    }
  }
  $ajax_wrapper = strtr($pane_id, '_', '-') . '-ajax-wrapper';
  $pane_form = array(
    '#parents' => array(
      $pane_id,
    ),
    '#prefix' => '<div id="' . $ajax_wrapper . '">',
    '#suffix' => '</div>',
  );
  _commerce_addressbook_add_profile_copy_checkbox($pane_form, $checkout_pane, $order, $type);
  $profile_copy_enabled = FALSE;

  // If profile copying is enabled.
  if (isset($pane_form['commerce_customer_profile_copy']) && !empty($pane_form['commerce_customer_profile_copy']['#default_value'])) {
    $profile_copy_enabled = TRUE;
    $mode = 'copy';
    field_attach_form('commerce_customer_profile', $profile, $pane_form, $form_state);
    $source_profile_type_name = variable_get('commerce_' . $checkout_pane['pane_id'] . '_profile_copy_source', NULL);
    if ($source_profile_type = commerce_customer_profile_type_load($source_profile_type_name)) {
      $common_fields = array();
      foreach (field_info_instances('commerce_customer_profile', $source_profile_type['type']) as $field_name => $field) {

        // If the field exists on the destination profile then disable it.
        if (!empty($pane_form[$field_name])) {
          $langcode = $pane_form[$field_name]['#language'];
          $pane_form[$field_name][$langcode]['#access'] = FALSE;
          $common_fields[] = $field_name;
        }
      }

      // Look for a matching destination profile in the valid profiles array.
      $source_pane_id = 'pane_customer_profile_' . $source_profile_type_name;

      // Check if we have multiple valid profiles, verify that the source
      // pane is in the "view" mode.
      if (count($valid_profiles) > 1 && $common_fields && isset($form_state[$source_pane_id]) && $form_state[$source_pane_id]['mode'] == 'view') {
        $source_profile = $form_state[$source_pane_id]['profile'];

        // Loop over the valid profiles to find a matching one.
        foreach ($valid_profiles as $valid_profile) {

          // Compare the fields that are common to both profile types.
          foreach ($common_fields as $field_name) {
            if ($source_profile->{$field_name} !== $valid_profile->{$field_name}) {
              continue 2;
            }
          }

          // Update the customer profile used by this pane to use the matching
          // one.
          $profile = $valid_profile;
          break;
        }
      }
    }
  }

  // Force the edit mode if we couldn't find "valid" profiles.
  if ($mode == 'view' && !empty($profile->profile_id) && !$valid_profiles) {
    $mode = 'edit';
  }

  // Remember the current profile and mode in form state.
  $form_state['pane_' . $checkout_pane['pane_id']] = array(
    'profile' => $profile,
    'mode' => $mode,
  );

  // Add the entity context of the current cart order.
  $profile->entity_context = array(
    'entity_type' => 'commerce_order',
    'entity_id' => $order->order_id,
  );

  // When the profile copy is checked, don't show any other form elements.
  if ($profile_copy_enabled) {
    return $pane_form;
  }
  if ($mode == 'view') {
    $content = entity_view('commerce_customer_profile', array(
      $profile->profile_id => $profile,
    ), 'customer');

    // Prepare the options.
    $options = array();
    foreach ($valid_profiles as $id => $customer_profile) {
      $field_values = field_get_items('commerce_customer_profile', $customer_profile, 'commerce_customer_address');
      $options[$customer_profile->profile_id] = $field_values[0]['thoroughfare'];
    }
    $options['new_address'] = t('+ Enter a new address');
    drupal_alter('commerce_addressbook_labels', $options, $valid_profiles);
    $pane_form['profile_selection'] = array(
      '#title' => t('Select an address'),
      '#options' => $options,
      '#type' => 'select',
      '#ajax' => array(
        'callback' => 'commerce_addressbook_pane_refresh',
        'wrapper' => $ajax_wrapper,
      ),
      '#element_validate' => array(
        'commerce_addressbook_saved_addresses_validate',
      ),
      '#default_value' => $profile->profile_id,
    );
    $pane_form['rendered_profile'] = array(
      '#markup' => drupal_render($content),
    );
    $pane_form['edit_button'] = array(
      '#type' => 'submit',
      '#name' => 'pane-' . $pane_id . '-edit',
      '#value' => t('Edit'),
      '#limit_validation_errors' => array(),
      '#ajax' => array(
        'callback' => 'commerce_addressbook_pane_refresh',
        'wrapper' => $ajax_wrapper,
      ),
      '#submit' => array(
        'commerce_addressbook_pane_edit',
      ),
    );
  }
  else {

    // Add the field widgets for the profile.
    field_attach_form('commerce_customer_profile', $profile, $pane_form, $form_state);

    // Tweak the form to remove the fieldset from the address field if there
    // is only one on this profile.
    $addressfields = array();
    foreach (commerce_info_fields('addressfield', 'commerce_customer_profile') as $field_name => $field) {
      if (!empty($pane_form[$field_name]['#language'])) {
        $langcode = $pane_form[$field_name]['#language'];

        // Only consider this addressfield if it's represented on the form.
        if (!empty($pane_form[$field_name][$langcode])) {
          $addressfields[] = array(
            $field_name,
            $langcode,
          );
        }
      }
    }

    // Check to ensure only one addressfield was found on the form.
    if (count($addressfields) == 1) {
      list($field_name, $langcode) = array_shift($addressfields);
      foreach (element_children($pane_form[$field_name][$langcode]) as $delta) {

        // Don't mess with the "Add another item" button that could be present.
        if ($pane_form[$field_name][$langcode][$delta]['#type'] != 'submit') {
          $pane_form[$field_name][$langcode][$delta]['#type'] = 'container';
        }
      }
    }
    if ($valid_profiles) {
      $pane_form['cancel_button'] = array(
        '#type' => 'submit',
        '#name' => 'pane-' . $pane_id . '-cancel',
        '#value' => t('Return to address selection'),
        '#limit_validation_errors' => array(),
        '#ajax' => array(
          'callback' => 'commerce_addressbook_pane_refresh',
          'wrapper' => $ajax_wrapper,
        ),
        '#submit' => array(
          'commerce_addressbook_pane_cancel',
        ),
        '#weight' => 100,
      );
    }
  }
  return $pane_form;
}