You are here

uc_store.module in Ubercart 5

Contains global Ubercart functions and store administration functionality.

The store module is a container of sorts for various helper functions used in different parts of the Ubercart core. It also provides screens and settings pages for use in store administration.

File

uc_store/uc_store.module
View source
<?php

/**
 * @file
 * Contains global Ubercart functions and store administration functionality.
 *
 * The store module is a container of sorts for various helper functions used
 * in different parts of the Ubercart core.  It also provides screens and
 * settings pages for use in store administration.
 */

/**
 * Unit conversion ratios.
 *
 * Used by the unit conversion functions uc_weight_convesion() and
 * uc_length_conversion().
 */
define('KG_TO_KG', 1);
define('KG_TO_G', 1000);
define('KG_TO_LB', 2.204622621849);
define('KG_TO_OZ', 35.27396194958);
define('G_TO_G', 1);
define('G_TO_KG', 0.001);
define('G_TO_LB', 0.002204622622);
define('G_TO_OZ', 0.03527396195);
define('LB_TO_LB', 1);
define('LB_TO_OZ', 16);
define('LB_TO_KG', 0.45359237);
define('LB_TO_G', 453.59237);
define('OZ_TO_OZ', 1);
define('OZ_TO_LB', 0.0625);
define('OZ_TO_G', 28.349523125);
define('OZ_TO_KG', 0.028349523);
define('IN_TO_IN', 1);
define('IN_TO_FT', 0.083333333333);
define('IN_TO_CM', 2.54);
define('IN_TO_MM', 25.4);
define('FT_TO_FT', 1);
define('FT_TO_IN', 12);
define('FT_TO_CM', 30.48);
define('FT_TO_MM', 304.8);
define('CM_TO_CM', 1);
define('CM_TO_IN', 0.393700787402);
define('CM_TO_FT', 0.03280839895);
define('CM_TO_MM', 10);
define('MM_TO_MM', 1);
define('MM_TO_IN', 0.03937007874);
define('MM_TO_FT', 0.003280839895);
define('MM_TO_CM', 0.1);

/*******************************************************************************
 * Hook Functions (Drupal)
 ******************************************************************************/

/**
 * Implementation of hook_menu().
 */
function uc_store_menu($may_cache) {
  $items = array();
  drupal_add_css(drupal_get_path('module', 'uc_store') . '/uc_store.css');
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/store',
      'title' => t('Store administration'),
      'description' => t('Administer store settings, products, orders, and more.'),
      'callback' => 'uc_store_admin',
      'access' => user_access('administer store'),
      'type' => MENU_NORMAL_ITEM,
    );
    $items[] = array(
      'path' => 'admin/store/customers',
      'title' => t('Customers'),
      'description' => t('View and modify customer information and orders.'),
      'callback' => 'uc_store_customers',
      'callback arguments' => array(
        NULL,
        NULL,
        NULL,
        25,
      ),
      'access' => user_access('view customers'),
      'weight' => -6,
      'type' => MENU_NORMAL_ITEM,
    );
    $items[] = array(
      'path' => 'admin/store/customers/view',
      'title' => t('View customers'),
      'description' => t('View and modify customer information and orders.'),
      'callback arguments' => array(
        NULL,
        NULL,
        NULL,
        25,
      ),
      'access' => user_access('view customers'),
      'weight' => -10,
      'type' => MENU_NORMAL_ITEM,
    );
    $items[] = array(
      'path' => 'admin/store/customers/search',
      'title' => t('Search customers'),
      'description' => t('Search through your customer list.'),
      'callback' => 'uc_store_customer_search',
      'access' => user_access('view customers'),
      'weight' => -5,
      'type' => MENU_NORMAL_ITEM,
    );
    $items[] = array(
      'path' => 'admin/store/reports',
      'title' => t('Reports'),
      'description' => t('Browse various store reports.'),
      'callback' => 'uc_store_reports',
      'access' => user_access('view store reports'),
      'weight' => 2,
      'type' => MENU_NORMAL_ITEM,
    );
    $items[] = array(
      'path' => 'admin/store/settings',
      'title' => t('Configuration'),
      'description' => t('Adjust configuration settings for Ubercart.'),
      'callback' => 'uc_store_configuration_page',
      'access' => user_access('administer store'),
      'weight' => 6,
      'type' => MENU_NORMAL_ITEM,
    );
    $items[] = array(
      'path' => 'admin/store/help',
      'title' => t('Help'),
      'description' => t('Links to get help!'),
      'callback' => 'uc_store_ubercart_help',
      'access' => user_access('administer store'),
      'weight' => 10,
      'type' => MENU_NORMAL_ITEM,
    );
    $items[] = array(
      'path' => 'admin/store/help/tokens',
      'title' => t('Using tokens'),
      'description' => t('Understand what tokens are and how to use them.'),
      'callback' => 'uc_store_ubercart_help_tokens',
      'access' => user_access('administer store'),
      'type' => MENU_NORMAL_ITEM,
    );
    $items[] = array(
      'path' => 'admin/store/settings/countries',
      'title' => t('Country settings'),
      'callback' => 'uc_country_settings_overview',
      'access' => user_access('administer store'),
      'description' => t('Configure country specific settings.'),
      'type' => MENU_NORMAL_ITEM,
    );
    $items[] = array(
      'path' => 'admin/store/settings/countries/overview',
      'title' => t('Overview'),
      'access' => user_access('administer store'),
      'description' => t('View the country settings.'),
      'type' => MENU_DEFAULT_LOCAL_TASK,
      'weight' => -10,
    );
    $items[] = array(
      'path' => 'admin/store/settings/countries/edit',
      'title' => t('Edit'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'uc_country_import_form',
      ),
      'access' => user_access('administer store'),
      'description' => t('Edit the country settings.'),
      'type' => MENU_LOCAL_TASK,
      'weight' => -5,
    );
    $items[] = array(
      'path' => 'admin/store/settings/countries/edit/import',
      'title' => t('Import countries'),
      'access' => user_access('administer store'),
      'description' => t('Import and manage countries.'),
      'type' => MENU_DEFAULT_LOCAL_TASK,
      'weight' => -10,
    );
    $items[] = array(
      'path' => 'admin/store/settings/countries/edit/formats',
      'title' => t('Country formats'),
      'access' => user_access('administer store'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'uc_country_formats_form',
      ),
      'description' => t('Edit the country specific format settings.'),
      'type' => MENU_LOCAL_TASK,
      'weight' => -5,
    );
    $items[] = array(
      'path' => 'admin/store/settings/store',
      'title' => t('Store settings'),
      'callback' => 'uc_store_store_settings_overview',
      'access' => user_access('administer store'),
      'description' => t('Configure the main store settings.'),
      'type' => MENU_NORMAL_ITEM,
    );
    $items[] = array(
      'path' => 'admin/store/settings/store/overview',
      'title' => t('Overview'),
      'access' => user_access('administer store'),
      'description' => t('View the store settings.'),
      'type' => MENU_DEFAULT_LOCAL_TASK,
      'weight' => -10,
    );
    $items[] = array(
      'path' => 'admin/store/settings/store/edit',
      'title' => t('Edit'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'uc_store_store_settings_form',
      ),
      'access' => user_access('administer store'),
      'description' => t('Edit the store settings.'),
      'type' => MENU_LOCAL_TASK,
      'weight' => -5,
    );
    $items[] = array(
      'path' => 'admin/store/settings/store/edit/contact',
      'title' => t('Contact settings'),
      'access' => user_access('administer store'),
      'description' => t('Edit the contact settings.'),
      'type' => MENU_DEFAULT_LOCAL_TASK,
      'weight' => -10,
    );
    $items[] = array(
      'path' => 'admin/store/settings/store/edit/display',
      'title' => t('Display settings'),
      'access' => user_access('administer store'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'uc_store_display_settings_form',
      ),
      'description' => t('Edit the display settings.'),
      'type' => MENU_LOCAL_TASK,
      'weight' => -5,
    );
    $items[] = array(
      'path' => 'admin/store/settings/store/edit/format',
      'title' => t('Format settings'),
      'access' => user_access('administer store'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'uc_store_format_settings_form',
      ),
      'description' => t('Edit the format settings.'),
      'type' => MENU_LOCAL_TASK,
      'weight' => 0,
    );
    $items[] = array(
      'path' => 'admin/store/settings/store/edit/report',
      'title' => t('Reporting settings'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'uc_store_report_settings',
      ),
      'access' => user_access('administer store'),
      'description' => t('Report version information to Ubercart.org.'),
      'type' => MENU_LOCAL_TASK,
      'weight' => 10,
    );
    $items[] = array(
      'path' => 'admin/store/settings/store/initials',
      'title' => t('User initials'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'uc_store_initials',
      ),
      'access' => user_access('administer store'),
      'description' => t('Assign initials to user accounts.'),
      'type' => MENU_NORMAL_ITEM,
    );
    $items[] = array(
      'path' => 'admin/store/settings/tables',
      'title' => t('Table display settings'),
      'callback' => 'uc_store_tables',
      'access' => user_access('administer store'),
      'description' => t('Configure the display of tables in your store.'),
      'type' => MENU_NORMAL_ITEM,
    );
  }
  else {
    uc_add_js(array(
      'base_path' => base_path(),
    ), 'setting');
    $items[] = array(
      'path' => 'uc_js_util/' . arg(1),
      'title' => t('JS utilities'),
      'callback' => 'uc_store_js_util',
      'callback arguments' => array(
        arg(1),
      ),
      'access' => user_access('access content'),
      'type' => MENU_CALLBACK,
    );
    if (arg(2) == 'customers') {
      $items[] = array(
        'path' => 'admin/store/customers/orders/' . arg(4),
        'title' => t('Customer orders'),
        'callback' => 'uc_store_customer_orders',
        'callback arguments' => array(
          intval(arg(4)),
        ),
        'description' => t('View a list of orders placed by this customer.'),
        'access' => user_access('view all orders'),
        'weight' => -5,
        'type' => MENU_CALLBACK,
      );
    }
    if (is_numeric(arg(4))) {
      $items[] = array(
        'path' => 'admin/store/settings/countries/' . arg(4) . '/disable',
        'title' => t('Disable a country'),
        'description' => t('Disable a country from use.'),
        'callback' => 'uc_country_disable',
        'callback arguments' => array(
          arg(4),
        ),
        'access' => user_access('administer store'),
        'type' => MENU_CALLBACK,
      );
      $items[] = array(
        'path' => 'admin/store/settings/countries/' . arg(4) . '/enable',
        'title' => t('Enable a country'),
        'description' => t('Enable a disabled country.'),
        'callback' => 'uc_country_enable',
        'callback arguments' => array(
          arg(4),
        ),
        'access' => user_access('administer store'),
        'type' => MENU_CALLBACK,
      );
      $items[] = array(
        'path' => 'admin/store/settings/countries/' . arg(4) . '/remove',
        'title' => t('Remove a country'),
        'description' => t('Remove an installed country.'),
        'callback' => 'drupal_get_form',
        'callback arguments' => array(
          'uc_country_remove_form',
          arg(4),
        ),
        'access' => user_access('administer store'),
        'type' => MENU_CALLBACK,
      );
      $items[] = array(
        'path' => 'admin/store/settings/countries/' . arg(4) . '/update/' . arg(6),
        'title' => t('Update a country'),
        'description' => t('Update an installed country.'),
        'callback' => 'uc_country_update',
        'callback arguments' => array(
          arg(4),
          arg(6),
        ),
        'access' => user_access('administer store'),
        'type' => MENU_CALLBACK,
      );
    }
  }
  return $items;
}

/**
 * Implementation of hook_init().
 */
function uc_store_init() {

  // Add base_path to the Drupal object for use in Ubercart .js files.
  // uc_add_js(array('base_path' => base_path()), 'setting');
}

/**
 * Implementation of hook_token_values(). (token.module)
 */
function uc_store_token_values($type, $object = NULL) {
  global $base_url;
  switch ($type) {
    case 'global':
      $login_link = url('user', NULL, NULL, TRUE);
      $values['site-login'] = l($login_link, $login_link);
      $theme_key = variable_get('theme_default', 'garland');
      $settings = theme_get_settings($theme_key);
      $themes = list_themes();
      $theme_object = $themes[$theme_key];
      if ($settings['toggle_logo']) {
        if ($settings['default_logo']) {
          $settings['logo'] = dirname($theme_object->filename) . '/logo.png';
        }
        elseif ($settings['logo_path']) {
          $settings['logo'] = $settings['logo_path'];
        }
      }
      $values['site-logo'] = '<img src="' . url($base_url . '/' . $settings['logo'], NULL, NULL, TRUE) . '" />';
      $values['store-name'] = variable_get('uc_store_name', t('Our store'));
      $values['store-url'] = variable_get('uc_store_url', $base_url);
      $values['store-link'] = l(variable_get('uc_store_name', t('Our store')), variable_get('uc_store_url', $base_url));
      $values['store-owner'] = variable_get('uc_store_owner', '');
      $values['store-email'] = variable_get('uc_store_email', '');
      $values['store-phone'] = variable_get('uc_store_phone', '');
      $values['store-address'] = uc_store_address();
      $values['store-help-url'] = url(variable_get('uc_notify_store_help_page', ''), NULL, NULL, TRUE);
      break;
  }
  return $values;
}

/**
 * Implementation of hook_token_list(). (token.module)
 */
