You are here

uc_addresses.module in Ubercart Addresses 5.2

File

uc_addresses.module
View source
<?php

/**
 * @file
 * Adds user profile address support to Ubercart.
 *
 * The uc_addresses module adds support for one or more addresses in
 * the user's profile. When users register, they must provide an
 * address. Users can then add more addresses and edit or delete
 * existing addresses. One address must be designated as the default
 * address and cannot be deleted (but it can be edited).
 *
 * The Ubercart order process is altered so that users select delivery
 * and billing addresses from their collection of addresses rather
 * than from previous orders. Any new addresses entered during the
 * order process are automatically added to the user's list.
 * <!--break-->
 *
 * @author Ben Thompson with inspiration from uc_order.module and uc_cart.module.
 * @author Rich from Freestyle Systems (enhancements).
 * @author Tony Freixas (maintainer) from Tiger Heron LLC (major revisions).
 *
 * @ingroup uc_addresses
 */
require_once 'uc_addresses_address_pane.inc';

/**
 * Give users the ability to view anyone's default address.
 */
define('UC_ADDRESSES_ACCESS_VIEW_DEFAULT', 'view default addresses');

/**
 * Give users the ability to view anyone's addresses.
 * Anyone with this permission also has UC_ADDRESSES_ACCESS_VIEW_DEFAULT.
 */
define('UC_ADDRESSES_ACCESS_VIEW_ALL', 'view all addresses');

/**
 * Give users the ability to add or edit anyone's addresses.
 * Anyone with this permission also has
 * UC_ADDRESSES_ACCESS_VIEW_DEFAULT and UC_ADDRESSES_ACCESS_VIEW_ALL.
 */
define('UC_ADDRESSES_ACCESS_ADD_EDIT', 'add/edit addresses');

/*******************************************************************************
 * Hook Functions
 ******************************************************************************/

/**
 * Implementation of hook_menu().
 *
 * @param $may_cache A boolean that is TRUE if menu items will be cached.
 * @return A array of menu items.
 */
function uc_addresses_menu($may_cache) {
  global $user;
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/store/settings/addresses',
      'title' => t('Address settings'),
      'description' => t('Configure the address settings.'),
      'callback' => 'uc_addresses_settings_overview',
      'access' => user_access('administer store'),
      'type' => MENU_NORMAL_ITEM,
    );
    $items[] = array(
      'path' => 'admin/store/settings/addresses/overview',
      'title' => t('Overview'),
      'access' => user_access('administer store'),
      'description' => t('View the address settings.'),
      'type' => MENU_DEFAULT_LOCAL_TASK,
      'weight' => -10,
    );
    $items[] = array(
      'path' => 'admin/store/settings/addresses/edit',
      'title' => t('Edit'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'uc_addresses_settings_form',
      ),
      'access' => user_access('administer store'),
      'description' => t('Edit the address settings.'),
      'type' => MENU_LOCAL_TASK,
      'weight' => -5,
    );
  }
  else {
    drupal_add_css(drupal_get_path('module', 'uc_order') . '/uc_order.css');
    if (is_numeric(arg(1)) && intval(arg(1)) == arg(1)) {
      $items[] = array(
        'path' => 'user/' . arg(1) . '/addresses',
        'title' => t('Addresses'),
        'description' => t('Manage your addresses'),
        'callback' => 'uc_addresses_list_addresses',
        'callback arguments' => array(
          arg(1),
        ),
        'access' => user_access(UC_ADDRESSES_ACCESS_VIEW_DEFAULT) || user_access(UC_ADDRESSES_ACCESS_VIEW_ALL) || user_access(UC_ADDRESSES_ACCESS_ADD_EDIT) || $user->uid == arg(1),
        'type' => MENU_LOCAL_TASK,
        'weight' => 1,
      );
      if (!(is_numeric(arg(3)) && intval(arg(3)) == arg(3))) {
        $items[] = array(
          'path' => 'user/' . arg(1) . '/addresses/list',
          'title' => t('Address list'),
          'description' => t('Manage your addresses'),
          'access' => user_access(UC_ADDRESSES_ACCESS_VIEW_DEFAULT) || user_access(UC_ADDRESSES_ACCESS_VIEW_ALL) || user_access(UC_ADDRESSES_ACCESS_ADD_EDIT) || $user->uid == arg(1),
          'type' => MENU_DEFAULT_LOCAL_TASK,
          'weight' => 0,
        );
        $items[] = array(
          'path' => 'user/' . arg(1) . '/addresses/add',
          'title' => t('Add address'),
          'description' => t('Add a new address.'),
          'callback' => 'uc_addresses_get_address',
          'callback arguments' => array(
            arg(1),
            NULL,
            'add',
          ),
          'access' => user_access(UC_ADDRESSES_ACCESS_ADD_EDIT) || $user->uid == arg(1),
          'type' => MENU_LOCAL_TASK,
          'weight' => 3,
        );
      }
      else {
        $items[] = array(
          'path' => 'user/' . arg(1) . '/addresses/' . arg(3),
          'title' => t('View Address'),
          'description' => t('View one saved address'),
          'callback' => 'uc_addresses_list_addresses',
          'callback arguments' => array(
            arg(1),
            arg(3),
          ),
          'access' => user_access(UC_ADDRESSES_ACCESS_VIEW_DEFAULT) || user_access(UC_ADDRESSES_ACCESS_VIEW_ALL) || user_access(UC_ADDRESSES_ACCESS_ADD_EDIT) || $user->uid == arg(1),
          'type' => MENU_CALLBACK,
        );
        $items[] = array(
          'path' => 'user/' . arg(1) . '/addresses/' . arg(3) . '/edit',
          'title' => t('Edit address'),
          'callback' => 'uc_addresses_get_address',
          'callback arguments' => array(
            arg(1),
            arg(3),
            'edit',
          ),
          'access' => user_access(UC_ADDRESSES_ACCESS_ADD_EDIT) || $user->uid == arg(1),
          'type' => MENU_CALLBACK,
        );
        $items[] = array(
          'path' => 'user/' . arg(1) . '/addresses/' . arg(3) . '/delete',
          'title' => t('Delete address'),
          'callback' => 'uc_addresses_delete_address_confirm',
          'callback arguments' => array(
            arg(1),
            arg(3),
          ),
          'access' => user_access(UC_ADDRESSES_ACCESS_ADD_EDIT) || $user->uid == arg(1),
          'type' => MENU_CALLBACK,
        );
      }
    }
  }
  return $items;
}

/**
 * Implementation of hook_perm().
 *
 * @return array An array of permission names.
 */
function uc_addresses_perm() {
  return array(
    UC_ADDRESSES_ACCESS_VIEW_DEFAULT,
    UC_ADDRESSES_ACCESS_VIEW_ALL,
    UC_ADDRESSES_ACCESS_ADD_EDIT,
  );
}

