acquia_commercemanager-8.x-1.122/modules/acm_checkout/src/Plugin/CheckoutPane/StoredAddressTrait.php
modules/acm_checkout/src/Plugin/CheckoutPane/StoredAddressTrait.php
<?php namespace Drupal\acm_checkout\Plugin\CheckoutPane; use Drupal\acm\ACMAddressFormatter; use Drupal\Core\Form\FormStateInterface; use Drupal\Component\Utility\NestedArray; /** * Provides a trait for stored address forms. */ trait StoredAddressTrait { /** * Builds the address options list. * * @return array * An array of address options. */ public function buildAddressOptions() { $address_formatter = new ACMAddressFormatter(); $user = $this->getCurrentCommerceUser(); $addresses = $user->getAddresses(); // Stored addresses. foreach ($addresses as $address) { $option_id = $address['address_id']; $options[$option_id] = [ 'id' => $option_id, 'label' => $address_formatter->render((object) $address), ]; } // New address. $option_id = 'new_address'; $options[$option_id] = [ 'id' => $option_id, 'label' => $this->t('New address'), ]; return $options; } /** * Finds the default address option. * * @param string $type * The address type. * @param array $options * An array of address options. * * @return string * The key of the default option. */ protected function getDefaultAddressOption($type, array $options) { $default_option = NULL; // Check if any address is a default for this type. foreach ($options as $option_id => $option) { $key = "default-{$type}"; if (isset($option[$key]) && $option[$key]) { $default_option = $option_id; break; } } // Fallback to the first option. if (!$default_option || !isset($options[$default_option])) { $option_ids = array_keys($options); $default_option = reset($option_ids); } return $default_option; } /** * Finds an address by id. * * @param string|int $address_id * The address id. * * @return null|array * The found address. */ public static function findAddress($address_id) { $found_address = NULL; $user = \Drupal::service('acm.commerce_user_manager')->getAccount(); $addresses = $user->getAddresses(); $extra_keys = [ 'customer_id', 'customer_address_id', 'region_id', 'default_billing', 'default_shipping', 'extension', ]; foreach ($addresses as $address) { if ($address['address_id'] != $address_id) { continue; } // Found address, strip out extra info. foreach ($extra_keys as $key) { unset($address[$key]); } $found_address = $address; break; } return $found_address; } /** * Decorates the form with the stored address options. * * @param array $pane_form * The pane form, containing the following basic properties: * - #parents: Identifies the position of the pane form in the overall * parent form, and identifies the location where the field values are * placed within $form_state->getValues(). * @param \Drupal\Core\Form\FormStateInterface $form_state * The form state of the parent form. * @param string $type * Whether it's shipping or billing address. * @param array $current_address * The current set address. * * @return array * The updated form array. */ protected function buildStoredAddressOptions(array $pane_form, FormStateInterface $form_state, $type = 'billing', array $current_address = []) { $field_name = "{$type}_address_options"; $options = $this->buildAddressOptions(); $user_input = $form_state->getUserInput(); $values = NestedArray::getValue($user_input, $pane_form['#parents']); $default_option = NULL; if (!empty($values[$field_name])) { // The form was rebuilt via AJAX, use the submitted value. $default_option = $values[$field_name]; } else { $default_option = $this->getDefaultAddressOption($type, $options); // Check if the saved address matches an option, if so use that as the // default. if ($default_option != 'new_address') { if (isset($current_address['address_id']) && isset($options[$current_address['address_id']])) { $default_option = $current_address['address_id']; } elseif (!empty($current_address)) { $default_option = 'new_address'; } } } // Prepare the form for ajax. $pane_form['#wrapper_id'] = "{$type}-information-wrapper"; $pane_form['#prefix'] = '<div id="' . $pane_form['#wrapper_id'] . '">'; $pane_form['#suffix'] = '</div>'; $pane_form[$field_name] = [ '#type' => 'radios', '#options' => array_column($options, 'label', 'id'), '#default_value' => $default_option, '#ajax' => [ 'callback' => [get_class($this), 'ajaxRefresh'], 'wrapper' => $pane_form['#wrapper_id'], ], '#access' => count($options) > 1, ]; $pane_form['address'] = [ '#type' => 'container', '#attributes' => [ 'id' => ['address_wrapper'], ], '#access' => ($default_option == 'new_address') ? TRUE : FALSE, ]; $checkout_config = \Drupal::config('acm_checkout.settings'); $validate_address = $checkout_config->get("validate_{$type}_address"); $address_review_text = $checkout_config->get("{$type}_address_review_text"); $address_failed_text = $checkout_config->get("{$type}_address_failed_text"); $pane_form['address']['address_fields'] = [ '#type' => 'acm_address', '#default_value' => $current_address, '#display_telephone' => TRUE, '#display_title' => TRUE, '#display_firstname' => TRUE, '#display_lastname' => TRUE, '#validate_address' => $validate_address, '#address_review_text' => $address_review_text, '#address_failed_text' => $address_failed_text, ]; return $pane_form; } /** * Ajax callback. */ public static function ajaxRefresh(array $form, FormStateInterface $form_state) { $parents = $form_state->getTriggeringElement()['#parents']; array_pop($parents); return NestedArray::getValue($form, $parents); } }