function uc_store_token_list($type = 'all') {
  $tokens['global']['site-login'] = t('A link to the site login page.');
  $tokens['global']['site-logo'] = t('The URL for the site logo.');
  $tokens['global']['store-name'] = t('The Ubercart store name.');
  $tokens['global']['store-url'] = t('The Ubercart store URL.');
  $tokens['global']['store-link'] = t('A link to the Ubercart store using the store name.');
  $tokens['global']['store-owner'] = t('The Ubercart store owner.');
  $tokens['global']['store-email'] = t('The Ubercart store e-mail address.');
  $tokens['global']['store-phone'] = t('The Ubercart store phone number.');
  $tokens['global']['store-address'] = t('The Ubercart store mailing address.');
  $tokens['global']['store-help-url'] = t('The URL to the store help page.');
  return $tokens;
}
function uc_store_help($section) {
  switch ($section) {
    case 'admin/store/settings/store/edit/report':
      return t("Reporting to Ubercart.org happens once a week during a normal cron run and is logged in your site's watchdog. Reporting lets Ubercart.org calculate the total number of Ubercart installations and aggregate version information for use in development. Your site's data is never shared with anyone, and aggregate statistics displayed through Ubercart.org will be in the form of anonymous group statistics. Reporting will also allow Ubercart.org to report security notices back to your site if needed.");
  }
}

/**
 * Implementation of hook_cron().
 */
function uc_store_cron() {

  // Report version information into Ubercart.org once a week if enabled.
  if (variable_get('uc_store_report', TRUE) && variable_get('uc_store_last_report', 0) <= time() - 604800) {
    uc_store_send_report();
  }
}

/**
 * Implementation of hook_block().
 */
function uc_store_block($op = 'list', $delta = 0, $edit = array()) {
  if ($op == 'list') {
    $blocks[0]['info'] = t('Store links');
    return $blocks;
  }
  else {
    if ($op == 'view') {
      switch ($delta) {
        case 0:
          if (!user_access('administer store')) {
            break;
          }
          uc_add_js(drupal_get_path('module', 'uc_store') . '/uc_store.js');
          $menu = menu_get_item(null, 'admin/store');
          $output = '<ul id="store-links">' . "\n";
          $output .= theme('uc_store_block_links', $menu);
          $output .= "</ul>\n";
          $block['subject'] = t('Store links');
          $block['content'] = $output . '<br class="clear" /><br />';
          break;
      }
      return $block;
    }
  }
}

/**
 * Implementation of hook_perm().
 */
function uc_store_perm() {
  return array(
    'administer store',
    'view customers',
    'view store reports',
  );
}

/**
 * Implementation of hook_footer().
 */
function uc_store_footer() {

  // Exit if the store footer is turned off.
  if (variable_get('uc_footer_message', 0) === 'none') {
    return;
  }

  // Figure out what page is being viewed.
  $path = drupal_get_normal_path($_GET['q']);
  $parts = explode('/', $path);
  switch ($parts[0]) {
    case 'admin':
      if ($parts[1] != 'store') {
        break;
      }
    case 'node':
      if (intval($parts[1]) > 0) {
        if ($node = node_load($parts[1])) {
          if (function_exists('uc_product_node_info') && !in_array($node->type, module_invoke_all('product_types'))) {
            break;
          }
        }
      }
    case 'catalog':
    case 'cart':
    case 'manufacturer':
      $messages = _store_footer_options();
      if (($message = variable_get('uc_footer_message', 0)) > 0) {
        $message = $messages[$message];
      }
      else {
        $message = db_result(db_query("SELECT message FROM {uc_store_footers} WHERE path_hash = '%s'", md5($path)));
        if (!$message) {
          unset($messages['none']);
          $message = $messages[array_rand($messages)];
          db_query("INSERT INTO {uc_store_footers} (path_hash, message) VALUES ('%s', '%s')", md5($path), $message);
        }
      }
      return theme('uc_store_footer', $message);
  }
}

/**
 * Implementation of hook_exit().
 */
function uc_store_exit() {

  // Save the current request for tracking paths on subsequent page requests.
  // When HTTP_REFERER is set, the session version is not; and vice versa.
  if (referer_uri() == '') {
    $protocol = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? 'https' : 'http';
    $_SESSION['uc_referer_uri'] = $protocol . '://' . $_SERVER['SERVER_NAME'] . $GLOBALS['base_path'] . $_GET['q'];
  }
  else {
    if (isset($_SESSION['uc_referer_uri'])) {
      unset($_SESSION['uc_referer_uri']);
    }
  }

  // Save the timestamp of the last access.
  // $_SESSION['uc_last_access'] = time();
}

/******************************************************************************
 * Callback Functions, Forms, and Tables
 ******************************************************************************/
function uc_store_admin() {
  $main_menu = menu_get_item(NULL, 'admin/store');
  usort($main_menu['children'], '_menu_sort');
  if (($type = variable_get('uc_store_admin_page_display', 1)) == 4) {
    $main_menu = menu_get_item(NULL, 'admin/store');
    $content = system_admin_menu_block($main_menu);
    $output = theme('admin_block_content', $content);
  }
  else {
    foreach ($main_menu['children'] as $mid) {
      if ($mid > 0) {
        $menus[] = menu_get_item($mid);
      }
    }
    $output = theme('uc_admin_dashboard', $type, $menus);
  }
  $results = module_invoke_all('store_status');
  foreach ($results as $message) {
    switch ($message['status']) {
      case 'warning':
        $icon = base_path() . drupal_get_path('module', 'uc_store') . '/images/alert.gif';
        break;
      case 'error':
        $icon = base_path() . drupal_get_path('module', 'uc_store') . '/images/error.gif';
        break;
      case 'ok':
      default:
        $icon = base_path() . drupal_get_path('module', 'uc_store') . '/images/info.gif';
    }
    $rows[] = array(
      'data' => array(
        array(
          'data' => '<img src="' . $icon . '" />',
        ),
        array(
          'data' => '<strong>' . $message['title'] . '</strong>',
          'nowrap' => 'nowrap',
        ),
        array(
          'data' => $message['desc'],
          'width' => '100%',
        ),
      ),
      'valign' => 'top',
    );
  }
  $header = array(
    '&nbsp;',
    t('Title'),
    t('Description'),
  );
  $output .= '<div style="clear: both;"><h2>' . t('Status messages:') . '</h2>' . theme('table', $header, $rows) . '</div>';
  return $output;
}

// Themes the dashboard on the admin/store page.
function theme_uc_admin_dashboard($type, $menus) {
  if ($type == 1) {
    uc_add_js(drupal_get_path('module', 'uc_store') . '/uc_store.js', 'module');
    uc_add_js("var text_show = '" . t('- Show links -') . "';\nvar text_hide = '" . t('- Hide links -') . "';\n", 'inline');
  }
  $output = '<table class="uc-store-admin-table" align="center"><tr valign="top">';
  $panels = 0;
  if (is_array($menus)) {
    foreach ($menus as $menu) {
      $panel++;
      if ($panel % 4 == 0) {
        $output .= '</tr><tr valign="top">';
      }
      $panel_title = $menu['title'];
      if ($type == 3) {
        $panel_links = '';
      }
      else {
        $panel_links = theme('admin_block_content', system_admin_menu_block($menu));
      }
      $panel_table = '<table width="100%"><tr>' . '<td>' . l(uc_store_get_icon($menu['path']), $menu['path'], array(), NULL, NULL, FALSE, TRUE) . '</td>' . '<td class="panel-title">' . l($menu['title'], $menu['path']) . '</td></tr>';
      if (strlen($panel_links) > 0) {
        if ($type == 1) {
          $disp = 'display: none;';
        }
        $panel_table .= '<tr><td nowrap colspan="2" class="panel-links" ' . 'style="' . $disp . '">' . $panel_links . '</td></tr>';
        if ($type == 1) {
          $panel_table .= '<tr><td align="center" colspan="2" ' . 'class="panel-show-link" id="show-links-' . $panel . '"><a>' . t('- Show links -') . '</a></td></tr>';
        }
      }
      $panel_table .= '</table>';
      $output .= '<td class="uc-store-admin-panel" id="panel-' . $panel . '">' . $panel_table . '</td>';
    }
  }
  $output .= '</tr></table>';
  return $output;
}

/**
 * Display customer administration page.
 */
function uc_store_customers($message = NULL, $query = NULL, $count_query = NULL, $page_length = 25) {
  if (!module_exists('uc_order')) {
    return t('You must enable the order module to track customers.');
  }
  if (is_null($query)) {
    $query = "SELECT DISTINCT o.uid, u.mail, o.billing_first_name, " . "o.billing_last_name, o.billing_city, o.billing_zone, " . "o.billing_country FROM {uc_orders} AS o LEFT JOIN " . "{users} AS u ON o.uid = u.uid WHERE o.uid > 0 AND " . "o.order_status IN " . uc_order_status_list('general', TRUE);
    $count_query = "";
    switch ($GLOBALS['db_type']) {
      case 'mysql':
      case 'mysqli':
        $count_query = "SELECT COUNT(DISTINCT o.uid, o.billing_first_name, " . "o.billing_last_name, u.mail) FROM {uc_orders} AS o " . "LEFT JOIN {users} AS u ON o.uid = u.uid WHERE o.uid > 0 " . "AND o.order_status IN " . uc_order_status_list('general', TRUE);
        break;
      case 'pgsql':
        $count_query = "SELECT DISTINCT o.uid, o.billing_last_name, o.billing_first_name, " . "COUNT(*) " . "FROM {uc_orders} AS o " . "LEFT JOIN {users} AS u ON o.uid = u.uid WHERE o.uid > 0 " . "AND o.order_status IN " . uc_order_status_list('general', TRUE) . " GROUP BY o.uid, o.billing_last_name, o.billing_first_name ";
        break;
    }
    $message = t('The following users on your site have placed orders:');
  }
  $header = array(
    t('View'),
    array(
      'data' => t('Name'),
      'field' => 'o.billing_last_name',
      'sort' => 'asc',
    ),
    array(
      'data' => t('E-mail'),
      'field' => 'u.mail',
    ),
    array(
      'data' => t('City'),
      'field' => 'o.billing_city',
    ),
    array(
      'data' => t('ID'),
      'field' => 'o.uid',
    ),
  );
  $query .= tablesort_sql($header);
  $count_query .= tablesort_sql($header);
  $address = variable_get('uc_customer_list_address', 'billing');
  if ($address == 'shipping') {
    $query = str_replace('billing', 'delivery', $query);
    $count_query = str_replace('billing', 'delivery', $count_query);
  }
  else {
    $address = 'billing';
  }
  $result = pager_query($query, $page_length, 0, $count_query);
  while ($customer = db_fetch_object($result)) {
    $icons = l(uc_store_get_icon('admin/store/customers', TRUE), 'user/' . $customer->uid, array(
      'title' => t('View user details.'),
    ), NULL, NULL, FALSE, TRUE) . l(uc_store_get_icon('admin/store/orders', TRUE), 'admin/store/customers/orders/' . $customer->uid, array(
      'title' => t("View customer's order."),
    ), NULL, NULL, FALSE, TRUE);
    if ($address == 'shipping') {
      $name = ucfirst($customer->delivery_last_name) . ', ' . ucfirst($customer->delivery_first_name);
      $city = ucfirst($customer->delivery_city) . ', ' . uc_get_zone_code($customer->delivery_zone);
    }
    else {
      $name = ucfirst($customer->billing_last_name) . ', ' . ucfirst($customer->billing_first_name);
      $city = ucfirst($customer->billing_city) . ', ' . uc_get_zone_code($customer->billing_zone);
    }
    if ($name == ', ') {
      $name = db_result(db_query("SELECT name FROM {users} WHERE uid = %d", $customer->uid));
      $name = t('User: !name', array(
        '!name' => $name,
      ));
    }
    $rows[] = array(
      'data' => array(
        array(
          'data' => $icons,
        ),
        array(
          'data' => check_plain($name),
        ),
        array(
          'data' => check_plain($customer->mail),
        ),
        array(
          'data' => check_plain($city),
        ),
        array(
          'data' => $customer->uid,
        ),
      ),
      'id' => 'customer-' . $customer->uid,
    );
  }
  uc_add_js(drupal_get_path('module', 'uc_store') . '/uc_store.js');
  $output = '<p>' . $message . '</p>' . theme('table', $header, $rows, array(
    'width' => '100%',
    'class' => 'uc-customer-table',
  )) . '<br />' . theme_pager(NULL, $page_length);
  return $output;
}
function uc_store_customer_orders($uid) {
  $result = pager_query("SELECT * FROM {uc_orders} WHERE uid = %d AND " . "order_status IN " . uc_order_status_list('general', TRUE) . " ORDER BY created DESC", 50, 0, NULL, $uid);
  $header = array(
    t('View'),
    t('Order ID'),
    t('Date'),
    t('Billing name'),
    t('Shipping name'),
    t('Items'),
    t('Total'),
  );
  if (db_num_rows($result) == 0) {
    $rows[] = array(
      array(
        'data' => t('No orders found.'),
        'colspan' => 7,
      ),
    );
  }
  else {
    $totals = array(
      'orders' => 0,
      'items' => 0,
      'total' => 0,
    );
    while ($order = db_fetch_object($result)) {
      $icons = l(uc_store_get_icon('file:order_view'), 'admin/store/orders/' . $order->order_id, array(
        'title' => t("View order !order_id.", array(
          '!order_id' => $order->order_id,
        )),
      ), NULL, NULL, FALSE, TRUE) . l(uc_store_get_icon('file:order_edit'), 'admin/store/orders/' . $order->order_id . '/edit', array(
        'title' => t("Edit order !order_id.", array(
          '!order_id' => $order->order_id,
        )),
      ), NULL, NULL, FALSE, TRUE);
      $bname = ucfirst($order->billing_first_name) . ' ' . ucfirst($order->billing_last_name);
      $sname = ucfirst($order->delivery_first_name) . ' ' . ucfirst($order->delivery_last_name);
      $result2 = db_query("SELECT COUNT(*) FROM {uc_order_products} WHERE " . "order_id = %d", $order->order_id);
      $item_count = db_fetch_array($result2);
      $totals['orders'] += 1;
      $totals['items'] += $item_count['COUNT(*)'];
      $totals['total'] += $order->order_total;
      $rows[] = array(
        'data' => array(
          array(
            'data' => $icons,
          ),
          array(
            'data' => $order->order_id,
          ),
          array(
            'data' => format_date($order->created, 'custom', variable_get('uc_date_format_default', 'm/d/Y')),
          ),
          array(
            'data' => check_plain($bname),
          ),
          array(
            'data' => check_plain($sname),
          ),
          array(
            'data' => $item_count['COUNT(*)'],
          ),
          array(
            'data' => uc_currency_format($order->order_total),
            'nowrap' => 'nowrap',
          ),
        ),
        'id' => 'order-' . $order->order_id,
      );
    }
  }
  uc_add_js(drupal_get_path('module', 'uc_store') . '/uc_store.js');
  $output = '<p>' . l(t('Create an order for this customer.'), 'admin/store/orders/create/' . $uid) . '</p>';
  $output .= '<p>' . t('!totals_orders orders shown match that account with !totals_items items purchased and !totals_total spent:', array(
    '!totals_orders' => $totals['orders'],
    '!totals_items' => $totals['items'],
    '!totals_total' => uc_currency_format($totals['total']),
  )) . '</p>' . theme('table', $header, $rows, array(
    'width' => '100%',
    'class' => 'uc-cust-orders-table',
  )) . '<br />' . theme_pager(NULL, 50);
  return $output;
}