/**
 * Implementation of hook_user().
 *
 * @param $op An integer representing the action being performed.
 * @param $edit An array of form values submitted by the user.
 * @param $account The user on which the operation is being performed.
 * @param $category The active category of user information being edited.
 */
function uc_addresses_user($op, &$edit, &$account, $category = NULL) {
  global $user;
  switch ($op) {
    case 'view':

      // When viewing the basic user information, all we do is add a
      // nice little message for the account holder, so that's all we
      // need to check
      if ($user->uid == $account->uid) {
        $items = array();
        $items['addresses'] = array(
          'value' => l(t('Click here to manage your addresses.'), 'user/' . $account->uid . '/addresses'),
          'class' => 'member',
        );
        return array(
          t('Addresses') => $items,
        );
      }
      else {
        return NULL;
      }
    case 'register':

      // For registration, we may want the user to enter his default
      // address
      if (variable_get('uc_addresses_require_address', TRUE)) {
        $form = uc_addresses_pane_address('new', NULL, $edit);
        $form = array(
          $form['contents'],
        );

        // Modify to what we need
        $form[0]['#title'] = t('Address');

        // Rename the fieldset
        return $form;
      }
    case 'insert':

      // We're about to add the user to the database, so get the address
      // info and add it to the address table
      $address = (object) $edit;
      $address->is_default = 0;
      _uc_addresses_db_add_address($address);
      return;
    case 'delete':

      // We're deleting the user, so delete all his/her addresses as
      // well
      db_query("DELETE FROM {uc_addresses} WHERE uid = %d", $account->uid);
      db_query("DELETE FROM {uc_addresses_defaults} WHERE uid = %d", $account->uid);
      return;
  }
}

/**
 * Implementation of hook_form_alter().
 *
 * Here we're going to override the saved address options on the
 * checkout form.
 *
 * @param $form_id The name of the form.
 * @param $form The form array.
 */
function uc_addresses_form_alter($form_id, &$form) {
  global $user;

  // This is a good place to clear any addresses we might have
  // leftover from a previous checkout
  if (isset($_SESSION['uc_addresses_saved_addresses'])) {
    $_SESSION['uc_addresses_saved_addresses'] = null;
    unset($_SESSION['uc_addresses_saved_addresses']);
  }
  if ($form_id == 'uc_cart_checkout_form') {

    // Create the list of addresses the user can select from
    // Each address is just line a full address, but on one line
    $options = NULL;
    if ($addresses = _uc_addresses_db_get_address($user->uid)) {
      $options = array(
        '0' => t('Select one...'),
      );
      foreach ($addresses as $address) {
        $address = (array) $address;
        if ($address['address_name']) {
          $options[drupal_to_js($address)] = $address['address_name'];
        }
        else {

          // Not happy about this--if uc_address_format() ever changes
          // it's output, we're hosed
          $options[drupal_to_js($address)] = preg_replace('/<.*?>/', ', ', uc_address_format($address['first_name'], $address['last_name'], $address['company'], $address['street1'], $address['street2'], $address['city'], $address['zone'], $address['postal_code'], $address['country']));
        }
      }
    }
    $address_book_icon = l(uc_store_get_icon('file:address_book', FALSE, 'address-book-icon'), 'user/' . $user->uid . '/addresses', array(), NULL, NULL, FALSE, TRUE);

    // If we have some addresses saved (almost always true), revise
    // the delivery/billing address selection
    if ($options) {

      // Might not have any shippable products so make sure the
      // delivery address exists before mucking with it
      if ($form['panes']['delivery'] && (uc_cart_is_shippable() || !variable_get('uc_cart_delivery_not_shippable', TRUE))) {
        if (variable_get('uc_pane_delivery_enabled', TRUE)) {
          $form['panes']['delivery']['#description'] = (variable_get('uc_addresses_default_delivery_address', TRUE) ? t('Edit the address below or select an address from the list. ') : t('Enter an address below or select an address from the list. ')) . t('Click !here to manage your saved addresses.', array(
            '!here' => l(t('here'), 'user/' . $user->uid . '/addresses'),
          ));
          $form['panes']['delivery']['delivery_address_select'] = array(
            '#type' => 'select',
            '#title' => t('Saved addresses'),
            '#options' => $options,
            '#attributes' => array(
              'onchange' => 'apply_address(\'delivery\', this.value);',
            ),
            '#suffix' => $address_book_icon,
            '#weight' => -10,
          );
        }
      }
      if (variable_get('uc_pane_billing_enabled', TRUE)) {
        $form['panes']['billing']['#description'] = (variable_get('uc_addresses_default_billing_address', TRUE) ? t('Edit the address below or select an address from the list. ') : t('Enter an address below or select an address from the list. ')) . t('Click !here to manage your saved addresses.', array(
          '!here' => l(t('here'), 'user/' . $user->uid . '/addresses'),
        ));
        $form['panes']['billing']['billing_address_select'] = array(
          '#type' => 'select',
          '#title' => t('Saved addresses'),
          '#options' => $options,
          '#attributes' => array(
            'onchange' => 'apply_address(\'billing\', this.value);',
          ),
          '#suffix' => $address_book_icon,
          '#weight' => -10,
        );
      }

      // Copy the default address to the delivery address fields if
      // the option is enabled and if the fields are empty
      if ($form['panes']['delivery'] && (uc_cart_is_shippable() || !variable_get('uc_cart_delivery_not_shippable', TRUE))) {
        if (variable_get('uc_addresses_default_delivery_address', TRUE) && variable_get('uc_pane_delivery_enabled', TRUE) && _uc_addresses_address_fields_empty($form['panes']['delivery'], 'delivery')) {
          foreach ($addresses as $address) {
            if ($address->is_default) {
              if (uc_address_field_enabled('first_name')) {
                $form['panes']['delivery']['delivery_first_name']['#default_value'] = $address->first_name;
              }
              if (uc_address_field_enabled('last_name')) {
                $form['panes']['delivery']['delivery_last_name']['#default_value'] = $address->last_name;
              }
              if (uc_address_field_enabled('phone')) {
                $form['panes']['delivery']['delivery_phone']['#default_value'] = $address->phone;
              }
              if (uc_address_field_enabled('company')) {
                $form['panes']['delivery']['delivery_company']['#default_value'] = $address->company;
              }
              if (uc_address_field_enabled('street1')) {
                $form['panes']['delivery']['delivery_street1']['#default_value'] = $address->street1;
              }
              if (uc_address_field_enabled('street2')) {
                $form['panes']['delivery']['delivery_street2']['#default_value'] = $address->street2;
              }
              if (uc_address_field_enabled('city')) {
                $form['panes']['delivery']['delivery_city']['#default_value'] = $address->city;
              }
              if (uc_address_field_enabled('country')) {
                $form['panes']['delivery']['delivery_country']['#default_value'] = $address->country;
              }
              if (uc_address_field_enabled('zone')) {
                $form['panes']['delivery']['delivery_zone'] = uc_zone_select(uc_get_field_name('zone'), $address->zone, NULL, $address->country, 'name', uc_address_field_required('zone'));
              }
              if (uc_address_field_enabled('postal_code')) {
                $form['panes']['delivery']['delivery_postal_code']['#default_value'] = $address->postal_code;
              }
            }
          }
        }
      }

      // Copy the default address to the billing address fields if the
      // option is enabled and if the fields are empty
      if (variable_get('uc_addresses_default_billing_address', TRUE) && variable_get('uc_pane_billing_enabled', TRUE) && _uc_addresses_address_fields_empty($form['panes']['billing'], 'billing')) {
        foreach ($addresses as $address) {
          if ($address->is_default) {
            if (uc_address_field_enabled('first_name')) {
              $form['panes']['billing']['billing_first_name']['#default_value'] = $address->first_name;
            }
            if (uc_address_field_enabled('last_name')) {
              $form['panes']['billing']['billing_last_name']['#default_value'] = $address->last_name;
            }
            if (uc_address_field_enabled('phone')) {
              $form['panes']['billing']['billing_phone']['#default_value'] = $address->phone;
            }
            if (uc_address_field_enabled('company')) {
              $form['panes']['billing']['billing_company']['#default_value'] = $address->company;
            }
            if (uc_address_field_enabled('street1')) {
              $form['panes']['billing']['billing_street1']['#default_value'] = $address->street1;
            }
            if (uc_address_field_enabled('street2')) {
              $form['panes']['billing']['billing_street2']['#default_value'] = $address->street2;
            }
            if (uc_address_field_enabled('city')) {
              $form['panes']['billing']['billing_city']['#default_value'] = $address->city;
            }
            if (uc_address_field_enabled('country')) {
              $form['panes']['billing']['billing_country']['#default_value'] = $address->country;
            }
            if (uc_address_field_enabled('zone')) {
              $form['panes']['billing']['billing_zone'] = uc_zone_select(uc_get_field_name('zone'), $address->zone, NULL, $address->country, 'name', uc_address_field_required('zone'));
            }
            if (uc_address_field_enabled('postal_code')) {
              $form['panes']['billing']['billing_postal_code']['#default_value'] = $address->postal_code;
            }
          }
        }
      }
    }
    else {
      unset($form['panes']['delivery']['delivery_address_select']);
      unset($form['panes']['billing']['billing_address_select']);
    }

    // Add the "Save address" checkbox
    // TODO: (Tony) I can add these, but don't know how to find out if
    // the checkbox was checked. For now, all order addresses are
    // automatically saved.
    //     $form['panes']['billing']['billing_address_save_address'] = array(
    //       '#title' => t('Save this address'),
    //       '#type' => 'checkbox',
    //       '#default_value' => 1,
    //       '#weight' => 10
    //       );
    //     $form['panes']['delivery']['delivery_address_save_address'] = array(
    //       '#title' => t('Save this address'),
    //       '#type' => 'checkbox',
    //       '#default_value' => 1,
    //       '#weight' => 10
    //       );
  }
}
function _uc_addresses_address_fields_empty($fields, $type) {
  if (uc_address_field_enabled('first_name') && $fields[$type . '_first_name']['#default_value']) {
    return FALSE;
  }
  else {
    if (uc_address_field_enabled('last_name') && $fields[$type . '_last_name']['#default_value']) {
      return FALSE;
    }
    else {
      if (uc_address_field_enabled('phone') && $fields[$type . '_phone']['#default_value']) {
        return FALSE;
      }
      else {
        if (uc_address_field_enabled('company') && $fields[$type . '_company']['#default_value']) {
          return FALSE;
        }
        else {
          if (uc_address_field_enabled('street1') && $fields[$type . '_street1']['#default_value']) {
            return FALSE;
          }
          else {
            if (uc_address_field_enabled('street2') && $fields[$type . '_street2']['#default_value']) {
              return FALSE;
            }
            else {
              if (uc_address_field_enabled('city') && $fields[$type . '_city']['#default_value']) {
                return FALSE;
              }
              else {
                if (uc_address_field_enabled('postal_code') && $fields[$type . '_postal_code']['#default_value']) {
                  return FALSE;
                }
              }
            }
          }
        }
      }
    }
  }
  return TRUE;
}