/**
 * Display the customer search page.
 */
function uc_store_customer_search() {
  $output = drupal_get_form('uc_store_customer_search_form');
  if (arg(4) == 'results') {
    $first_name = strtolower(str_replace('*', '%', check_plain(arg(5))));
    $last_name = strtolower(str_replace('*', '%', check_plain(arg(6))));
    $email = strtolower(str_replace('*', '%', check_plain(arg(7))));
    if ($first_name !== '0' && $first_name !== '%') {
      $where .= " AND LOWER(o.billing_first_name) LIKE '" . $first_name . "'";
    }
    if ($last_name !== '0' && $last_name !== '%') {
      $where .= " AND LOWER(o.billing_last_name) LIKE '" . $last_name . "'";
    }
    if ($email !== '0' && $email !== '%') {
      $where .= " AND LOWER(o.primary_email) LIKE '" . $email . "'";
    }
    $query = "SELECT DISTINCT o.uid, u.mail, o.billing_first_name," . "o.billing_last_name, o.billing_city, o.billing_zone, " . "o.billing_country FROM {uc_orders} AS o LEFT JOIN " . "{users} AS u ON o.uid = u.uid WHERE o.uid > 0 AND " . "o.order_status IN " . uc_order_status_list('general', TRUE) . $where;

    // ." ORDER BY o.billing_last_name ASC";
    $count_query = '';
    switch ($GLOBALS['db_type']) {
      case 'mysql':
      case 'mysqli':
        $count_query = "SELECT COUNT(DISTINCT o.uid, o.billing_first_name, " . "o.billing_last_name, u.mail) FROM {uc_orders} AS o " . "LEFT JOIN {users} AS u ON o.uid = u.uid WHERE o.uid > 0 AND " . "o.order_status IN " . uc_order_status_list('general', TRUE) . $where;

        // ." ORDER BY o.billing_last_name ASC";
        break;
      case 'pgsql':
        $count_query = "SELECT DISTINCT o.uid, o.billing_first_name, " . "o.billing_last_name, u.mail, COUNT(*) " . "FROM {uc_orders} AS o " . "LEFT JOIN {users} AS u ON o.uid = u.uid WHERE o.uid > 0 AND " . "o.order_status IN " . uc_order_status_list('general', TRUE) . $where . "GROUP BY o.uid, o.billing_first_name, o.billing_last_name, u.mail ";

        //."ORDER BY o.billing_last_name ASC";
        break;
    }
    $message = t('Search returned the following results:');
    $output .= uc_store_customers($message, $query, $count_query, 100);
  }
  return $output;
}
function uc_store_customer_search_form() {
  $form['search'] = array(
    '#type' => 'fieldset',
    '#title' => t('Search options'),
    '#collapsible' => TRUE,
    '#collapsed' => arg(4) == 'results' ? TRUE : FALSE,
  );
  $form['search']['table1'] = array(
    '#value' => '<table><tbody style="border: 0px;"><tr><td colspan="4">',
  );
  $form['search']['desc'] = array(
    '#value' => '<div>' . t("Search for customers based on any of the following fields.  Use * as a wildcard to match any character.<br />For example, searching by last name for 's*' will return all customers whose last name starts with an s.<br />(<em>Leave a field empty to ignore it in the search.</em>)") . '</div>',
  );
  $form['search']['table2'] = array(
    '#value' => '</td></tr><tr><td>',
  );
  $form['search']['first_name'] = array(
    '#type' => 'textfield',
    '#title' => t('First name'),
    '#default_value' => arg(5) != '0' ? arg(5) : '',
    '#size' => 24,
    '#maxlength' => 32,
  );
  $form['search']['table3'] = array(
    '#value' => '</td><td>',
  );
  $form['search']['last_name'] = array(
    '#type' => 'textfield',
    '#title' => t('Last name'),
    '#default_value' => arg(6) != '0' ? arg(6) : '',
    '#size' => 24,
    '#maxlength' => 32,
  );
  $form['search']['table4'] = array(
    '#value' => '</td><td>',
  );
  $form['search']['email'] = array(
    '#type' => 'textfield',
    '#title' => t('E-mail'),
    '#default_value' => arg(7) != '0' ? arg(7) : '',
    '#size' => 24,
    '#maxlength' => 96,
  );
  $form['search']['table5'] = array(
    '#value' => '</td><td>',
  );
  $form['search']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Search'),
  );
  $form['search']['table6'] = array(
    '#value' => '</td></tr></tbody></table>',
  );
  return $form;
}
function uc_store_customer_search_form_submit($form_id, $form_values) {
  if (strlen(trim($form_values['first_name'])) == 0) {
    $first_name = '0';
  }
  else {
    $first_name = strtolower(trim($form_values['first_name']));
  }
  if (strlen(trim($form_values['last_name'])) == 0) {
    $last_name = '0';
  }
  else {
    $last_name = strtolower(trim($form_values['last_name']));
  }
  if (strlen(trim($form_values['email'])) == 0) {
    $email = '0';
  }
  else {
    $email = strtolower(trim($form_values['email']));
  }
  drupal_goto('admin/store/customers/search/results/' . $first_name . '/' . $last_name . '/' . $email);
}

/**
 * Display main reports page.
 */
function uc_store_reports() {
  $menu = menu_get_item(NULL, 'admin/store/reports');
  $content = system_admin_menu_block($menu);
  $message = module_exists('uc_reports') ? t('Various reports generated by Ubercart modules can be found here. Click the links below to view the reports.') : t('Various reports generated by Ubercart modules can be found here. Click the links below to view the reports. To view core Ubercart statistics enable the <strong>Reports</strong> module on the <a href="!url">module administration page</a>', array(
    '!url' => url('admin/build/modules'),
  ));
  $output = $message . theme('admin_block_content', $content);
  return $output;
}

/**
 * Display store configuration page.
 */
function uc_store_configuration_page() {
  $menu = menu_get_item(NULL, 'admin/store/settings');
  $content = system_admin_menu_block($menu);
  $output = theme('admin_block_content', $content);
  return $output;
}

/**
 * Display store help page.
 */
function uc_store_ubercart_help() {
  $output = '<p>' . t('Use the following links to find documentation and support:') . '</p>';
  $items[] = l(t("Ubercart User's Guide"), 'http://www.ubercart.org/docs/user');
  $items[] = l(t('Support Forums'), 'http://www.ubercart.org/forum');
  $items[] = l(t('Drupal Handbook'), 'http://drupal.org/node/258');
  $output .= theme_item_list($items);
  return $output;
}

/**
 * Display the tokens help page.
 */
function uc_store_ubercart_help_tokens() {
  $output = '<p>' . t('Tokens are bracketed phrases you can use in certain text fields and boxes as placeholders for some other text. Tokens represent things like store variables, links to certain pages, order information, etc.  Tokens are used by including the token listed below in a text field that uses them.  The description for the textfields will alert you to which groups of tokens listed below may be used.') . '</p>';
  $output .= theme('token_help', 'ubercart');
  return $output;
}

/**
 * Display the country settings overview.
 */
function uc_country_settings_overview() {
  $result = db_query("SELECT * FROM {uc_countries} ORDER BY country_name ASC");
  while ($country = db_fetch_object($result)) {
    $items[] = t('!country version !version is !status.', array(
      '!country' => $country->country_name,
      '!version' => abs($country->version),
      '!status' => $country->version > 0 ? t('enabled') : t('disabled'),
    ));
  }
  $sections[] = array(
    'edit' => 'admin/store/settings/countries/edit',
    'title' => t('Imported countries'),
    'items' => $items,
  );
  $sections[] = array(
    'edit' => 'admin/store/settings/countries/edit/formats',
    'title' => t('Country specific formats'),
    'items' => array(
      t('Tweak the address formatting for a specific country.'),
    ),
  );
  $output = theme('uc_settings_overview', $sections);
  return $output;
}
function uc_country_import_form() {
  $result = db_query("SELECT * FROM {uc_countries} ORDER BY country_name ASC");
  while ($country = db_fetch_object($result)) {
    $countries[] = $country;
  }
  $files = _country_import_list();
  $header = array(
    t('Country'),
    t('Code'),
    t('Version'),
    t('Operations'),
  );
  if (is_array($countries)) {
    foreach ($countries as $country) {
      $row = array(
        $country->country_name,
        $country->country_iso_code_3,
        array(
          'data' => abs($country->version),
          'align' => 'center',
        ),
      );
      $ops = array();
      if ($country->version < 0) {
        $ops[] = l(t('enable'), 'admin/store/settings/countries/' . $country->country_id . '/enable');
      }
      else {
        $ops[] = l(t('disable'), 'admin/store/settings/countries/' . $country->country_id . '/disable');
      }
      if ($country->version < $files[$country->country_id]['version'] && $country->version > 0) {
        $ops[] = l(t('update'), 'admin/store/settings/countries/' . $country->country_id . '/update/' . $files[$country->country_id]['version']);
      }
      $ops[] = l(t('remove'), 'admin/store/settings/countries/' . $country->country_id . '/remove');
      $row[] = implode(' ', $ops);
      $rows[] = $row;
      unset($files[$country->country_id]);
    }
  }
  foreach ($files as $file) {
    $import_list[$file['file']] = $file['file'];
  }
  if (is_array($import_list)) {
    ksort($import_list);
  }
  $form['text'] = array(
    '#value' => t('To import new country data, select it in the list and click the import button. If you are using a custom or contributed import file, it must be placed in the Ubercart folder uc_store/countries.'),
  );
  if (is_array($import_list)) {
    $options = $import_list;
  }
  else {
    $options = array(
      t('-None available-'),
    );
  }
  $form['import_file'] = array(
    '#type' => 'select',
    '#title' => t('Country'),
    '#options' => $options,
    '#disabled' => !is_array($import_list),
    '#multiple' => is_array($import_list),
    '#size' => min(10, count($options)),
  );
  $form['import_button'] = array(
    '#type' => 'submit',
    '#value' => t('Import'),
    '#disabled' => !is_array($import_list),
  );
  $form['country_table'] = array(
    '#value' => theme('table', $header, $rows),
  );
  return $form;
}
function uc_country_import_form_submit($form_id, $form_values) {
  $files = $form_values['import_file'];
  foreach ($files as $file) {
    $pieces = explode('_', substr($file, 0, strlen($file) - 4));
    $country_id = $pieces[count($pieces) - 2];
    $version = $pieces[count($pieces) - 1];
    $country = substr($file, 0, strlen($file) - strlen($country_id) - strlen($version) - 6);
    require_once drupal_get_path('module', 'uc_store') . '/countries/' . $file;
    $func = $country . '_install';
    if (function_exists($func)) {
      $func();
      drupal_set_message(t('Country file @file imported.', array(
        '@file' => $file,
      )));
    }
    else {
      drupal_set_message(t('Country file @file had no install function.', array(
        '@file' => $file,
      )), 'error');
    }
  }
}

/**
 * Disable a country so it remains installed but is no longer selectable.
 */