/*******************************************************************************
 * Hook Functions (Ubercart)
 ******************************************************************************/

/**
 * Implementation of hook_address_pane().
 *
 * @return array
 */
function uc_addresses_address_pane() {
  $panes[] = array(
    'id' => 'address',
    'callback' => 'uc_addresses_pane_address',
    'title' => t('Address'),
    'desc' => t("Manage the user's addresses and contact information."),
    'class' => 'pos-left',
    'weight' => 1,
    'show' => array(
      'view',
      'add',
      'edit',
    ),
  );
  return $panes;
}

/**
 * Use hook_order to add an address or two to the user's address list.
 * For the moment, we save all addresses. I'd like to add an option to
 * let the user select which addresses get saved.
 *
 * @param $op The operation being performed.
 * @param $arg1 A reference to the order object.
 * @param $arg2 Not used.
 */
function uc_addresses_order($op, &$arg1, $arg2) {
  global $user;
  $order = $arg1;
  if ($op == 'submit' && $order->order_status == 'in_checkout') {
    $address = new stdClass();

    // Add the billing address first. If the user has no addresses,
    // this is the one that will become the default address
    if (variable_get('uc_pane_billing_enabled', TRUE)) {
      $address->address_name = '';
      $address->uid = $order->uid;
      $address->first_name = $order->billing_first_name;
      $address->last_name = $order->billing_last_name;
      $address->company = $order->billing_company;
      $address->street1 = $order->billing_street1;
      $address->street2 = $order->billing_street2;
      $address->city = $order->billing_city;
      $address->zone = $order->billing_zone;
      $address->postal_code = $order->billing_postal_code;
      $address->country = $order->billing_country;
      $address->phone = $order->billing_phone;
      $address->is_default = 0;
      _uc_addresses_db_add_address($address, TRUE);
    }
    if (variable_get('uc_pane_delivery_enabled', TRUE) && (uc_cart_is_shippable() || !variable_get('uc_cart_delivery_not_shippable', TRUE))) {
      $address->address_name = '';
      $address->uid = $order->uid;
      $address->first_name = $order->delivery_first_name;
      $address->last_name = $order->delivery_last_name;
      $address->company = $order->delivery_company;
      $address->street1 = $order->delivery_street1;
      $address->street2 = $order->delivery_street2;
      $address->city = $order->delivery_city;
      $address->zone = $order->delivery_zone;
      $address->postal_code = $order->delivery_postal_code;
      $address->country = $order->delivery_country;
      $address->phone = $order->delivery_phone;
      $address->is_default = 0;
      _uc_addresses_db_add_address($address, TRUE);
    }
  }
  else {
    if ($user->uid == 0 && $order->uid != 0 && _uc_addresses_db_have_saved_addresses()) {
      $address = new stdClass();
      $address->uid = $order->uid;
      _uc_addresses_db_add_address($address, TRUE);
    }
  }
}

/*******************************************************************************
 * Callback Functions, Forms, and Tables
 ******************************************************************************/

/**
 * Display the addresses settings overview.
 */
function uc_addresses_settings_overview() {
  $items = array(
    variable_get('uc_addresses_default_delivery_address', TRUE) ? t('Automatically filling in the delivery address with the user\'s default address.') : t('The customer must enter or choose a delivery address.'),
    variable_get('uc_addresses_default_billing_address', TRUE) ? t('Automatically filling in the billing address with the user\'s default address.') : t('The customer must enter or choose a billing address.'),
    variable_get('uc_addresses_require_address', TRUE) ? t('The customer must enter an address when registering') : t('The customer does not enter an address when registering.'),
  );
  $sections[] = array(
    'edit' => 'admin/store/settings/addresses/edit',
    'title' => t('Address settings '),
    'items' => $items,
  );
  $output = theme('uc_settings_overview', $sections);
  return $output;
}
function uc_addresses_settings_form() {
  $form['user'] = array(
    '#type' => 'fieldset',
    '#title' => t('User settings'),
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
  );
  $form['user']['uc_addresses_default_billing_address'] = array(
    '#type' => 'checkbox',
    '#title' => t('Automatically fill in the billing address with the user\'s default address.'),
    '#default_value' => variable_get('uc_addresses_default_billing_address', TRUE),
  );
  $form['user']['uc_addresses_default_delivery_address'] = array(
    '#type' => 'checkbox',
    '#title' => t('Automatically fill in the delivery address with the user\'s default address.'),
    '#default_value' => variable_get('uc_addresses_default_delivery_address', TRUE),
  );
  $form['user']['uc_addresses_require_address'] = array(
    '#type' => 'checkbox',
    '#title' => t('Require that an address be entered during registration'),
    '#default_value' => variable_get('uc_addresses_require_address', TRUE),
  );
  return system_settings_form($form);
}

/**
 * Generate a list of one or all addresses defined by one user and
 * then theme the list for display.
 *
 * If the current user can edit the addresses, then provide an edit
 * link for each address.
 *
 * @param $address_user The user whose address list we want to display.
 * @param $aid The id of the address to display or null to display all.
 * @return The themed list (as a string).
 */
function uc_addresses_list_addresses($address_user, $aid = NULL) {
  global $user;

  // Save this for later use
  $saved_aid = $aid;

  // Determine if the user can view all addresses or just the default address
  $can_view_all_addresses = $user->uid == $address_user || user_access(UC_ADDRESSES_ACCESS_VIEW_ALL) || user_access(UC_ADDRESSES_ACCESS_ADD_EDIT);

  // Flag to determine error message
  $allowed_to_view_address = true;

  // If they can view all addresses, fetch the addresses
  if ($can_view_all_addresses) {
    $addresses = _uc_addresses_db_get_address($address_user, $aid);
  }
  else {
    if ($aid === NULL) {
      $aid = _uc_addresses_get_default_address_id($address_user);
      if ($aid === NULL) {
        $aid = 0;
      }

      // NULL would mean read all addresses
    }
    $addresses = _uc_addresses_db_get_address($address_user, $aid);
    if (is_object($addresses) && $addresses->is_default === false) {
      $addresses = FALSE;
      $allowed_to_view_address = FALSE;
    }
  }
  $output = '';

  // We have multiple addresses
  if (is_array($addresses)) {
    foreach ($addresses as $address) {
      $output .= _uc_addresses_list_one_address($address);
    }
  }
  elseif (is_object($addresses)) {
    $output .= _uc_addresses_list_one_address($addresses);
  }
  else {

    // If they asked for all addresses and got nothing, it's because
    // there is nothing
    if ($saved_aid === NULL) {
      $output .= t('No addresses have been saved.<br />');
    }
    elseif ($allowed_to_view_address) {
      $output .= t('This address does not exist.<br />');
    }
    else {
      $output .= t('You are not allowed to view this address.<br />');
    }
  }

  // Decide whether to include a link for adding a new address based
  // on whether the current user can edit the addresses
  if (user_access(UC_ADDRESSES_ACCESS_ADD_EDIT) || $user->uid == $address_user) {
    $link = l(t('Add a new address'), 'user/' . $address_user . '/addresses/add');
    $output .= $link;
  }
  return $output;
}

/**
 * List one address.
 *
 * @param $address The address object to list.
 * @return The HTML string for the address.
 */
function _uc_addresses_list_one_address($address) {
  $panes = _address_pane_list();
  foreach ($panes as $pane) {
    if (variable_get('uc_addresses_pane_' . $pane['id'] . '_enabled', TRUE)) {
      $func = $pane['callback'];
      if (function_exists($func)) {
        $return = $func('view', $address, NULL);
        if (!is_NULL($return)) {
          $data[$pane['title']] = $return;
        }
      }
    }
  }
  $output = '<div class="list_address">';
  $output .= theme('uc_addresses_list_address', $address, $data);
  $output .= '</div>';
  return $output;
}

/**
 * Theme the address list view.
 *
 * @param $address The address object we are theming.
 * @param $panes An associative array for each address pane.
 *	The key is the pane's title and the value is either the data
 *	returned for that pane or an array of returned data.
 * @return The themed address.
 * @ingroup themeable
 */
function theme_uc_addresses_list_address($address, $panes) {
  global $user;
  $address_user = $address->uid;
  $aid = $address->aid;
  drupal_add_css(drupal_get_path('module', 'uc_addresses') . '/uc_addresses.css');
  $output = '';
  if ($address->is_default) {
    $output = '<table class="address-preview-table addresses-default-address">';
  }
  else {
    $output = '<table class="address-preview-table">';
  }
  foreach ($panes as $title => $data) {

    // We add an edit link only if the user is allowed to edit this address
    if (user_access(UC_ADDRESSES_ACCESS_ADD_EDIT) || $user->uid == $address_user) {
      $output .= '<tr class="pane-title-row"><td colspan="2">' . l(t('Edit this address'), 'user/' . $address_user . '/addresses/' . $aid . '/edit') . ($address->is_default ? '' : ' | ' . l(t('Delete this address'), 'user/' . $address_user . '/addresses/' . $aid . '/delete')) . '</td></tr>';
    }
    if ($address->is_default) {
      $output .= '<tr><td colspan="2" class="addresses-default-address-label"> ' . t('Default address') . '</td></tr>';
    }
    if ($address->address_name) {
      $output .= '<tr class="pane-data-row"><td class="title-col" ' . '>' . t('Name') . ':</td><td class="data-col">' . $address->address_name . '</td></tr>';
    }
    if (is_array($data)) {
      foreach ($data as $row) {
        if (is_array($row)) {
          if (isset($row['border'])) {
            $border = ' class="row-border-' . $row['border'] . '"';
          }
          else {
            $border = '';
          }
          $output .= '<tr class="pane-data-row"' . $border . '><td class="title-col" ' . '>' . $row['title'] . ':</td><td class="data-col">' . $row['data'] . '</td></tr>';
        }
        else {
          $output .= '<tr class="pane-data-row"><td colspan="2">' . $row . '</td></tr>';
        }
      }
    }
    else {
      $output .= '<tr class="pane-data-row"><td colspan="2">' . $data . '</td></tr>';
    }
  }
  $output .= '</table><br />';
  return $output;
}