function uc_country_disable($country_id) {
  $result = db_query("SELECT * FROM {uc_countries} WHERE country_id = %d", $country_id);
  if ($country = db_fetch_object($result)) {
    if ($country->version > 0) {
      db_query("UPDATE {uc_countries} SET version = %d WHERE country_id = %d", 0 - $country->version, $country_id);
      drupal_set_message(t('!country disabled.', array(
        '!country' => $country->country_name,
      )));
    }
    else {
      drupal_set_message(t('!country is already disabled.', array(
        '!country' => $country->country_name,
      )), 'error');
    }
  }
  else {
    drupal_set_message(t('Attempted to disable an invalid country.'), 'error');
  }
  drupal_goto('admin/store/settings/countries/edit');
}

/**
 * Enable a disabled country.
 */
function uc_country_enable($country_id) {
  $result = db_query("SELECT * FROM {uc_countries} WHERE country_id = %d", $country_id);
  if ($country = db_fetch_object($result)) {
    if ($country->version < 0) {
      db_query("UPDATE {uc_countries} SET version = %d WHERE country_id = %d", abs($country->version), $country_id);
      drupal_set_message(t('@country enabled.', array(
        '@country' => $country->country_name,
      )));
    }
    else {
      drupal_set_message(t('@country is already enabled.', array(
        '@country' => $country->country_name,
      )), 'error');
    }
  }
  else {
    drupal_set_message(t('Attempted to enable an invalid country.'), 'error');
  }
  drupal_goto('admin/store/settings/countries/edit');
}

// Form to completely remove a country.
function uc_country_remove_form($country_id) {

  // Fetch the country name from the database.
  $country = db_result(db_query("SELECT country_name FROM {uc_countries} WHERE country_id = %d", $country_id));

  // If orders exist for this country, show a warning message prior to removal.
  if ($_POST['op'] != t('Remove') && module_exists('uc_order')) {
    $count = db_result(db_query("SELECT COUNT(order_id) FROM {uc_orders} WHERE delivery_country = %d OR billing_country = %d", $country_id, $country_id));
    if ($count > 0) {
      drupal_set_message(t('Warning: @count orders were found with addresses in @country. Removing it now will cause errors to show on those order pages. You might consider simply disabling @country instead.', array(
        '@count' => $count,
        '@country' => $country,
      )), 'error');
    }
  }

  // Store the country ID in the form array for processing.
  $form['country_id'] = array(
    '#type' => 'value',
    '#value' => $country_id,
  );
  return confirm_form($form, t('Are you sure you want to remove @country from the system?', array(
    '@country' => $country,
  )), 'admin/store/settings/countries/edit', NULL, t('Remove'));
}
function uc_country_remove_form_submit($form_id, $form_values) {
  $country_id = $form_values['country_id'];
  $result = db_query("SELECT * FROM {uc_countries} WHERE country_id = %d", $country_id);
  if (!($country = db_fetch_object($result))) {
    drupal_set_message(t('Attempted to remove an invalid country.'), 'error');
    drupal_goto('admin/store/settings/countries');
  }
  db_query("DELETE FROM {uc_countries} WHERE country_id = %d", $country_id);
  db_query("DELETE FROM {uc_zones} WHERE zone_country_id = %d", $country_id);
  variable_del('uc_address_format_' . $country_id);
  $func_base = _country_import_include($country_id, $country->version);
  if ($func_base !== FALSE) {
    $func = $func_base . '_uninstall';
    if (function_exists($func)) {
      $func();
    }
  }
  drupal_set_message(t('!country removed.', array(
    '!country' => $country->country_name,
  )));
  drupal_goto('admin/store/settings/countries/edit');
}

/**
 * Update a country to its latest version.
 */