/**
 * Display a form to add a new address or edit a user's addresses.
 *
 * @param $uid The user id of the user who "owns" this address.
 * @param $aid The address id for this address (0 for new addresses)
 * @param $view The URL path for which form to display. 'add' or 'edit'.
 * @return An address form
 */
function uc_addresses_get_address($uid, $aid, $view) {
  global $user;
  $output = drupal_get_form('uc_addresses_get_address_form', $uid, $aid, $view);
  return $output;
}

/**
 * Create a form used to add a new address or edit an existing address.
 *
 * @param $address_user The user who "owns" this address.
 * @param $aid The address id for this address (0 for new addresses)
 * @param $view The URL path for which form to display. 'new', 'add' or 'edit'.
 * @return An address form
 * @ingroup forms
 */
function uc_addresses_get_address_form($address_user, $aid, $view) {

  // Cancel an address entry when a customer clicks the 'Cancel'
  // button.
  if (isset($_POST['op'])) {
    if ($_POST['op'] == t('Cancel')) {
      drupal_goto('user/' . $address_user . '/addresses');
    }
    if ($_POST['op'] == variable_get('uc_addresses_delete_button', t('Delete address'))) {
      cache_clear_all();
      drupal_goto('user/' . $address_user . '/addresses/' . $aid . '/delete');
    }
  }

  // Get the panes to display
  $form['panes'] = array(
    '#tree' => TRUE,
  );
  $panes = _address_pane_list($view);
  foreach ($panes as $pane) {
    if (in_array($view, $pane['show']) && variable_get('uc_addresses_pane_' . $pane['id'] . '_show_' . $view, TRUE)) {
      if ($aid != NULL) {
        $address = _uc_addresses_db_get_address($address_user, $aid);
        $return = $pane['callback']($view, $address, NULL);
      }
      else {
        $return = $pane['callback']($view, NULL, NULL);
      }

      // Add the pane if any display data is returned from the
      // callback
      if (is_array($return) && (!empty($return['description']) || !empty($return['contents']))) {

        // Create the fieldset for the pane
        $form['panes'][$pane['id']] = array(
          '#type' => 'fieldset',
          '#title' => $pane['title'],
          '#description' => !empty($return['description']) ? $return['description'] : NULL,
          '#collapsible' => !empty($pane['collapsible']) ? $pane['collapsible'] : FALSE,
          '#collapsed' => FALSE,
          '#attributes' => array(
            'id' => $pane['id'] . '-pane',
          ),
          '#theme' => $return['theme'],
        );

        // Add the contents of the fieldset if any were returned
        if (!empty($return['contents'])) {
          $form['panes'][$pane['id']] = array_merge($form['panes'][$pane['id']], $return['contents']);
        }
      }
    }
  }
  $form['cancel'] = array(
    '#type' => 'submit',
    '#submit' => FALSE,
    '#value' => t('Cancel'),
  );

  // Edit an existing address
  if (arg(4) == 'edit') {
    $form['delete'] = array(
      '#type' => 'submit',
      '#value' => variable_get('uc_addresses_delete_button', t('Delete address')),
      '#disabled' => $address->is_default,
    );
    $form['continue'] = array(
      '#type' => 'submit',
      '#value' => variable_get('uc_addresses_update_button', t('Update address')),
    );
  }
  else {
    $form['continue'] = array(
      '#type' => 'submit',
      '#value' => variable_get('uc_addresses_update_button', t('Add address')),
    );
  }
  $form['#submit'] = array(
    'uc_addresses_get_address_form_submit' => array(
      $address_user,
      $aid,
      $view,
    ),
  );
  return $form;
}

/**
 * Theme the add or edit address form.
 *
 * @param $form The form array to theme.
 * @return The themed form (as a string).
 * @ingroup themeable
 */
function theme_uc_addresses_get_address_form($form) {
  drupal_add_css(drupal_get_path('module', 'uc_addresses') . '/uc_addresses.css');
  $output = '<p>';
  foreach (element_children($form['panes']) as $pane_id) {

    // TODO: (Tony) Not sure what's going on here.
    if (function_exists($func = _address_pane_data($pane_id, 'callback'))) {
      $result = $func('theme', $form['panes'][$pane_id], NULL);
      if (!empty($result)) {
        $output .= $result;
        $form['panes'][$pane_id] = array();
      }
      else {
        $output .= drupal_render($form['panes'][$pane_id]);
      }
    }
    else {
      $output .= drupal_render($form['panes'][$pane_id]);
    }
  }
  $output .= '<div id="checkout-form-bottom">' . drupal_render($form) . '</div>';
  return $output;
}

/**
 * Handle the form submit. If $view is 'edit' run update database
 * function, if 'new' or 'add', run insert database function.
 *
 * @param $form_id The name of the form.
 * @param $form_values The form array.
 * @param $address_user The user who "owns" the address.
 * @param $aid The address id (0 for new addresses).
 * @param $view Either ''new', 'add' or edit'.
 * @return The path where we should wind up.
 */
function uc_addresses_get_address_form_submit($form_id, $form_values, $address_user, $aid, $view) {
  global $user;
  $address = new stdClass();
  $address->uid = $address_user;
  $valid = TRUE;
  foreach (element_children($form_values['panes']) as $pane_id) {
    $func = _address_pane_data($pane_id, 'callback');
    $isvalid = $func('process', $address, $form_values['panes'][$pane_id]);
    if ($isvalid === FALSE) {
      $_SESSION['expanded_panes'][] = $key;
      $valid = FALSE;
    }
  }
  if ($view == 'edit') {

    // Update database
    $address->aid = $aid;
    _uc_addresses_db_update_address($address);
  }
  elseif ($view == 'new' || $view == 'add') {

    // Insert into datebase
    _uc_addresses_db_add_address($address);
  }
  return 'user/' . $address->uid . '/addresses';
}

/**
 * Format an address the same as the rest of the Ubercart store.
 *
 * @param $items An object containing address information.
 * @return A formatted address.
 */
function uc_addresses_address($items) {
  $address = uc_address_format($items->first_name, $items->last_name, $items->company, $items->street1, $items->street2, $items->city, $items->zone, $items->postal_code, $items->country);
  return $address;
}

/**
 * Display a confirmation page before deleting an address.
 *
 * @param $address_user The id of the user who "owns" the address.
 * @param $aid The id of the address to delete.
 */
function uc_addresses_delete_address_confirm($address_user, $aid) {

  // We returned to this page after the user pressed cancel. Redirect
  // the user back to the address list
  if ($_POST['op'] == t('Cancel')) {

    // TODO: (Tony) This seems draconian
    cache_clear_all();
    drupal_goto('user/' . $address_user . '/addresses/');
  }
  $form = drupal_get_form('uc_addresses_delete_address_confirm_form', $address_user, $aid);

  // If the address doesn't exist, let's get out of here
  $address = _uc_addresses_db_get_address($address_user, $aid);
  if ($address === FALSE) {
    $_SESSION['add_address'] = NULL;
    unset($_SESSION['add_address']);
    drupal_goto('user/' . $address_user . '/addresses/');
  }

  // Address exists. Make sure it's not the default address
  if (_uc_addresses_db_check_if_default($aid)) {
    drupal_set_message(t('You cannot delete your default address'), 'warning');
    drupal_goto('user/' . $address_user . '/addresses');
  }

  // Display a caution
  $help = variable_get('uc_addresses_delete_instructions', t('Are you are sure you want to Delete this address? ' . 'Once deleted, the address cannot be recovered.', array(
    '!delete' => variable_get('uc_addresses_delete_button', t('Delete address')),
  )));
  $panes = _address_pane_list();
  foreach ($panes as $pane) {
    if (variable_get('uc_addresses_pane_' . $pane['id'] . '_enabled', TRUE)) {
      $func = $pane['callback'];
      if (function_exists($func)) {
        $return = $func('view', $address, NULL);
        if (!is_NULL($return)) {
          $data[$pane['title']] = $return;
        }
      }
    }
  }
  $output = theme('uc_addresses_address_delete_confirm', $help, $data, $form);
  return $output;
}

/**
 * Theme the address deletion confirmation form.
 *
 * @param $help The help message to display.
 * @param $panes An associative array for each address pane that
 *	has information to add to the delete page. The key is the
 *	pane's title and the value is either the data returned for
 *	that pane or an array of returned data.
 * @param $form The HTML version of the form that by default
 *	includes the 'Back' and 'Delete Address' buttons at the bottom
 *	of the confirmation page.
 * @return The themed confirmation form (as a string).
 * @ingroup themeable
 */
function theme_uc_addresses_address_delete_confirm($help, $panes, $form) {
  drupal_add_css(drupal_get_path('module', 'uc_addresses') . '/uc_addresses.css');
  $output = '<p>' . $help . '</p>';
  $output .= '<div class="list_address"><table class="address-preview-table">';
  foreach ($panes as $title => $data) {
    $output .= '<tr class="pane-title-row"><td colspan="2">' . t('Address') . '</td></tr>';
    if (is_array($data)) {
      foreach ($data as $row) {
        if (is_array($row)) {
          if (isset($row['border'])) {
            $border = ' class="row-border-' . $row['border'] . '"';
          }
          else {
            $border = '';
          }
          $output .= '<tr class="pane-data-row"' . $border . '><td class="title-col" ' . '>' . $row['title'] . ':</td><td class="data-col">' . $row['data'] . '</td></tr>';
        }
        else {
          $output .= '<tr class="pane-data-row"><td colspan="2">' . $row . '</td></tr>';
        }
      }
    }
    else {
      $output .= '<tr class="pane-data-row"><td colspan="2">' . $data . '</td></tr>';
    }
  }
  $output .= '<tr class="preview-button-row"><td colspan="2">' . $form . '</td></tr></table>';
  $output .= '</div>';
  return $output;
}

/**
 * Get the submit buttons to confirm deletion of a user's address.
 *
 * @param $address_user The id of the user who "owns" the address.
 * @param $aid id of the address we are deleting.
 * @return The buttons for the form (as a string).
 * @ingroup forms
 */
function uc_addresses_delete_address_confirm_form($address_user, $aid) {

  // The buttons
  $form['cancel'] = array(
    '#type' => 'button',
    '#value' => t('Cancel'),
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => variable_get('uc_addresses_delete_button', t('Delete address')),
  );

  // Where we go if they say "OK"
  $form['#submit'] = array(
    'uc_addresses_delete_address_confirm_form_submit' => array(
      $address_user,
      $aid,
    ),
  );
  return $form;
}

/**
 * Delete a user-confirmed address.
 *
 * @param $form_id The name of the form.
 * @param $form_values The form parameters and their values.
 * @param $address_user The user id of the user who owns the address.
 * @param $aid The id of the address to delete.
 * @return The path to go to after the deletion occurs.
 */
function uc_addresses_delete_address_confirm_form_submit($form_id, $form_values, $address_user, $aid) {
  switch ($form_values['op']) {
    case variable_get('uc_addresses_delete_button', t('Delete address')):
      $_SESSION['do_complete'] = TRUE;
      if (_uc_addresses_db_delete_address($aid)) {
        drupal_set_message(t('The address has been deleted.'));
      }
      return 'user/' . $address_user . '/addresses';
  }
}

/*******************************************************************************
 * Database Functions
 ******************************************************************************/

/**
 * Add a new address to the database table. If the address is already
 * in the database (for this user), it is not added.
 *
 * @param $address The address to add (as an object).
 * @param The id of the new address or FALSE if there was an error.
 */