function uc_country_update($country_id, $version) {
  $result = db_query("SELECT * FROM {uc_countries} WHERE country_id = %d", $country_id);
  if (!($country = db_fetch_object($result))) {
    drupal_set_message(t('Attempted to update an invalid country.'));
    drupal_goto('admin/store/settings/countries');
  }
  if ($version < $country->version) {
    drupal_set_message(t('You cannot update to a previous version.'));
    drupal_goto('admin/store/settings/countries');
  }
  $func_base = _country_import_include($country_id, $version);
  if ($func_base !== FALSE) {
    $func = $func_base . '_update';
    if (function_exists($func)) {
      for ($i = $country->version; $i <= $version; $i++) {
        $func($i);
      }
    }
    db_query("UPDATE {uc_countries} SET version = %d WHERE country_id = %d", $version, $country_id);
    drupal_set_message(t('Country update complete.'));
  }
  else {
    drupal_set_message(t('Attempted to update an invalid country.'));
  }
  drupal_goto('admin/store/settings/countries');
}
function uc_country_formats_form() {
  $form['instructions'] = array(
    '#type' => 'fieldset',
    '#title' => t('Address variables instructions'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $header = array(
    t('Variable'),
    t('Description'),
  );
  $rows = array(
    array(
      '!first_name',
      t("Customer's first name"),
    ),
    array(
      '!last_name',
      t("Customer's last name"),
    ),
    array(
      '!company',
      t('Company name'),
    ),
    array(
      '!street1',
      t('First street address field'),
    ),
    array(
      '!street2',
      t('Second street address field'),
    ),
    array(
      '!city',
      t('City name'),
    ),
    array(
      '!zone_name',
      t('Full name of the zone'),
    ),
    array(
      '!zone_code',
      t('Abbreviation of the zone'),
    ),
    array(
      '!postal_code',
      t('Postal code'),
    ),
    array(
      '!country_name',
      t('Name of the country'),
    ),
    array(
      '!country_code2',
      t('2 digit country abbreviation'),
    ),
    array(
      '!country_code3',
      t('3 digit country abbreviation'),
    ),
  );
  $form['instructions']['text'] = array(
    '#value' => '<div>' . t('The following variables should be used in configuring addresses for the countries you ship to:') . '<p>' . theme('table', $header, $rows) . '</p><p>' . t('*Adding _if to any country variable will make it only display for addresses<br />whose country is different than the default store country.') . '</div>',
  );
  $result = db_query("SELECT * FROM {uc_countries} ORDER BY country_name ASC");
  while ($country = db_fetch_object($result)) {
    $countries[] = $country;
  }
  if (is_array($countries)) {
    $form['countries'] = array(
      '#tree' => TRUE,
    );
    foreach ($countries as $country) {
      $form['countries'][$country->country_id] = array(
        '#type' => 'fieldset',
        '#title' => $country->country_name,
        '#collapsible' => TRUE,
        '#collapsed' => TRUE,
      );
      $form['countries'][$country->country_id]['address_format'] = array(
        '#type' => 'textarea',
        '#title' => t('Address format'),
        '#default_value' => variable_get('uc_address_format_' . $country->country_id, ''),
        '#description' => t('Uses the variables mentioned in the instructions to format an address for this country.'),
        '#rows' => 6,
      );
    }
  }
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit changes'),
  );
  return $form;
}
function uc_country_formats_form_submit($form_id, $form_values) {
  foreach ($form_values['countries'] as $country_id => $data) {
    variable_set('uc_address_format_' . $country_id, $data['address_format']);
  }
  drupal_set_message(t('Country settings saved.'));
}

/**
 * Display the store settings overview page.
 */
function uc_store_store_settings_overview() {
  $name = variable_get('uc_store_name', NULL);
  $owner = variable_get('uc_store_owner', NULL);
  $email = variable_get('uc_store_email', NULL);
  $phone = variable_get('uc_store_phone', NULL);
  $fax = variable_get('uc_store_fax', NULL);
  $sections[] = array(
    'edit' => 'admin/store/settings/store/edit',
    'title' => t('Name and contact information'),
    'items' => array(
      t('Store name is %name.', array(
        '%name' => !empty($name) ? $name : t('not set'),
      )),
      t('Store owner is %owner.', array(
        '%owner' => !empty($owner) ? $owner : t('not set'),
      )),
      t('Store e-mail is %email.', array(
        '%email' => !empty($email) ? $email : t('not set'),
      )),
      t('Store phone number is !phone.', array(
        '!phone' => !empty($phone) ? $phone : t('not set'),
      )),
      t('Store fax number is !fax.', array(
        '!fax' => !empty($fax) ? $fax : t('not set'),
      )),
      t('Store address is:<p>!address', array(
        '!address' => uc_store_address(),
      )),
    ),
  );
  switch (variable_get('uc_store_admin_page_display', 1)) {
    case 1:
      $type = t('Dashboard with collapsed submenu links');
      break;
    case 2:
      $type = t('Dashboard with expanded submenu links');
      break;
    case 3:
      $type = t('Dashboard with no submenu links');
      break;
    case 4:
      $type = t('Normal Drupal submenu listing');
      break;
  }
  $sections[] = array(
    'edit' => 'admin/store/settings/store/edit/display',
    'title' => t('Display settings'),
    'items' => array(
      t('Store admin page display type:<br />!type', array(
        '!type' => $type,
      )),
      t('Customer !type address used in lists.', array(
        '!type' => variable_get('uc_customer_list_address', 'billing') == 'billing' ? t('billing') : t('shipping'),
      )),
      t('Footer using !type message.', array(
        '!type' => variable_get('uc_footer_message', 0) == 0 ? t('random') : t('specified'),
      )),
    ),
  );
  $sections[] = array(
    'edit' => 'admin/store/settings/store/edit/format',
    'title' => t('Format settings'),
    'items' => array(
      t('Default currency: !code', array(
        '!code' => variable_get('uc_currency_code', 'USD'),
      )),
      t('Currency format: !value', array(
        '!value' => uc_currency_format(1234.56),
      )),
      t('Weight format: !value', array(
        '!value' => uc_weight_format(36),
      )),
      t('Date format: !value', array(
        '!value' => uc_date_format(8, 18, 2007),
      )),
    ),
  );
  $items = array();
  if (variable_get('uc_store_report', TRUE)) {
    $items[] = t('Version information is being reported to Ubercart.org.');
  }
  else {
    $items[] = t('Your site is not reporting to Ubercart.org.');
  }
  $sections[] = array(
    'edit' => 'admin/store/settings/store/edit/report',
    'title' => t('Reporting settings'),
    'items' => $items,
  );
  $output = theme('uc_settings_overview', $sections);
  return $output;
}

// Displays the form for store settings.
function uc_store_store_settings_form() {
  $form['uc_store_name'] = uc_textfield(t('Store name'), variable_get('uc_store_name', NULL), FALSE, NULL, 64);
  $form['uc_store_owner'] = uc_textfield(t('Store owner'), variable_get('uc_store_owner', NULL), FALSE, NULL, 64);
  $form['uc_store_email'] = uc_textfield(t('E-mail address'), variable_get('uc_store_email', NULL), FALSE, NULL, 128);
  $form['uc_store_email_include_name'] = array(
    '#type' => 'checkbox',
    '#title' => t('Include the store name in the from line of store e-mails.'),
    '#description' => t('May not be available on all server configurations. Turn off if this causes problems.'),
    '#default_value' => variable_get('uc_store_email_include_name', TRUE),
  );
  $form['uc_store_phone'] = uc_textfield(t('Phone number'), variable_get('uc_store_phone', NULL), FALSE);
  $form['uc_store_fax'] = uc_textfield(t('Fax number'), variable_get('uc_store_fax', NULL), FALSE);
  $form['uc_store_street1'] = uc_textfield(uc_get_field_name('street1'), variable_get('uc_store_street1', NULL), FALSE, NULL, 128);
  $form['uc_store_street2'] = uc_textfield(uc_get_field_name('street2'), variable_get('uc_store_street2', NULL), FALSE, NULL, 128);
  $form['uc_store_city'] = uc_textfield(uc_get_field_name('city'), variable_get('uc_store_city', NULL), FALSE);
  $form['uc_store_country'] = uc_country_select(uc_get_field_name('country'), uc_store_default_country());
  if (isset($_POST['uc_store_country'])) {
    $country_id = intval($_POST['uc_store_country']);
  }
  else {
    $country_id = uc_store_default_country();
  }
  $form['uc_store_zone'] = uc_zone_select(uc_get_field_name('zone'), variable_get('uc_store_zone', NULL), NULL, $country_id);
  $form['uc_store_postal_code'] = uc_textfield(uc_get_field_name('postal_code'), variable_get('uc_store_postal_code', NULL), FALSE, NULL, 10);
  return system_settings_form($form);
}
function uc_store_display_settings_form() {
  $form['uc_store_admin_page_display'] = array(
    '#type' => 'radios',
    '#title' => t('Display type for the main store admininstration page'),
    '#description' => t('Some options are better suited for different themes, so feel free to try them all out!'),
    '#options' => array(
      1 => t('Dashboard with collapsed submenu links'),
      2 => t('Dashboard with expanded submenu links'),
      3 => t('Dashboard with no submenu links'),
      4 => t('Normal Drupal submenu listing'),
    ),
    '#default_value' => variable_get('uc_store_admin_page_display', 1),
  );
  $desc = t('Select the address to be used on customer lists and summaries.');
  if (module_exists('uc_notify')) {
    $desc .= ' ' . t('Also applies to notification e-mails.');
  }
  $form['uc_customer_list_address'] = array(
    '#type' => 'radios',
    '#title' => t('Primary customer address'),
    '#description' => $desc,
    '#options' => array(
      'billing' => t('Billing address'),
      'shipping' => t('Shipping address'),
    ),
    '#default_value' => variable_get('uc_customer_list_address', 'billing'),
  );
  $options = array(
    t('Randomly select a message from the list below.'),
  );
  $form['uc_footer_message'] = array(
    '#type' => 'radios',
    '#title' => t('Footer message for store pages'),
    '#options' => array_merge($options, _store_footer_options()),
    '#default_value' => variable_get('uc_footer_message', 0),
  );
  return system_settings_form($form);
}

// Return the default store footer options.
function _store_footer_options() {
  $url = array(
    '!url' => 'http://www.ubercart.org/',
  );
  return array(
    1 => t('<a href="!url">Powered by Ubercart</a>', $url),
    2 => t('<a href="!url">Drupal e-commerce</a> provided by Ubercart.', $url),
    3 => t('Supported by Ubercart, an <a href="!url">open source e-commerce suite</a>.', $url),
    4 => t('Powered by Ubercart, the <a href="!url">free shopping cart software</a>.', $url),
    'none' => t('(Do not display a message in the footer.)'),
  );
}

// Wrap the footer in a div so it can be re-styled.
function theme_uc_store_footer($message) {
  return '<div id="store-footer">' . $message . '</div>';
}
function uc_store_format_settings_form() {
  $form['currency'] = array(
    '#type' => 'fieldset',
    '#title' => t('Currency format'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['currency']['uc_currency_code'] = array(
    '#type' => 'textfield',
    '#title' => t('Default currency'),
    '#description' => t('While not used directly in formatting, the currency code is used by other modules as the primary currency for your site.  Enter here your three character <a href="!url">ISO 4217</a> currency code.', array(
      '!url' => 'http://en.wikipedia.org/wiki/ISO_4217#Active_codes',
    )),
    '#default_value' => variable_get('uc_currency_code', 'USD'),
    '#maxlength' => 3,
    '#size' => 5,
  );
  $form['currency']['example'] = array(
    '#type' => 'textfield',
    '#title' => t('Current format'),
    '#value' => uc_currency_format(1000.1234),
    '#disabled' => TRUE,
    '#size' => 10,
  );
  $form['currency']['uc_currency_sign'] = uc_textfield(t('Currency Sign'), variable_get('uc_currency_sign', '$'), FALSE, NULL, 10, 10);
  $form['currency']['uc_sign_after_amount'] = array(
    '#type' => 'checkbox',
    '#title' => t('Display currency sign after amount.'),
    '#default_value' => variable_get('uc_sign_after_amount', FALSE),
  );
  $form['currency']['uc_currency_thou'] = uc_textfield(t('Thousands Marker'), variable_get('uc_currency_thou', ','), FALSE, NULL, 10, 10);
  $form['currency']['uc_currency_dec'] = uc_textfield(t('Decimal Marker'), variable_get('uc_currency_dec', '.'), FALSE, NULL, 10, 10);
  $form['currency']['uc_currency_prec'] = array(
    '#type' => 'select',
    '#title' => t('Number of decimal places'),
    '#options' => drupal_map_assoc(array(
      0,
      1,
      2,
    )),
    '#default_value' => variable_get('uc_currency_prec', 2),
  );
  $form['weight'] = array(
    '#type' => 'fieldset',
    '#title' => t('Weight format'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['weight']['instructions'] = array(
    '#value' => '<div>' . t('Supply a format string for each unit. !value represents the weight value.') . '</div>',
  );
  $units = array(
    'lb' => t('Pounds'),
    'oz' => t('Ounces'),
    'kg' => t('Kilograms'),
    'g' => t('Grams'),
  );
  $form['weight']['uc_weight_unit'] = array(
    '#type' => 'select',
    '#title' => t('Default unit of measurement'),
    '#default_value' => variable_get('uc_weight_unit', 'lb'),
    '#options' => $units,
  );
  foreach ($units as $unit => $name) {
    $form['weight']['uc_weight_format_' . $unit] = array(
      '#type' => 'textfield',
      '#title' => t('@unit format string', array(
        '@unit' => $name,
      )),
      '#default_value' => variable_get('uc_weight_format_' . $unit, '!value ' . $unit),
    );
  }
  $form['length'] = array(
    '#type' => 'fieldset',
    '#title' => t('Length format'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['length']['instructions'] = array(
    '#value' => '<div>' . t('Supply a format string for each unit. !value represents the weight value.') . '</div>',
  );
  $units = array(
    'in' => t('Inches'),
    'ft' => t('Feet'),
    'cm' => t('Centimeters'),
    'mm' => t('Millimeters'),
  );
  $form['length']['uc_length_unit'] = array(
    '#type' => 'select',
    '#title' => t('Default unit of measurement'),
    '#default_value' => variable_get('uc_length_unit', 'in'),
    '#options' => $units,
  );
  foreach ($units as $unit => $name) {
    $form['length']['uc_length_format_' . $unit] = array(
      '#type' => 'textfield',
      '#title' => t('@unit format string', array(
        '@unit' => $name,
      )),
      '#default_value' => variable_get('uc_store_length_format_' . $unit, '!value ' . $unit),
    );
  }
  $form['date'] = array(
    '#type' => 'fieldset',
    '#title' => t('Date format'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['date']['instructions'] = array(
    '#value' => '<div>' . t('Supply a format string using !link syntax.', array(
      '!link' => l(t('PHP date'), 'http://www.php.net/date'),
    )) . '</div>',
  );
  $form['date']['uc_date_format_default'] = array(
    '#type' => 'textfield',
    '#title' => t('Default format string'),
    '#default_value' => variable_get('uc_date_format_default', 'm/d/Y'),
  );
  return system_settings_form($form);
}
function uc_store_address_fields_form() {
  $form['fields'] = array(
    '#tree' => TRUE,
  );
  $fields = array(
    'first_name' => array(
      t('First name'),
      TRUE,
    ),
    'last_name' => array(
      t('Last name'),
      TRUE,
    ),
    'phone' => array(
      t('Phone number'),
      TRUE,
    ),
    'company' => array(
      t('Company'),
      TRUE,
    ),
    'street1' => array(
      t('Street address 1'),
      TRUE,
    ),
    'street2' => array(
      t('Street address 2'),
      TRUE,
    ),
    'city' => array(
      t('City'),
      TRUE,
    ),
    'zone' => array(
      t('State/Province'),
      TRUE,
    ),
    'country' => array(
      t('Country'),
      TRUE,
    ),
    'postal_code' => array(
      t('Postal code'),
      TRUE,
    ),
    'address' => array(
      t('Address'),
      FALSE,
    ),
    'street' => array(
      t('Street address'),
      FALSE,
    ),
  );
  $current = variable_get('uc_address_fields', drupal_map_assoc(array(
    'first_name',
    'last_name',
    'phone',
    'company',
    'street1',
    'street2',
    'city',
    'zone',
    'postal_code',
    'country',
  )));
  $required = variable_get('uc_address_fields_required', drupal_map_assoc(array(
    'first_name',
    'last_name',
    'street1',
    'city',
    'zone',
    'postal_code',
    'country',
  )));
  foreach ($fields as $field => $data) {
    if ($data[1]) {
      $form['fields'][$field]['enabled'] = array(
        '#type' => 'checkbox',
        '#default_value' => isset($current[$field]) ? TRUE : FALSE,
      );
      $form['fields'][$field]['required'] = array(
        '#type' => 'checkbox',
        '#default_value' => isset($required[$field]) ? TRUE : FALSE,
      );
    }
    else {
      $form['fields'][$field]['enabled'] = array(
        '#value' => '-',
      );
    }
    $form['fields'][$field]['default'] = array(
      '#value' => $data[0],
    );
    $form['fields'][$field]['title'] = array(
      '#type' => 'textfield',
      '#default_value' => uc_get_field_name($field),
      '#size' => 32,
    );
  }
  $form['save'] = array(
    '#type' => 'submit',
    '#value' => t('Save configuration'),
  );
  $form['reset'] = array(
    '#type' => 'submit',
    '#value' => t('Reset to defaults'),
  );
  return $form;
}
function theme_uc_store_address_fields_form($form) {
  $header = array(
    t('Enabled'),
    t('Field'),
    t('Title'),
    t('Required'),
  );
  foreach (element_children($form['fields']) as $field) {
    $rows[] = array(
      array(
        'data' => drupal_render($form['fields'][$field]['enabled']),
        'align' => 'center',
      ),
      drupal_render($form['fields'][$field]['default']),
      drupal_render($form['fields'][$field]['title']),
      drupal_render($form['fields'][$field]['required']),
    );
  }
  $output = theme('table', $header, $rows) . '<br />' . drupal_render($form);
  return $output;
}
function uc_store_address_fields_form_submit($form_id, $form_values) {
  switch ($form_values['op']) {
    case t('Save configuration'):
      $fields = array();
      $required = array();
      foreach ($form_values['fields'] as $field => $data) {
        variable_set('uc_field_' . $field, $data['title']);
        if ($data['enabled'] == TRUE) {
          $fields[] = $field;
        }
        if ($data['required'] == TRUE) {
          $required[] = $field;
        }
      }
      variable_set('uc_address_fields', drupal_map_assoc($fields));
      variable_set('uc_address_fields_required', drupal_map_assoc($required));
      drupal_set_message(t('The configuration options have been saved.'));
      break;
    case t('Reset to defaults'):
      foreach ($form_values['fields'] as $field => $data) {
        variable_del('uc_field_' . $field);
      }
      variable_del('uc_address_fields');
      drupal_set_message(t('The configuration options have been reset to their default values.'));
      break;
  }
}

/**
 * Form to enter initials for an administrative user.
 */
function uc_store_initials() {
  $form['username'] = array(
    '#type' => 'textfield',
    '#title' => t('User name'),
    '#description' => t('Enter the name of the user whose initials you want to adjust.'),
    '#required' => TRUE,
    '#size' => 32,
    '#autocomplete_path' => 'user/autocomplete',
  );
  $form['initials'] = array(
    '#type' => 'textfield',
    '#title' => t('Initials'),
    '#description' => t('Enter initials or leave blank to erase current initials.'),
    '#size' => 6,
    '#maxlength' => 32,
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );
  return $form;
}
function uc_store_initials_submit($form_id, $form_values) {
  $result = db_query("SELECT uid FROM {users} WHERE name = '%s'", $form_values['username']);
  if ($user = db_fetch_object($result)) {
    if ($form_values['initials'] == '') {
      variable_del('user_initials_' . $user->uid);
      drupal_set_message(t('Initials for !username deleted.', array(
        '!username' => $form_values['username'],
      )));
    }
    else {
      variable_set('user_initials_' . $user->uid, $form_values['initials']);
      drupal_set_message(t('Initials for !username set to !initials.', array(
        '!username' => $form_values['username'],
        '!initials' => $form_values['initials'],
      )));
    }
  }
}
function uc_store_report_settings() {
  $form['uc_store_report'] = array(
    '#type' => 'checkbox',
    '#title' => t('Report version information to Ubercart.org as shown below.'),
    '#default_value' => variable_get('uc_store_report', TRUE),
  );
  $form['data'] = array(
    '#type' => 'fieldset',
    '#title' => t('Report preview'),
  );
  $form['data']['preview'] = array(
    '#value' => '<pre>' . print_r(uc_store_report_data(), TRUE) . '</pre>',
  );
  return system_settings_form($form);
}

/**
 * List of extensible TAPIr tables used by Ubercart.
 */
function uc_store_tables() {
  $output = '<p>' . t('The following tables are used to display various parts of your store to your administrators and customers. Click on a table id to configure the display of that table.');
  $output .= '<p>' . tapir_table_list('admin/store/settings/tables') . '</p>';
  return $output;
}

/**
 * A handler for Javascript helper functions...
 */
function uc_store_js_util($func) {
  switch ($func) {
    case 'currency_format':
      $amount = is_numeric($_POST['amount']) ? $_POST['amount'] : 0;
      $output = uc_currency_format($amount);
      break;
    case 'zone_select':
      $country_id = intval($_POST['country_id']) > 0 ? intval($_POST['country_id']) : uc_store_default_country();
      $title = isset($_POST['title']) ? check_plain($_POST['title']) : NULL;
      $display = isset($_POST['display']) ? check_plain($_POST['display']) : 'name';
      $select = uc_zone_select($title, NULL, NULL, $country_id, $display);
      $select['#parents'] = array();
      $match = array(
        '`<[/]*div[^>]*>`',
        '`<[/]*select[^>]*>`',
        '`\\n|\\r`',
      );
      $replace = array(
        '',
        '',
        '',
      );
      $output = preg_replace($match, $replace, theme('select', $select));
  }
  print $output;
  exit;
}

/*******************************************************************************
 * Module and Helper Functions
 ******************************************************************************/
function theme_uc_store_block_links($menu) {
  if (!($menu['type'] & MENU_VISIBLE_IN_TREE)) {
    return '';
  }
  $depth = count(explode('/', $menu['path']));
  $link_title = uc_store_get_icon($menu['path'], TRUE) . ' ' . $menu['title'];
  $output = str_repeat("  ", $depth) . '<li>' . l($link_title, $menu['path'], array(), NULL, NULL, FALSE, TRUE);
  if (is_array($menu['children']) && !empty($menu['children'])) {
    usort($menu['children'], '_menu_sort');
    $child_output = '';
    foreach ($menu['children'] as $child) {
      $child_output .= theme('uc_store_block_links', menu_get_item($child));
    }
    if ($child_output) {
      $output .= "\n" . str_repeat(" ", 2 * $depth + 1) . "<ul>\n";
      $output .= $child_output;
      $output .= str_repeat(" ", 2 * $depth + 1) . "</ul>\n" . str_repeat("  ", $depth);
    }
  }
  $output .= "</li>\n";
  return $output;
}

/**
 * Return the IMG tag for a store icon.
 *
 * @param $path
 *   The Drupal path of the menu item. Atlernately may specify a filename by
 *   passing this string as file:filename.png.
 * @param $small
 *   Pass TRUE to get a link to the small version of the icon. If specifying a
 *   filename, you should let this be FALSE.
 * @return
 *   HTML output for the image.
 */
function uc_store_get_icon($path, $small = FALSE, $class = 'uc-store-icon', $alt = NULL) {
  $file = FALSE;
  switch ($path) {
    case 'admin/store':
      $file = 'store_monitor';
      break;
    case 'admin/store/orders':
      $file = 'menu_orders';
      break;
    case 'admin/store/customers':
      $file = 'menu_customers';
      break;
    case 'admin/store/products':
      $file = 'menu_products';
      break;
    case 'admin/store/reports':
      $file = 'menu_reports';
      break;
    case 'admin/store/settings':
      $file = 'menu_store_settings';
      break;
    case 'admin/store/help':
      $file = 'menu_help';
      break;
  }
  if (substr($path, 0, 5) == 'file:') {
    $file = substr($path, 5);
  }
  if (!$file) {

    // See if it's hooked in anywhere else...
    return '';
  }
  if ($small) {
    $file .= '_small';
  }
  $alt = ' alt="' . (string) $alt . '"';
  $output = '<img src="' . base_path() . drupal_get_path('module', 'uc_store') . '/images/' . $file . '.gif" class="' . $class . '"' . $alt . ' />';
  return $output;
}

/**
 * Format an amount for display with the store's currency settings.
 */
function uc_currency_format($value, $sign = TRUE, $thou = TRUE, $dec = NULL) {
  if ($value === NULL) {
    return NULL;
  }
  if (variable_get('uc_currency_prec', 2) > 0) {
    if (abs($value) < '.' . str_repeat('0', variable_get('uc_currency_prec', 2) - 1) . '1') {
      $value = 0;
    }
  }
  $format = '';
  if ($value < 0) {
    $value = abs($value);
    $format = '-';
  }
  if ($sign && !variable_get('uc_sign_after_amount', FALSE)) {
    $format .= variable_get('uc_currency_sign', '$');
  }
  $format .= number_format($value, variable_get('uc_currency_prec', 2), !is_null($dec) ? $dec : variable_get('uc_currency_dec', '.'), $thou ? variable_get('uc_currency_thou', ',') : '');
  if ($sign && variable_get('uc_sign_after_amount', FALSE)) {
    $format .= variable_get('uc_currency_sign', '$');
  }
  return $format;
}

/**
 * Format a weight value for display.
 */
function uc_weight_format($value, $unit = NULL) {
  $vars = array(
    '!value' => $value,
  );
  if (is_null($unit)) {
    $unit = variable_get('uc_weight_unit', 'lb');
  }
  $defaults = array(
    'lb' => '!value lb.',
    'oz' => '!value oz.',
    'kg' => '!valuekg',
    'g' => '!valueg',
  );
  $pattern = variable_get('uc_weight_format_' . $unit, $defaults[$unit]);
  if (strpos($pattern, '!value') === FALSE) {
    $pattern = $defaults[$unit];
  }
  $format = strtr($pattern, $vars);
  return $format;
}
function uc_weight_conversion($from_units, $to_units = NULL) {
  if (is_null($to_units)) {
    $to_units = variable_get('uc_weight_unit', 'lb');
  }
  $constant = strtoupper($from_units) . '_TO_' . strtoupper($to_units);
  if (defined($constant) && ($conversion = constant($constant)) > 0) {
    return $conversion;
  }
  else {
    return 1;
  }
}

/**
 * Format a length value for display.
 */
function uc_length_format($value, $unit = NULL) {
  $vars = array(
    '!value' => $value,
  );
  if (is_null($unit)) {
    $unit = variable_get('uc_length_unit', 'in');
  }
  $defaults = array(
    'in' => '!valuein.',
    'ft' => '!valueft.',
    'cm' => '!valuecm',
    'mm' => '!valuemm',
  );
  $pattern = variable_get('uc_length_format_' . $unit, $defaults[$unit]);
  if (strpos($pattern, '!value') === FALSE) {
    $pattern = $defaults[$unit];
  }
  $format = strtr($pattern, $vars);
  return $format;
}
function uc_length_conversion($from_units, $to_units = NULL) {
  if (is_null($to_units)) {
    $to_units = variable_get('uc_length_unit', 'in');
  }
  $constant = strtoupper($from_units) . '_TO_' . strtoupper($to_units);
  if (defined($constant) && ($conversion = constant($constant)) > 0) {
    return $conversion;
  }
  else {
    return 1;
  }
}

/**
 * Format a date value for display.
 */
function uc_date_format($month, $day, $year, $class = 'default') {
  $time = strtotime($month . '/' . $day . '/' . $year);
  $pattern = variable_get('uc_date_format_' . $class, 'm/d/Y');
  if (strlen($pattern) < 3) {
    $pattern = 'm/d/Y';
  }
  return format_date($time, 'custom', $pattern);
}

/**
 * Save the address format for a country.
 */
function uc_set_address_format($country_id, $format) {
  variable_set('uc_address_format_' . intval($country_id), $format);
}

/**
 * Format an address for display based on a country's address format.
 */
function uc_address_format($first_name, $last_name, $company, $street1, $street2, $city, $zone, $postal_code, $country) {
  $result = db_query("SELECT * FROM {uc_zones} WHERE zone_id = %d", $zone);
  if (!($zone_data = db_fetch_array($result))) {
    $zone_data = array(
      'zone_code' => t('N/A'),
      'zone_name' => t('Unknown'),
    );
  }
  $result = db_query("SELECT * FROM {uc_countries} WHERE country_id = %d", $country);
  if (!($country_data = db_fetch_array($result))) {
    $country_data = array(
      'country_name' => t('Unknown'),
      'country_iso_code_2' => t('N/A'),
      'country_iso_code_3' => t('N/A'),
    );
  }
  $variables = array(
    "\r\n" => '<br />',
    '!company' => check_plain($company),
    '!first_name' => check_plain($first_name),
    '!last_name' => check_plain($last_name),
    '!street1' => check_plain($street1),
    '!street2' => check_plain($street2),
    '!city' => check_plain($city),
    '!zone_code' => $zone_data['zone_code'],
    '!zone_name' => $zone_data['zone_name'],
    '!postal_code' => check_plain($postal_code),
    '!country_name' => $country_data['country_name'],
    '!country_code2' => $country_data['country_iso_code_2'],
    '!country_code3' => $country_data['country_iso_code_3'],
  );
  if (uc_store_default_country() != $country) {
    $variables['!country_name_if'] = $country_data['country_name'];
    $variables['!country_code2_if'] = $country_data['country_iso_code_2'];
    $variables['!country_code3_if'] = $country_data['country_iso_code_3'];
  }
  else {
    $variables['!country_name_if'] = '';
    $variables['!country_code2_if'] = '';
    $variables['!country_code3_if'] = '';
  }
  $format = variable_get('uc_address_format_' . $country, '');
  if (empty($format)) {
    $format = "!company\r\n!first_name !last_name\r\n!street1\r\n!street2\r\n!city, !zone_code !postal_code\r\n!country_name_if";
  }
  $address = strtr($format, $variables);
  $address = strtr($address, array(
    "\n" => '<br />',
  ));
  $match = array(
    '`^<br( /)?>`',
    '`<br( /)?>$`',
    '`<br( /)?>(\\s*|[\\s*<br( /)?>\\s*]+)<br( /)?>`',
    '`<br( /)?><br( /)?>`',
    '`<br( /)?>, N/A`',
  );
  $replace = array(
    '',
    '',
    '<br />',
    '<br />',
    '',
    '',
  );
  $address = preg_replace($match, $replace, $address);
  return $address;
}

/**
 * Return the code abbreviation for a zone based on the zone ID or name.
 */
function uc_get_zone_code($zone = NULL) {
  if (empty($zone)) {
    return FALSE;
  }
  if (is_numeric($zone)) {
    $result = db_query("SELECT zone_code FROM {uc_zones} WHERE zone_id = %d", $zone);
  }
  else {
    $result = db_query("SELECT zone_code FROM {uc_zones} WHERE zone_name = '%s'", $zone);
  }
  if ($row = db_fetch_object($result)) {
    return $row->zone_code;
  }
  return FALSE;
}

/**
 * Returns the rows of countries whose data matches the fields specified in the
 * $fields array.
 */
function uc_get_country_data($match = array(), $sort = 'country_name') {
  $valid_fields = array(
    'country_id',
    'country_name',
    'country_iso_code_2',
    'country_iso_code_3',
    'version',
  );
  if (!is_array($match)) {
    $match = array();
  }
  if (!in_array($sort, $valid_fields)) {
    $sort = 'country_name';
  }
  $query = 'SELECT * FROM {uc_countries}';
  if (count($match) > 0) {
    $where = '';
    foreach ($match as $key => $value) {
      if (!in_array($key, $valid_fields)) {
        continue;
      }
      if (strlen($where) == 0) {
        $where = ' WHERE ';
      }
      if (strlen($where) > 7) {
        $where .= ' AND ';
      }
      $where .= $key . " = '" . check_plain($value) . "'";
    }
  }
  $query .= $where . ' ORDER BY ' . check_plain($sort);
  $result = db_query($query);
  if (db_num_rows($result) == 0) {
    return FALSE;
  }
  while ($row = db_fetch_array($result)) {
    $countries[] = $row;
  }
  return $countries;
}

/**
 * Return the name of an address field.
 */
function uc_get_field_name($field) {
  $fields = array(
    'first_name' => t('First name'),
    'last_name' => t('Last name'),
    'email' => t('E-mail'),
    'phone' => t('Phone number'),
    'company' => t('Company'),
    'address' => t('Address'),
    'street' => t('Street address'),
    'street1' => t('Street address 1'),
    'street2' => t('Street address 2'),
    'city' => t('City'),
    'zone' => t('State/Province'),
    'postal_code' => t('Postal code'),
    'country' => t('Country'),
  );
  $default = $fields[$field];
  if (empty($default)) {
    drupal_set_message(t('The field title %field is being accessed incorrectly.', array(
      '%field' => $field,
    )), 'error');
    return '';
  }
  return variable_get('uc_field_' . $field, $default);
}

/**
 * Return TRUE if a field is enabled.
 */
function uc_address_field_enabled($field) {
  $fields = variable_get('uc_address_fields', drupal_map_assoc(array(
    'first_name',
    'last_name',
    'phone',
    'company',
    'street1',
    'street2',
    'city',
    'zone',
    'postal_code',
    'country',
  )));
  if (!isset($fields[$field])) {
    return FALSE;
  }
  else {
    return TRUE;
  }
}

/**
 * Return TRUE if a field is required.
 */
function uc_address_field_required($field) {
  $fields = variable_get('uc_address_fields_required', drupal_map_assoc(array(
    'first_name',
    'last_name',
    'street1',
    'city',
    'zone',
    'postal_code',
    'country',
  )));
  if (!isset($fields[$field])) {
    return FALSE;
  }
  else {
    return TRUE;
  }
}

/**
 * A simple Forms API textfield generator...
 */
function uc_textfield($title, $default = NULL, $required = TRUE, $description = NULL, $maxlength = 32, $size = 32) {
  if (is_null($title) || empty($title)) {
    return NULL;
  }
  $textfield = array(
    '#type' => 'textfield',
    '#title' => $title,
    '#description' => $description,
    '#size' => $size,
    '#maxlength' => $maxlength,
    '#required' => $required,
    '#default_value' => $default,
  );
  return $textfield;
}

/**
 * Create a zone select box for a form.
 * $display can be 'code' or 'name'.
 */
function uc_zone_select($title, $default = NULL, $description = NULL, $country_id = NULL, $display = 'name', $required = FALSE) {
  if (empty($country_id)) {
    $country_id = uc_store_default_country();
  }
  $result = db_query("SELECT * FROM {uc_zones} WHERE zone_country_id = %d ORDER BY %s", $country_id, $display == 'code' ? 'zone_code' : 'zone_name');
  if (db_num_rows($result) == 0) {
    $options[-1] = t('Not applicable');
  }
  else {
    $options[''] = t('Please select');
    while ($zone = db_fetch_object($result)) {
      $options[$zone->zone_id] = $display == 'code' ? $zone->zone_code : $zone->zone_name;
    }
  }
  $select = array(
    '#type' => 'select',
    '#title' => $title,
    '#description' => $description,
    '#options' => $options,
    '#default_value' => $default,
    '#required' => $required,
    '#disabled' => isset($options[-1]) ? TRUE : FALSE,
    '#suffix' => '<span class="zone-throbber"></span>',
  );
  return $select;
}

/**
 * Create a country select box for a form.
 * $display can be 'name', 'code2' for the 2-digit code, or 'code3' for the 3-digit code.
 */
function uc_country_select($title, $default = NULL, $description = NULL, $display = 'name', $required = FALSE) {
  if ($display == 'name') {
    $order_by = 'country_name';
  }
  elseif ($display == 'code2') {
    $order_by = 'country_iso_code_2';
  }
  elseif ($display == 'code3') {
    $order_by = 'country_iso_code_3';
  }
  $result = db_query("SELECT * FROM {uc_countries} WHERE version > 0 ORDER BY %s", $order_by);
  $options = array();
  while ($country = db_fetch_array($result)) {
    $options[$country['country_id']] = $country[$order_by];
  }
  if (count($options) == 0) {
    $options[] = t('No countries found.');
  }
  $default = db_result(db_query("SELECT country_id FROM {uc_countries} WHERE country_id = %d AND version > 0", empty($default) ? 0 : intval($default)));
  $select = array(
    '#type' => 'select',
    '#title' => $title,
    '#description' => $description,
    '#options' => $options,
    '#default_value' => empty($default) ? uc_store_default_country() : $default,
    '#required' => $required,
  );
  uc_add_js(drupal_get_path('module', 'uc_store') . '/uc_country_select.js');
  return $select;
}

/**
 * Create a day select box for a form.
 */
function uc_select_day($title = NULL, $default = NULL) {
  $select = array(
    '#type' => 'select',
    '#title' => is_null($title) ? t('Day') : $title,
    '#options' => drupal_map_assoc(range(1, 31)),
    '#default_value' => is_null($default) ? 1 : $default,
  );
  return $select;
}

/**
 * Create a month select box for a form.
 */
function uc_select_month($title = NULL, $default = NULL, $allow_empty = FALSE) {
  $options = $allow_empty ? array(
    '' => '',
  ) : array();
  $select = array(
    '#type' => 'select',
    '#title' => is_null($title) ? t('Month') : $title,
    '#options' => $options + array(
      1 => t('01 - January'),
      2 => t('02 - February'),
      3 => t('03 - March'),
      4 => t('04 - April'),
      5 => t('05 - May'),
      6 => t('06 - June'),
      7 => t('07 - July'),
      8 => t('08 - August'),
      9 => t('09 - September'),
      10 => t('10 - October'),
      11 => t('11 - November'),
      12 => t('12 - December'),
    ),
    '#default_value' => is_null($default) ? 0 : $default,
  );
  return $select;
}

/**
 * Create a year select box for a form.
 */
function uc_select_year($title = NULL, $default = NULL, $min = NULL, $max = NULL, $allow_empty = FALSE) {
  $min = is_null($min) ? intval(date('Y')) : $min;
  $max = is_null($max) ? intval(date('Y')) + 20 : $max;
  $options = $allow_empty ? array(
    '' => '',
  ) : array();
  $select = array(
    '#type' => 'select',
    '#title' => is_null($title) ? t('Year') : $title,
    '#options' => $options + drupal_map_assoc(range($min, $max)),
    '#default_value' => is_null($default) ? 0 : $default,
  );
  return $select;
}

/**
 * Create an address select box based on a user's previous orders.
 *
 * @param $uid
 *   The user's ID to search for in the orders table.
 * @param $type
 *   Choose either 'shipping' or 'billing'.
 */
function uc_select_address($uid, $type = 'billing', $onchange = '', $title = NULL, $icon_suffix = FALSE) {
  $addresses = uc_get_addresses($uid, $type);
  if (!is_array($addresses) || count($addresses) == 0) {
    return NULL;
  }
  $options = array(
    '0' => t('Select one...'),
  );
  foreach ($addresses as $address) {
    $options[drupal_to_js($address)] = check_plain($address['street1']);
  }
  $select = array(
    '#type' => 'select',
    '#title' => is_null($title) ? t('Address book') : $title,
    '#options' => $options,
    '#attributes' => array(
      'onchange' => $onchange,
    ),
    '#suffix' => $icon_suffix ? uc_store_get_icon('file:address_book', FALSE, 'address-book-icon') : NULL,
  );
  return $select;
}
function uc_get_addresses($uid, $type = 'billing') {
  if ($uid == 0) {
    return NULL;
  }
  if ($type == 'delivery') {
    $type = 'delivery';
  }
  else {
    $type = 'billing';
  }
  switch ($GLOBALS['db_type']) {
    case 'mysqli':
    case 'mysql':
      $result = db_query("SELECT DISTINCT " . $type . "_first_name AS first_name, " . $type . "_last_name AS last_name, " . $type . "_phone AS phone, " . $type . "_company AS company, " . $type . "_street1 AS street1, " . $type . "_street2 AS street2, " . $type . "_city AS city, " . $type . "_zone AS zone, " . $type . "_postal_code AS postal_code, " . $type . "_country AS country FROM {uc_orders} WHERE uid = %d " . "AND order_status IN " . uc_order_status_list('general', TRUE) . " ORDER BY created DESC", $uid);
      break;
    case 'pgsql':

      // In pgsql, ORDER BY requires the field being sorted by to be in the SELECT list.
      // But if we have the 'created' column in the SELECT list, the DISTINCT is
      // rather useless. So for pgsql we will just sort addresses alphabetically.
      $result = db_query("SELECT DISTINCT " . $type . "_first_name AS first_name, " . $type . "_last_name AS last_name, " . $type . "_phone AS phone, " . $type . "_company AS company, " . $type . "_street1 AS street1, " . $type . "_street2 AS street2, " . $type . "_city AS city, " . $type . "_zone AS zone, " . $type . "_postal_code AS postal_code, " . $type . "_country AS country FROM {uc_orders} WHERE uid = %d " . "AND order_status IN " . uc_order_status_list('general', TRUE) . " ORDER BY " . $type . "_street1 DESC", $uid);
      break;
  }
  $addresses = array();
  while ($address = db_fetch_array($result)) {
    if (!empty($address['street1']) || !empty($address['postal_code'])) {
      $addresses[] = $address;
    }
  }
  return $addresses;
}

/**
 * Strip <form> tags and form_token and form_id hidden fields from form HTML for
 * use in an AJAX populated div. (Enables these values to be access via $_POST.)
 */
function uc_strip_form($html) {
  $html = preg_replace('`</?form.*>`', '', $html);
  $html = preg_replace('`<input.*name="form_(token|id)".*>`', '', $html);
  return $html;
}

// Return the initials for a user account.
function uc_get_initials($uid) {
  if ($uid == 0 || $uid == NULL) {
    return '-';
  }
  return check_plain(variable_get('user_initials_' . $uid, $uid));
}

/**
 * Return an array of country files in ubercart/uc_store/countries that can
 * be installed or updated.
 */
function _country_import_list() {
  $dir = drupal_get_path('module', 'uc_store') . '/countries/';
  $countries = array();
  if (is_dir($dir)) {
    if ($dh = opendir($dir)) {
      while (($file = readdir($dh)) !== false) {
        switch (filetype($dir . $file)) {
          case 'file':
            if (substr($file, -4, 4) == '.cif') {
              $pieces = explode('_', substr($file, 0, strlen($file) - 4));
              $country_id = intval($pieces[count($pieces) - 2]);
              $version = $pieces[count($pieces) - 1];
              if (!isset($countries[$country_id])) {
                $countries[$country_id]['version'] = $version;
                $countries[$country_id]['file'] = $file;
              }
              else {
                if ($version > $countries[$country_id]['version']) {
                  $countries[$country_id]['version'] = $version;
                  $countries[$country_id]['file'] = $file;
                }
              }
            }
            break;
        }
      }
      closedir($dh);
    }
  }
  return $countries;
}

/**
 * Include the appropriate country file and return the base for hooks.
 */
function _country_import_include($country_id, $version) {
  $dir = drupal_get_path('module', 'uc_store') . '/countries/';
  $match = '_' . $country_id . '_' . $version . '.cif';
  $matchlen = strlen($match);
  $countries = array();
  if (is_dir($dir)) {
    if ($dh = opendir($dir)) {
      while (($file = readdir($dh)) !== false) {
        switch (filetype($dir . $file)) {
          case 'file':
            if (substr($file, -$matchlen) == $match) {
              require_once $dir . $file;
              return substr($file, 0, strlen($file) - $matchlen);
            }
            break;
        }
      }
      closedir($dh);
    }
  }
  return FALSE;
}

/**
 * Return an array of IDs to use for country file zone INSERTs!
 */
function uc_get_zone_ids($num) {
  for ($i = 0; $i < $num; $i++) {
    $ids[] = db_next_id('{uc_zones}_zone_id');
  }
  return $ids;
}

// Sort an array of arrays having a weight key to determine their order.
function uc_weight_sort($a, $b) {
  if ($a['weight'] == $b['weight']) {
    return 0;
  }
  return $a['weight'] > $b['weight'] ? 1 : -1;
}

/**
 * Theme an array of settings information into a pretty little table.
 */
function theme_uc_settings_overview($sections) {
  if (!is_array($sections) || count($sections) == 0) {
    return t('No overview found.');
  }
  uc_add_js(drupal_get_path('module', 'uc_store') . '/uc_store.js');
  $output = '<table class="settings-overview">';
  foreach ($sections as $section) {
    $output .= '<tr class="section" id="' . $section['edit'] . '">' . '<td valign="top">' . uc_store_get_icon('file:order_edit', FALSE, 'settings-icon', t('Edit')) . '</td><td class="section-items">' . '<div class="section-title">' . $section['title'] . ':</div>';
    if (is_array($section['items']) && count($section['items']) > 0) {
      $output .= theme('item_list', $section['items']);
    }
    else {
      $output .= '<tr><td>' . t('No settings found.') . '</td></tr>';
    }
    $output .= '</td></tr>';
  }
  $output .= '</table>';
  return $output;
}

/**
 * Return the default message for a configurable message.
 */
function uc_get_message($message_id) {
  static $messages;
  if (empty($messages)) {
    $messages = module_invoke_all('uc_message');
  }
  return $messages[$message_id];
}

/**
 * Theme a pane sorting form into a table!
 */
function theme_uc_pane_sort_table($form) {
  $prefix = $form['#pane_prefix'];
  if (isset($form['#table_attributes']) && is_array($form['#table_attributes'])) {
    $attributes = $form['#table_attributes'];
  }
  else {
    $attributes = array();
  }
  $header = array(
    t('Enabled'),
    t('Title'),
    t('Weight'),
  );
  foreach (element_children($form) as $pane_id) {
    $rows[] = array(
      array(
        'data' => drupal_render($form[$pane_id][$prefix . '_' . $pane_id . '_enabled']),
        'align' => 'center',
      ),
      drupal_render($form[$pane_id]['title']),
      drupal_render($form[$pane_id][$prefix . '_' . $pane_id . '_weight']),
    );
  }
  return theme('table', $header, $rows, $attributes) . '<br />';
}

/**
 * Return an array of values like PHP 5's range function.
 */
function uc_range($low, $high, $step = 1) {
  if (!is_numeric($low) || !is_numeric($high)) {
    return array(
      0,
    );
  }
  if ($low == $high || !is_numeric($step) || $step == 0) {
    return array(
      $low,
    );
  }
  if ($step < 0) {
    $step = abs($step);
  }
  $arr = array();
  for ($i = $low; $low < $high ? $i <= $high : $i >= $high; $low < $high ? $i += $step : ($i -= $step)) {
    $arr[] = $i;
  }
  return $arr;
}
function uc_store_address() {
  $store_address = uc_address_format(NULL, NULL, variable_get('uc_store_name', NULL), variable_get('uc_store_street1', NULL), variable_get('uc_store_street2', NULL), variable_get('uc_store_city', NULL), variable_get('uc_store_zone', NULL), variable_get('uc_store_postal_code', NULL), uc_store_default_country());
  return $store_address;
}
function uc_numeric_validate($form, $sign = 0) {
  $error = t('You must enter a number.');
  switch ($sign) {
    case -1:
      $error = t('You must enter a negative number.');
      break;
    case 1:
      $error = t('You must enter a positive number.');
      break;
  }

  // Allow an empty field to be cast to 0
  if (empty($form['#value']) || is_numeric($form['#value'])) {
    if ($form['#value'] <= 0 && $sign == 1 || $form['#value'] >= 0 && $sign == -1) {
      form_error($form, $error);
    }
  }
  else {
    form_error($form, $error);
  }
}

// Returns the e-mail from string in the format of Store Name <store@email.com>.
function uc_store_email_from() {
  $email_from = variable_get('uc_store_email', '');
  if (empty($email_from)) {
    $email_from = variable_get('site_mail', ini_get('sendmail_from'));
  }

  // Add the store name to the e-mail from line.  Must be optional to prevent
  // server conflicts.
  if (variable_get('uc_store_email_include_name', TRUE)) {
    $store = variable_get('uc_store_name', '');
    if (!empty($store)) {
      $email_from = '"' . $store . '" <' . $email_from . '>';
    }
  }
  return $email_from;
}

/**
 * Trimmed down version of GPL class by Tony Marston.  Details available at
 * http://www.tonymarston.co.uk/php-mysql/encryption.html
 *
 * Usage:
 * 1) Create an encryption object.
 *    ex: $crypt = new uc_encryption_class;
 * 2) To encrypt string data, use the encrypt method with the key.
 *    ex: $encrypted = $crypt->encrypt($key, $string);
 * 3) To decrypt string data, use the decrypt method with the original key.
 *    ex: $decrypted = $crypt->decrypt($key, $string);
 * 4) To check for errors, use the errors method to return an array of errors.
 *    ex: $errors = $crypt->errors();
 */
class uc_encryption_class {
  var $scramble1;
  var $scramble2;
  var $errors;
  var $adj;
  var $mod;
  function uc_encryption_class() {
    $this->errors = array();
    $this->scramble1 = '! #$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`"abcdefghijklmnopqrstuvwxyz{|}~';
    $this->scramble2 = 'f^jAE]okIOzU[2&q1{3`h5w_794p@6s8?BgP>dFV=m" D<TcS%Ze|r:lGK/uCy.Jx)HiQ!#$~(;Lt-R}Ma,NvW+Ynb*0X';
    $this->adj = 1.75;
    $this->mod = 3;
  }
  function decrypt($key, $source) {
    $this->errors = array();
    $fudgefactor = $this
      ->_convertKey($key);
    if ($this->errors) {
      return;
    }
    if (empty($source)) {

      // Commented out to prevent errors getting logged for use cases that may
      // have variable encryption/decryption requirements. -RS
      // $this->errors[] = t('No value has been supplied for decryption');
      return;
    }
    $target = NULL;
    $factor2 = 0;
    for ($i = 0; $i < strlen($source); $i++) {
      $char2 = substr($source, $i, 1);
      $num2 = strpos($this->scramble2, $char2);
      if ($num2 === FALSE) {
        $this->errors[] = t('Source string contains an invalid character (!char)', array(
          '!char' => $char2,
        ));
        return;
      }
      $adj = $this
        ->_applyFudgeFactor($fudgefactor);
      $factor1 = $factor2 + $adj;
      $num1 = $num2 - round($factor1);
      $num1 = $this
        ->_checkRange($num1);
      $factor2 = $factor1 + $num2;
      $char1 = substr($this->scramble1, $num1, 1);
      $target .= $char1;
    }
    return rtrim($target);
  }
  function encrypt($key, $source, $sourcelen = 0) {
    $this->errors = array();
    $fudgefactor = $this
      ->_convertKey($key);
    if ($this->errors) {
      return;
    }
    if (empty($source)) {

      // Commented out to prevent errors getting logged for use cases that may
      // have variable encryption/decryption requirements. -RS
      // $this->errors[] = t('No value has been supplied for encryption');
      return;
    }
    while (strlen($source) < $sourcelen) {
      $source .= ' ';
    }
    $target = NULL;
    $factor2 = 0;
    for ($i = 0; $i < strlen($source); $i++) {
      $char1 = substr($source, $i, 1);
      $num1 = strpos($this->scramble1, $char1);
      if ($num1 === FALSE) {
        $this->errors[] = t('Source string contains an invalid character (!char)', array(
          '!char' => $char1,
        ));
        return;
      }
      $adj = $this
        ->_applyFudgeFactor($fudgefactor);
      $factor1 = $factor2 + $adj;
      $num2 = round($factor1) + $num1;
      $num2 = $this
        ->_checkRange($num2);
      $factor2 = $factor1 + $num2;
      $char2 = substr($this->scramble2, $num2, 1);
      $target .= $char2;
    }
    return $target;
  }
  function getAdjustment() {
    return $this->adj;
  }
  function getModulus() {
    return $this->mod;
  }
  function setAdjustment($adj) {
    $this->adj = (double) $adj;
  }
  function setModulus($mod) {
    $this->mod = (int) abs($mod);
  }
  function _applyFudgeFactor(&$fudgefactor) {
    static $alerted = FALSE;
    if (!is_array($fudgefactor)) {
      if (!$alerted) {

        // Throw an error that makes sense so this stops getting reported.
        $this->errors[] = t('No encryption key was found.');
        drupal_set_message(t('Ubercart cannot find a necessary encryption key.  Refer to the store admin <a href="!url">dashboard</a> to isolate which one.', array(
          '!url' => url('admin/store'),
        )), 'error');
        $alerted = TRUE;
      }
    }
    else {
      $fudge = array_shift($fudgefactor);
    }
    $fudge = $fudge + $this->adj;
    $fudgefactor[] = $fudge;
    if (!empty($this->mod)) {
      if ($fudge % $this->mod == 0) {
        $fudge = $fudge * -1;
      }
    }
    return $fudge;
  }
  function _checkRange($num) {
    $num = round($num);
    $limit = strlen($this->scramble1);
    while ($num >= $limit) {
      $num = $num - $limit;
    }
    while ($num < 0) {
      $num = $num + $limit;
    }
    return $num;
  }
  function _convertKey($key) {
    if (empty($key)) {

      // Commented out to prevent errors getting logged for use cases that may
      // have variable encryption/decryption requirements. -RS
      // $this->errors[] = 'No value has been supplied for the encryption key';
      return;
    }
    $array[] = strlen($key);
    $tot = 0;
    for ($i = 0; $i < strlen($key); $i++) {
      $char = substr($key, $i, 1);
      $num = strpos($this->scramble1, $char);
      if ($num === false) {
        $this->errors[] = "Key contains an invalid character ({$char})";
        return;
      }
      $array[] = $num;
      $tot = $tot + $num;
    }
    $array[] = $tot;
    return $array;
  }

}

/**
 * Logs encryption errors to watchdog.
 *
 * @param $crypt
 *   The object used to perform your encryption/decryption.
 * @param $module
 *   The module name to specify in the watchdog notices.
 */
function uc_store_encryption_errors(&$crypt, $module) {
  if (!empty($crypt->errors)) {
    foreach ($crypt->errors as $message) {
      $items[] = $message;
    }
    watchdog('encryption', t('Encryption failed. !messages', array(
      '!messages' => theme('item_list', $items),
    )), WATCHDOG_ERROR);
  }
}

// Returns a default store country value.
function uc_store_default_country() {
  static $default;
  if (!empty($default)) {
    return $default;
  }
  $default = variable_get('uc_store_country', 840);
  $result = db_result(db_query("SELECT COUNT(*) FROM {uc_countries} WHERE country_id = %d AND version > 0", $default));
  if ($result == 0) {
    $default = db_result(db_query("SELECT country_id FROM {uc_countries} WHERE version > 0 ORDER BY country_name LIMIT 1"));
  }
  return $default;
}

// Wrapper for uc_add_js() to cache .js files based on their timestamp.
function uc_add_js($data = NULL, $type = 'module', $scope = 'header', $defer = FALSE, $cache = TRUE) {

  // If using the JS Aggregator module or some other module that this function
  // interferes with, uncomment the following two lines.
  // drupal_add_js($data, $type, $scope, $defer, $cache);
  // return;
  // If we're adding a module or theme .js file...
  if (($type == 'module' || $type == 'theme') && $cache) {

    // And the file actually exists...
    if (file_exists($data)) {

      // Add the file timestamp to the query so the browser-cached
      // javascript is updated when the file is updated.
      drupal_add_js($data . '?' . substr(filemtime($data), -5), $type, $scope, $defer, $cache);
    }
    else {

      // Log a file not found to the watchdog.
      watchdog('uc_store', t('Could not find JS file %path.', array(
        '%path' => $data,
      )), WATCHDOG_ERROR);
    }
  }
  else {
    drupal_add_js($data, $type, $scope, $defer, $cache);
  }
}

// Builds the version info reported to Ubercart.org.
function uc_store_report_data() {

  // Build the data array.
  $data = array(
    'site_id' => variable_get('uc_store_site_id', ''),
    'server_name' => $_SERVER['SERVER_NAME'],
    'php_version' => PHP_VERSION,
    'drupal_version' => VERSION,
    'db_type' => $GLOBALS['db_type'],
    'db_version' => db_version(),
  );

  // Grab the Ubercart version from uc_store.info.
  $info = _module_parse_info_file(drupal_get_path('module', 'uc_store') . '/uc_store.info');
  $data['ubercart_version'] = $info['version'] ? $info['version'] : 'bzr';
  return $data;
}
function uc_store_send_report() {

  // Load the version data array.
  $data = uc_store_report_data();

  // Set the time of our report.
  variable_set('uc_store_last_report', time());

  // Send the data off to Ubercart.org.
  $response = drupal_http_request('http://www.ubercart.org/statistics/report', array(
    'Content-Type' => 'application/x-www-form-urlencoded',
  ), 'POST', drupal_query_string_encode($data));

  // If we got a response, store it as the site ID.
  if ($response->data) {
    variable_set('uc_store_site_id', $response->data);
  }
  watchdog('uc_store', t('Reported the following version info to Ubercart.org:') . '<pre>' . print_r($data, TRUE) . '</pre>');
}

// Checks referers to see if they are in the allowed list.
function uc_referer_check($urls) {
  $http_referer = uc_referer_uri();

  // Always return true if we have no referer; covers the case of page refreshes
  // and switching from HTTP to HTTPS. This bypasses the two-time check below...
  // is it safe?
  if (empty($http_referer)) {
    return TRUE;
  }

  // Check the user didn't shamelessly two-time us with another site.
  $referer = parse_url($http_referer);
  if ($referer['host'] != $_SERVER['SERVER_NAME']) {
    return FALSE;
  }

  // The check itself.
  foreach ((array) $urls as $url) {
    if (substr($http_referer, -strlen($url)) == $url) {
      return TRUE;
    }
  }
  return FALSE;
}

// Provides a more reliable referrer for Ubercart.
function uc_referer_uri() {
  if (referer_uri() == '') {
    return $_SESSION['uc_referer_uri'];
  }
  else {
    return referer_uri();
  }
}

// Returns the current version of Ubercart.
function uc_version() {
  return '1.7';
}

Functions

Namesort descending Description
theme_uc_admin_dashboard
theme_uc_pane_sort_table Theme a pane sorting form into a table!
theme_uc_settings_overview Theme an array of settings information into a pretty little table.
theme_uc_store_address_fields_form
theme_uc_store_block_links
theme_uc_store_footer
uc_address_field_enabled Return TRUE if a field is enabled.
uc_address_field_required Return TRUE if a field is required.
uc_address_format Format an address for display based on a country's address format.
uc_add_js
uc_country_disable Disable a country so it remains installed but is no longer selectable.
uc_country_enable Enable a disabled country.
uc_country_formats_form
uc_country_formats_form_submit
uc_country_import_form
uc_country_import_form_submit
uc_country_remove_form
uc_country_remove_form_submit
uc_country_select Create a country select box for a form. $display can be 'name', 'code2' for the 2-digit code, or 'code3' for the 3-digit code.
uc_country_settings_overview Display the country settings overview.
uc_country_update Update a country to its latest version.
uc_currency_format Format an amount for display with the store's currency settings.
uc_date_format Format a date value for display.
uc_get_addresses
uc_get_country_data Returns the rows of countries whose data matches the fields specified in the $fields array.
uc_get_field_name Return the name of an address field.
uc_get_initials
uc_get_message Return the default message for a configurable message.
uc_get_zone_code Return the code abbreviation for a zone based on the zone ID or name.
uc_get_zone_ids Return an array of IDs to use for country file zone INSERTs!
uc_length_conversion
uc_length_format Format a length value for display.
uc_numeric_validate
uc_range Return an array of values like PHP 5's range function.
uc_referer_check
uc_referer_uri
uc_select_address Create an address select box based on a user's previous orders.
uc_select_day Create a day select box for a form.
uc_select_month Create a month select box for a form.
uc_select_year Create a year select box for a form.
uc_set_address_format Save the address format for a country.
uc_store_address
uc_store_address_fields_form
uc_store_address_fields_form_submit
uc_store_admin
uc_store_block Implementation of hook_block().
uc_store_configuration_page Display store configuration page.
uc_store_cron Implementation of hook_cron().
uc_store_customers Display customer administration page.
uc_store_customer_orders
uc_store_customer_search Display the customer search page.
uc_store_customer_search_form
uc_store_customer_search_form_submit
uc_store_default_country
uc_store_display_settings_form
uc_store_email_from
uc_store_encryption_errors Logs encryption errors to watchdog.
uc_store_exit Implementation of hook_exit().
uc_store_footer Implementation of hook_footer().
uc_store_format_settings_form
uc_store_get_icon Return the IMG tag for a store icon.
uc_store_help
uc_store_init Implementation of hook_init().
uc_store_initials Form to enter initials for an administrative user.
uc_store_initials_submit
uc_store_js_util A handler for Javascript helper functions...
uc_store_menu Implementation of hook_menu().
uc_store_perm Implementation of hook_perm().
uc_store_reports Display main reports page.
uc_store_report_data
uc_store_report_settings
uc_store_send_report
uc_store_store_settings_form
uc_store_store_settings_overview Display the store settings overview page.
uc_store_tables List of extensible TAPIr tables used by Ubercart.
uc_store_token_list Implementation of hook_token_list(). (token.module)
uc_store_token_values Implementation of hook_token_values(). (token.module)
uc_store_ubercart_help Display store help page.
uc_store_ubercart_help_tokens Display the tokens help page.
uc_strip_form Strip <form> tags and form_token and form_id hidden fields from form HTML for use in an AJAX populated div. (Enables these values to be access via $_POST.)
uc_textfield A simple Forms API textfield generator...
uc_version
uc_weight_conversion
uc_weight_format Format a weight value for display.
uc_weight_sort
uc_zone_select Create a zone select box for a form. $display can be 'code' or 'name'.
_country_import_include Include the appropriate country file and return the base for hooks.
_country_import_list Return an array of country files in ubercart/uc_store/countries that can be installed or updated.
_store_footer_options

Constants

Classes

Namesort descending Description
uc_encryption_class Trimmed down version of GPL class by Tony Marston. Details available at http://www.tonymarston.co.uk/php-mysql/encryption.html