function _uc_addresses_db_add_address($address, $silent = FALSE) {
  global $user;

  // If this is an anonymous user, save the address for later
  if ($address->uid == 0 && isset($address->first_name)) {
    $saved_addresses = NULL;
    if (isset($_SESSION['uc_addresses_saved_addresses'])) {
      $saved_addresses = $_SESSION['uc_addresses_saved_addresses'];
    }
    if (!is_array($saved_addresses)) {
      $saved_addresses = array();
    }
    $saved_addresses[] = drupal_clone($address);
    $_SESSION['uc_addresses_saved_addresses'] = $saved_addresses;
    return;
  }

  // If we have a logged in user but no address information, then some
  // module created a user without going through the normal
  // registration procedure. Let's see if we have any address
  // information saved for this user
  if ($address->uid != 0 && !isset($address->first_name)) {
    if (isset($_SESSION['uc_addresses_saved_addresses'])) {
      $saved_addresses = $_SESSION['uc_addresses_saved_addresses'];
      if (is_array($saved_addresses)) {
        foreach ($saved_addresses as $addr) {
          $addr->uid = $address->uid;
          $status = _uc_addresses_db_add_address($addr, true);
          if ($status === FALSE) {
            return FALSE;
          }
        }
      }
      $_SESSION['uc_addresses_saved_addresses'] = null;
      unset($_SESSION['uc_addresses_saved_addresses']);
    }

    // Let this user get created without an address
    return TRUE;
  }

  // Final special case: no logged in user and no address information!
  if ($address->uid == 0) {
    return TRUE;
  }

  // From this point on, we have both a user and an address to add
  // We need to work with systems where this module is added when
  // users are already present. Find out how many addresses this user has
  $num_addresses = db_result(db_query("SELECT COUNT(*) FROM {uc_addresses} WHERE uid = %d", $address->uid));

  // If this is the first address the user has ever added, make it the
  // default address
  if ($num_addresses < 1) {
    $address->is_default = 1;
  }
  if ($num_addresses > 0) {

    // Check for problems
    $result = _uc_addresses_db_check_address($address, 'add', $silent);
    if (!$result) {
      return FALSE;
    }
  }
  else {
    _uc_addresses_db_normalize_address($address);
  }

  // Add the address
  $aid = db_next_id('{uc_addresses}_aid');
  db_query("INSERT INTO {uc_addresses} (aid, uid, first_name, last_name, " . "phone, company, street1, street2, city, zone, postal_code, country, " . "address_name, " . "created, modified) VALUES (%d, %d, " . "'%s', '%s', '%s', " . "'%s', '%s', '%s', " . "'%s', %d, '%s', %d, " . "'%s', " . "%d, %d)", $aid, $address->uid, $address->first_name, $address->last_name, $address->phone, $address->company, $address->street1, $address->street2, $address->city, $address->zone, $address->postal_code, is_NULL($address->country) || $address->country == 0 ? variable_get('uc_store_country', 840) : $address->country, $address->address_name, time(), time());

  // Update the default address, if necessary
  if ($address->is_default) {
    if ($num_addresses < 1) {
      db_query("INSERT INTO {uc_addresses_defaults} (aid, uid) VALUES (%d, %d)", $aid, $address->uid);
    }
    else {
      db_query("UPDATE {uc_addresses_defaults} SET aid = %d WHERE uid = %d", $aid, $address->uid);
    }
  }
  return $aid;
}

/**
 * Check to see if we saved any addresses for an anonymous user.
 *
 * @return True if there are any saved addresses.
 */
function _uc_addresses_db_have_saved_addresses() {
  return isset($_SESSION['uc_addresses_saved_addresses']) && is_array($_SESSION['uc_addresses_saved_addresses']);
}

/**
 * Update an address in the database table.
 *
 * @param $address The address to add.
 * @param A boolean that is TRUE if the address was added, FALSE otherwise.
 */
function _uc_addresses_db_update_address($address) {

  // Check for problems
  $result = _uc_addresses_db_check_address($address, 'update', false);
  if (!$result) {
    return FALSE;
  }

  // We're set to go
  db_query("UPDATE {uc_addresses} SET " . "first_name = '%s', " . "last_name = '%s', " . "phone = '%s', " . "company = '%s', " . "street1 = '%s', " . "street2 = '%s', " . "city = '%s', " . "zone = %d, " . "postal_code = '%s', " . "country = %d, " . "address_name = '%s', " . "modified = %d " . "WHERE aid = %d", $address->first_name, $address->last_name, $address->phone, $address->company, $address->street1, $address->street2, $address->city, $address->zone, $address->postal_code, $address->country, $address->address_name, time(), $address->aid);

  // Update the default address, if necessary
  if ($address->is_default) {
    db_query("UPDATE {uc_addresses_defaults} SET aid = %d WHERE uid = %d", $address->aid, $address->uid);
  }
  drupal_set_message(t('The address was updated.'));
  return TRUE;
}

/**
 * Before adding or updating an address, check it for errors.
 *
 * @param $address The address we are about to add or update.
 * @param $op Either 'add' or 'update'.
 * @param A boolean which, if TRUE, tells us not to display warnings
 *	to the user.
 * @return TRUE if the address is valid, FALSE otherwise.
 */
function _uc_addresses_db_check_address($address, $op, $silent) {
  _uc_addresses_db_normalize_address($address);
  $result = db_query("SELECT aid FROM {uc_addresses} WHERE " . "uid = %d AND " . "first_name = '%s' AND " . "last_name = '%s' AND " . "phone = '%s' AND " . "company = '%s' AND " . "street1 = '%s' AND " . "street2 = '%s' AND " . "city = '%s' AND " . "zone = '%s' AND " . "postal_code = '%s' AND " . "country = '%s'", $address->uid, $address->first_name, $address->last_name, $address->phone, $address->company, $address->street1, $address->street2, $address->city, $address->zone, $address->postal_code, $address->country);
  $num_rows = 0;
  while ($db_address = db_fetch_object($result)) {
    $num_rows++;

    // If the address appears more than once, the database table is
    // corrupted. The fix, however, is simple: delete the extra
    // address
    if ($num_rows > 1) {
      drupal_set_message(t('This address appears more than once in your address book. ' . 'Please delete the duplicates and file a bug report.'), 'error');
      return FALSE;
    }

    // If we get one address, it's OK only if it is the address we're
    // trying to add or update
    if (!isset($address->aid) || $db_address->aid != $address->aid) {
      if (!$silent) {
        if ($op == 'add') {
          drupal_set_message(t('This address already appears in your address book. ' . 'A new address was not added.'), 'warning');
        }
        else {
          drupal_set_message(t('The revised address is already in your address book. ' . 'Your change was not made.'), 'warning');
        }
      }
      return FALSE;
    }
  }

  // Now check to make sure the address_name is not already in use
  // Unless its for the address we are trying to update
  if ($address->address_name) {
    $result = db_query("SELECT aid FROM {uc_addresses} WHERE " . "uid = %d AND " . "address_name = '%s'", $address->uid, $address->address_name);
    while ($db_address = db_fetch_object($result)) {
      if ($db_address->aid != $address->aid && !$silent) {
        drupal_set_message(t('The short name you selected for this address is already in your address book. ' . 'Please select a different name.'), 'error');
        return FALSE;
      }
    }
  }
  return TRUE;
}

/**
 * SQL gets a little weird when comparing nulls. "value = NULL" is
 * always false, even if the value is NULL! You have to write "value
 * IS NULL" to get the "right" answer. Rather than changing the
 * comparisons all over the place, we will make sure no value is null.
 * Because address fields can be disabled, any field could be null.
 *
 * @param $address The address to normalize (altered in place).
 */
function _uc_addresses_db_normalize_address(&$address) {

  // Yes, the comparisons are checking for null, '', and 0. This is
  // deliberate--call me paranoid
  if (!$address->first_name) {
    $address->first_name = '';
  }
  if (!$address->last_name) {
    $address->last_name = '';
  }
  if (!$address->phone) {
    $address->phone = '';
  }
  if (!$address->company) {
    $address->company = '';
  }
  if (!$address->street1) {
    $address->street1 = '';
  }
  if (!$address->street2) {
    $address->street2 = '';
  }
  if (!$address->city) {
    $address->city = '';
  }
  if (!$address->zone) {
    $address->zone = 0;
  }
  if (!$address->postal_code) {
    $address->postal_code = '';
  }
  if (!$address->country) {
    $address->country = variable_get('uc_store_country', 840);
  }
  if (!isset($address->address_name) || !$address->address_name) {
    $address->address_name = '';
  }
}

/**
 * Get an address or list of addresses from the database.
 *
 * @param $address_user The id of the user who "owns" the address.
 * @param $aid The id of the address to fetch. If NULL, fetch
 *	all addresses owned by the user.
 * @return FALSE on error. An object if $aid was not NULL. An
 *	array of objects if $aid was NULL.
 */
function _uc_addresses_db_get_address($address_user, $aid = NULL) {

  // If $aid is present, return just the one address
  if ($aid) {
    $result = db_query("SELECT * FROM {uc_addresses} WHERE aid = %d ", $aid);

    // Check to make sure there is data
    if (($address = db_fetch_object($result)) == FALSE) {
      return FALSE;
    }

    // Check to make sure it's from the right user
    if ($address->uid != $address_user) {
      return FALSE;
    }

    // Find out if this is the default address
    $address->is_default = 0;
    $def = db_query("SELECT aid FROM {uc_addresses_defaults} WHERE uid = %d", $address_user);
    if ($default_aid = db_fetch_object($def)) {
      $address->is_default = $default_aid->aid == $address->aid;
    }

    // All OK
    return $address;
  }

  // If $aid is NULL, return all addresses for that user
  $result = db_query("SELECT * FROM {uc_addresses} WHERE uid = %d ORDER BY created", $address_user);
  $default_aid = _uc_addresses_get_default_address_id($address_user);

  // Gather up everything
  $num_rows = 0;
  while ($address = db_fetch_object($result)) {
    $num_rows++;
    $address->is_default = $default_aid == $address->aid;
    $addresses[] = $address;
  }
  if ($num_rows == 0) {
    return FALSE;
  }
  return $addresses;
}

/**
 * Get a user's default address id. Because the addresses module can
 * be added to an existing system, it's possible that some people will
 * not have a default address (or any addresses).
 *
 * @param $address_user The id of the user who "owns" the address.
 * @return The $id of the default address or NULL if none.
 */
function _uc_addresses_get_default_address_id($address_user) {
  $def = db_query("SELECT aid FROM {uc_addresses_defaults} WHERE uid = %d", $address_user);
  $aid = null;
  while ($obj = db_fetch_object($def)) {
    $aid = $obj->aid;
  }
  return $aid;
}

/**
 * Delete an address from the database.
 *
 * @param $aid The id of the address to delete.
 * @return Returns TRUE if the address was deleted.
 */
function _uc_addresses_db_delete_address($aid) {
  if (_uc_addresses_db_check_if_default($aid)) {
    drupal_set_message(t('You cannot delete your default address'), 'warning');
    return FALSE;
  }
  else {
    db_query("DELETE FROM {uc_addresses} WHERE aid = %d", $aid);
    return TRUE;
  }
}

/**
 * Check to see if an address is the default address.
 *
 * @param $aid The id of the address to check.
 * @return Returns TRUE if the address is the default address.
 */
function _uc_addresses_db_check_if_default($aid) {
  $count = db_result(db_query("SELECT COUNT(*) FROM {uc_addresses_defaults} WHERE " . "aid = %d", $aid));
  if ($count > 0) {
    return TRUE;
  }
  return FALSE;
}

Functions

Namesort descending Description
theme_uc_addresses_address_delete_confirm Theme the address deletion confirmation form.
theme_uc_addresses_get_address_form Theme the add or edit address form.
theme_uc_addresses_list_address Theme the address list view.
uc_addresses_address Format an address the same as the rest of the Ubercart store.
uc_addresses_address_pane Implementation of hook_address_pane().
uc_addresses_delete_address_confirm Display a confirmation page before deleting an address.
uc_addresses_delete_address_confirm_form Get the submit buttons to confirm deletion of a user's address.
uc_addresses_delete_address_confirm_form_submit Delete a user-confirmed address.
uc_addresses_form_alter Implementation of hook_form_alter().
uc_addresses_get_address Display a form to add a new address or edit a user's addresses.
uc_addresses_get_address_form Create a form used to add a new address or edit an existing address.
uc_addresses_get_address_form_submit Handle the form submit. If $view is 'edit' run update database function, if 'new' or 'add', run insert database function.
uc_addresses_list_addresses Generate a list of one or all addresses defined by one user and then theme the list for display.
uc_addresses_menu Implementation of hook_menu().
uc_addresses_order Use hook_order to add an address or two to the user's address list. For the moment, we save all addresses. I'd like to add an option to let the user select which addresses get saved.
uc_addresses_perm Implementation of hook_perm().
uc_addresses_settings_form
uc_addresses_settings_overview Display the addresses settings overview.
uc_addresses_user Implementation of hook_user().
_uc_addresses_address_fields_empty
_uc_addresses_db_add_address Add a new address to the database table. If the address is already in the database (for this user), it is not added.
_uc_addresses_db_check_address Before adding or updating an address, check it for errors.
_uc_addresses_db_check_if_default Check to see if an address is the default address.
_uc_addresses_db_delete_address Delete an address from the database.
_uc_addresses_db_get_address Get an address or list of addresses from the database.
_uc_addresses_db_have_saved_addresses Check to see if we saved any addresses for an anonymous user.
_uc_addresses_db_normalize_address SQL gets a little weird when comparing nulls. "value = NULL" is always false, even if the value is NULL! You have to write "value IS NULL" to get the "right" answer. Rather than changing the comparisons all over the…
_uc_addresses_db_update_address Update an address in the database table.
_uc_addresses_get_default_address_id Get a user's default address id. Because the addresses module can be added to an existing system, it's possible that some people will not have a default address (or any addresses).
_uc_addresses_list_one_address List one address.

Constants

Namesort descending Description
UC_ADDRESSES_ACCESS_ADD_EDIT Give users the ability to add or edit anyone's addresses. Anyone with this permission also has UC_ADDRESSES_ACCESS_VIEW_DEFAULT and UC_ADDRESSES_ACCESS_VIEW_ALL.
UC_ADDRESSES_ACCESS_VIEW_ALL Give users the ability to view anyone's addresses. Anyone with this permission also has UC_ADDRESSES_ACCESS_VIEW_DEFAULT.
UC_ADDRESSES_ACCESS_VIEW_DEFAULT Give users the ability to view anyone's default address.