View source  
  <?php
define('AMAZON_ECS_SCHEMA', '2011-08-01');
define('AMAZON_PARTICIPANT_TYPES', 'Author,Artist,Actor,Director,Creator');
define('AMAZON_IMAGE_SIZES', 'SmallImage,MediumImage,LargeImage');
function amazon_menu() {
  $items = array();
  $items['admin/config/services/amazon'] = array(
    'title' => 'Amazon API',
    'description' => 'Global settings for the Amazon Ecommerce API.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'amazon_settings_form',
    ),
    'file' => 'amazon.admin.inc',
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer amazon',
    ),
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/config/services/amazon/storage'] = array(
    'title' => 'Storage',
    'description' => 'Local data storage settings for Amazon products.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'amazon_storage_settings_form',
    ),
    'file' => 'amazon.admin.inc',
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer amazon',
    ),
    'type' => MENU_LOCAL_TASK,
  );
  $items['admin/config/services/amazon/test'] = array(
    'title' => 'Test',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'amazon_test_form',
    ),
    'file' => 'amazon.admin.inc',
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer amazon',
    ),
    'type' => MENU_LOCAL_TASK,
  );
  $items['admin/config/services/amazon/api'] = array(
    'title' => 'Settings',
    'weight' => -10,
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );
  return $items;
}
function amazon_permission() {
  return array(
    'administer amazon' => array(
      'title' => t('Administer Amazon module'),
      'description' => t('Configure and test Amazon module.'),
    ),
  );
}
function amazon_theme() {
  $templates = array(
    'amazon_item' => array(
      'variables' => array(
        'item' => array(),
        'style' => NULL,
      ),
      'template' => 'amazon-item',
      'path' => drupal_get_path('module', 'amazon') . '/templates',
    ),
    'amazon_inline_item' => array(
      'variables' => array(
        'item' => array(),
      ),
      'template' => 'amazon-item--inline',
      'preprocess functions' => array(
        'template_preprocess_amazon_item',
      ),
      'path' => drupal_get_path('module', 'amazon') . '/templates',
    ),
    'amazon_detail' => array(
      'variables' => array(
        'item' => array(),
        'detail' => NULL,
      ),
      'template' => 'amazon-detail',
      'preprocess functions' => array(
        'template_preprocess_amazon_item',
      ),
      'path' => drupal_get_path('module', 'amazon') . '/templates',
    ),
    
    'amazon_item__details' => array(
      'variables' => array(
        'item' => array(),
      ),
      'template' => 'amazon-item--details',
      'preprocess functions' => array(
        'template_preprocess_amazon_item',
      ),
      'path' => drupal_get_path('module', 'amazon') . '/templates',
    ),
    'amazon_item__default' => array(
      'variables' => array(
        'item' => array(),
      ),
      'template' => 'amazon-item',
      'preprocess functions' => array(
        'template_preprocess_amazon_item',
      ),
      'path' => drupal_get_path('module', 'amazon') . '/templates',
    ),
    'amazon_item__thumbnail' => array(
      'variables' => array(
        'item' => array(),
      ),
      'template' => 'amazon-item--thumbnail',
      'preprocess functions' => array(
        'template_preprocess_amazon_item',
      ),
      'path' => drupal_get_path('module', 'amazon') . '/templates',
    ),
    'amazon_item__medium' => array(
      'variables' => array(
        'item' => array(),
      ),
      'template' => 'amazon-item--medium',
      'preprocess functions' => array(
        'template_preprocess_amazon_item',
      ),
      'path' => drupal_get_path('module', 'amazon') . '/templates',
    ),
    'amazon_item__large' => array(
      'variables' => array(
        'item' => array(),
      ),
      'template' => 'amazon-item--large',
      'preprocess functions' => array(
        'template_preprocess_amazon_item',
      ),
      'path' => drupal_get_path('module', 'amazon') . '/templates',
    ),
  );
  return $templates;
}
function template_preprocess_amazon_item(&$variables, $theme_type) {
  $item = $variables['item'];
  
  foreach ($item as $key => $value) {
    if (is_string($value)) {
      $variables[$key] = filter_xss($value);
    }
  }
  $variables['type'] = _amazon_clean_type($item['producttypename']);
  $variables['detailpageurl'] = check_url($item['detailpageurl']);
  $variables['editorialreview'] = !empty($item['editorialreviews']) ? filter_xss_admin($item['editorialreviews'][0]['content']) : '';
  $variables['customerreviews_iframe'] = !empty($item['customerreviews_iframe']) ? check_url($item['customerreviews_iframe']) : '';
  $variables['invalid_asin'] = !empty($item['invalid_asin']) ? 1 : 0;
  if (!empty($variables['customerreviews'])) {
    foreach ($variables['customerreviews'] as $key => $review) {
      $variables['customerreviews'][$key] = filter_xss($variables['customerreviews'][$key]);
    }
  }
  $variables['invalid_asin'] = !empty($variables['invalid_asin']) ? 1 : 0;
  if (!empty($variables['publicationdate'])) {
    $date = explode('-', $variables['publicationdate']);
    $variables['publicationyear'] = check_plain($date[0]);
  }
  else {
    $variables['publicationyear'] = '';
  }
  
  if (isset($item['participants'])) {
    $variables['participants'] = filter_xss(filter_xss(implode(', ', $item['participants'])));
    $participant_types = preg_split('/,/', AMAZON_PARTICIPANT_TYPES);
    foreach ($participant_types as $participant_type) {
      $participant_type = strtolower($participant_type);
      if (!empty($item[$participant_type])) {
        if (is_string($item[$participant_type])) {
          $variables[$participant_type] = filter_xss($item[$participant_type]);
        }
        else {
          $variables[$participant_type] = filter_xss(implode(', ', $item[$participant_type]));
        }
      }
    }
  }
  $variables += array(
    'participants' => '',
    'director' => '',
    'actor' => '',
    'artist' => '',
    'author' => '',
  );
  
  if (isset($item['imagesets'])) {
    foreach ($item['imagesets'] as $key => $image) {
      $variables[$key] = theme('image', array(
        'path' => $image['url'],
        'alt' => t('Image of') . ' ' . strip_tags($item['title']),
        'title' => strip_tags($item['title']),
        'attributes' => array(
          'height' => $image['height'],
          'width' => $image['width'],
        ),
        'getsize' => FALSE,
      ));
      $variables["{$key}url"] = check_url($image['url']);
      $variables["{$key}height"] = check_plain($image['height']);
      $variables["{$key}width"] = check_plain($image['width']);
    }
  }
  $variables['image'] = !empty($variables['mediumimage']) ? $variables['mediumimage'] : '';
  $variables['classes_array'] = array();
  $variables['attributes_array'] = array();
  $variables['title_attributes_array'] = array();
  $variables['content_attributes_array'] = array();
  if (!empty($variables['detail']) && $theme_type == 'amazon_detail') {
    $variables['classes_array'] = array(
      "amazon-item",
      "amazon-item-detail-{$variables['detail']}",
    );
  }
  if (!empty($variables['style']) && $variables['style'] == 'inline' && !empty($variables['producttypename'])) {
    $variables['theme_hook_suggestions'][] = 'amazon_inline_item__' . _amazon_clean_type($item['producttypename']);
  }
  if (!empty($variables['style'])) {
    $variables['classes'] = _amazon_item_classes($item) . ' amazon-item-' . check_plain($variables['style']);
    
    $variables['theme_hook_suggestions'][] = 'amazon_item__' . $variables['style'];
    $variables['theme_hook_suggestions'][] = 'amazon_item__' . strtolower($variables['type']);
    $variables['theme_hook_suggestions'][] = 'amazon_item__' . strtolower($variables['type']) . '__' . $variables['style'];
    if (!empty($item['view']) && !empty($item['view']->name)) {
      $variables['theme_hook_suggestions'][] = 'amazon_item_view__' . $item['view']->name;
      $variables['theme_hook_suggestions'][] = 'amazon_item__' . strtolower($variables['type']) . '__view__' . $item['view']->name;
    }
  }
}
function _amazon_clean_type($type) {
  return check_plain(strtolower(str_replace(array(
    'ABIS_',
    'CONSOLE_',
    'VIDEO_',
    ' ',
  ), array(
    '',
    '',
    '',
    '_',
  ), $type)));
}
function _amazon_item_classes($item) {
  return 'amazon-item amazon-item-' . str_replace('_', '-', _amazon_clean_type($item['producttypename']));
}
function amazon_http_request($operation, $parameters = array(), $locale = NULL) {
  if (!isset($locale)) {
    $locale = variable_get('amazon_default_locale', 'US');
  }
  $metadata = amazon_data_cache();
  $locale_data = $metadata['locales'][$locale];
  
  $parameters += array(
    'Service' => 'AWSECommerceService',
    'Version' => AMAZON_ECS_SCHEMA,
    'AWSAccessKeyId' => variable_get('amazon_aws_access_key', ''),
    'Operation' => $operation,
  );
  if ($associate_id = amazon_get_associate_id($locale)) {
    $parameters += array(
      'AssociateTag' => $associate_id,
    );
  }
  $parameters_after_hook = module_invoke_all('amazon_request', $parameters);
  if (!empty($parameters_after_hook)) {
    $parameters = $parameters_after_hook;
  }
  $parameters += array(
    'Timestamp' => gmdate("Y-m-d\\TH:i:s") . 'Z',
  );
  uksort($parameters, 'strnatcmp');
  $params = array();
  foreach ($parameters as $key => $value) {
    if (is_array($value)) {
      $value = implode(',', $value);
    }
    $param = str_replace("%7E", "~", rawurlencode($key));
    $value = str_replace("%7E", "~", rawurlencode($value));
    $params[] = $param . '=' . $value;
  }
  $secret_access_key = variable_get('amazon_aws_secret_access_key', "");
  if ($secret_access_key == "") {
    watchdog('amazon', "No Secret Access Key configured. You must configure one at Admin->Settings->Amazon API", NULL, WATCHDOG_ERROR);
    drupal_set_message(t("Amazon Module: No Secret Access Key is configured. Please contact your site administrator"));
    return FALSE;
  }
  
  $query_string = implode('&', $params);
  $parsed_url = parse_url($locale_data['url']);
  $host = strtolower($parsed_url['host']);
  $string_to_sign = "GET\n{$host}\n{$parsed_url['path']}\n{$query_string}";
  $signature = base64_encode(hash_hmac('sha256', $string_to_sign, $secret_access_key, TRUE));
  $signature = str_replace("%7E", "~", rawurlencode($signature));
  $query_string .= "&Signature={$signature}";
  $url = $locale_data['url'] . '?' . $query_string;
  
  $results = drupal_http_request($url, array(
    'method' => 'GET',
  ));
  if ($results->code == 200) {
    $xml = new SimpleXMLElement($results->data);
    return $xml;
  }
  if ($results->code >= 400 && $results->code < 500) {
    try {
      $xml = new SimpleXMLElement($results->data);
    } catch (Exception $e) {
      watchdog('amazon', "Error handling results: http_code=%http_code, data=%data.", array(
        '%http_code' => $results->code,
        '%data' => (string) $results->data,
      ));
      return FALSE;
    }
    watchdog('amazon', "HTTP code %http_code accessing Amazon's AWS service: %code, %message", array(
      '%http_code' => $results->code,
      '%code' => (string) $xml->Error->Code,
      '%message' => (string) $xml->Error->Message,
    ));
    return FALSE;
  }
  watchdog('amazon', "Error accessing Amazon AWS web service with query '%url'. HTTP result code=%code, error=%error", array(
    '%code' => $results->code,
    '%error' => $results->error,
    '%url' => $url,
  ));
  return FALSE;
}
function amazon_item_lookup($item_ids = array(), $force_lookup = FALSE, $locale = NULL) {
  if (empty($item_ids)) {
    return array();
  }
  if (is_string($item_ids)) {
    $item_ids = array(
      $item_ids,
    );
  }
  $items = array();
  if (!$force_lookup) {
    $items = amazon_item_lookup_from_db($item_ids);
  }
  $items_to_fetch = array();
  foreach ($item_ids as $item_id) {
    if (!isset($items[$item_id])) {
      $items_to_fetch[] = $item_id;
    }
  }
  $items_from_web = amazon_item_lookup_from_web($items_to_fetch, $locale);
  $full_set = $items + $items_from_web;
  return $full_set;
}
function amazon_item_lookup_from_web($item_ids = array(), $locale = NULL) {
  $amazon_limit = 10;
  
  $asins = array();
  $results = array();
  $item_ids = array_filter($item_ids);
  
  foreach ($item_ids as $asin) {
    if (!empty($asin)) {
      $asins[] = $asin;
      if (count($asins) >= $amazon_limit || count($asins) == count($item_ids)) {
        $results += _amazon_item_batch_lookup_from_web($asins, $locale);
        $asins = array();
      }
    }
  }
  return $results;
}
function _amazon_item_batch_lookup_from_web($item_ids = array(), $locale = NULL) {
  if (!empty($item_ids)) {
    $params = array(
      'ItemId' => implode(',', $item_ids),
      'ResponseGroup' => amazon_get_response_groups(),
    );
    $results = amazon_http_request('ItemLookup', $params, $locale);
    if (!empty($results->Items->Request->Errors)) {
      _amazon_item_batch_lookup_from_web_errors($results->Items->Request->Errors);
    }
    $items = array();
    if (!empty($results->Items->Item)) {
      foreach ($results->Items->Item as $xml) {
        $item = amazon_item_clean_xml($xml);
        amazon_item_insert($item);
        $items["{$item['asin']}"] = $item;
      }
    }
    return $items;
  }
  return array();
}
function _amazon_item_batch_lookup_from_web_errors($errors) {
  foreach ($errors->Error as $error) {
    $code = (string) $error->Code;
    $message = (string) $error->Message;
    $matches = array();
    
    if (preg_match('/^([^ ]+) is not a valid value for ItemId/', $message, $matches)) {
      $error_asin = $matches[1];
      $update_fields = array(
        'invalid_asin' => TRUE,
      );
      try {
        $result = db_update('amazon_item')
          ->fields($update_fields)
          ->condition('asin', $error_asin)
          ->execute();
      } catch (Exception $e) {
        amazon_db_error_watchdog('Failed to update invalid_asin=TRUE on amazon_item.', $e);
      }
    }
    watchdog('amazon', 'Error retrieving Amazon item %code, message: %message.', array(
      '%code' => $code,
      '%message' => $message,
    ), WATCHDOG_WARNING);
  }
}
function amazon_item_lookup_from_db($item_ids = array()) {
  if (!empty($item_ids)) {
    $timestamp = REQUEST_TIME - variable_get('amazon_refresh_schedule', 86400);
    $result = db_query('SELECT * from {amazon_item} WHERE asin IN (:asins) AND timestamp > :timestamp', array(
      ':asins' => $item_ids,
      ':timestamp' => $timestamp,
    ), array(
      'fetch' => PDO::FETCH_ASSOC,
    ));
    $items = array();
    foreach ($result as $item) {
      _amazon_load_child_data($item);
      $item += module_invoke_all('amazon_item_load', $item);
      $items["{$item['asin']}"] = $item;
    }
    return $items;
  }
  return array();
}
function _amazon_load_child_data(&$item) {
  $result = db_query('SELECT type, participant FROM {amazon_item_participant} WHERE asin = :asin', array(
    ':asin' => $item['asin'],
  ), array(
    'fetch' => PDO::FETCH_ASSOC,
  ));
  foreach ($result as $participant) {
    
    $item[$participant['type']][] = $participant['participant'];
    $item['participants'][] = $participant['participant'];
  }
  $result = db_query('SELECT * FROM {amazon_item_image} WHERE asin = :asin', array(
    ':asin' => $item['asin'],
  ), array(
    'fetch' => PDO::FETCH_ASSOC,
  ));
  foreach ($result as $image) {
    unset($image['asin']);
    $item['imagesets'][$image['size']] = $image;
  }
  $result = db_query('SELECT * FROM {amazon_item_editorial_review} WHERE asin = :asin', array(
    ':asin' => $item['asin'],
  ), array(
    'fetch' => PDO::FETCH_ASSOC,
  ));
  foreach ($result as $review) {
    unset($review['asin']);
    $item['editorialreviews'][] = $review;
  }
}
function amazon_item_clean_xml($xml) {
  $metadata = amazon_data_cache();
  $item = array();
  
  $item['asin'] = (string) $xml->ASIN;
  if (!empty($xml->ItemAttributes->ISBN)) {
    $item['isbn'] = (string) $xml->ItemAttributes->ISBN;
  }
  if (!empty($xml->ItemAttributes->EAN)) {
    $item['ean'] = (string) $xml->ItemAttributes->EAN;
  }
  $item['salesrank'] = intval($xml->SalesRank);
  $item['detailpageurl'] = (string) $xml->DetailPageURL;
  if (!empty($xml->ItemAttributes->ListPrice)) {
    $item['listpriceamount'] = intval($xml->ItemAttributes->ListPrice->Amount);
    $item['listpricecurrencycode'] = (string) $xml->ItemAttributes->ListPrice->CurrencyCode;
    $item['listpriceformattedprice'] = (string) $xml->ItemAttributes->ListPrice->FormattedPrice;
  }
  if (!empty($xml->OfferSummary->LowestNewPrice)) {
    
    $item['lowestpriceamount'] = intval($xml->OfferSummary->LowestNewPrice->Amount);
    $item['lowestpricecurrencycode'] = (string) $xml->OfferSummary->LowestNewPrice->CurrencyCode;
    $item['lowestpriceformattedprice'] = (string) $xml->OfferSummary->LowestNewPrice->FormattedPrice;
  }
  
  if (!empty($xml->Offers->Offer[0]->OfferListing->Price)) {
    $item['amazonpriceamount'] = intval($xml->Offers->Offer[0]->OfferListing->Price->Amount);
    $item['amazonpricecurrencycode'] = (string) $xml->Offers->Offer[0]->OfferListing->Price->CurrencyCode;
    $item['amazonpriceformattedprice'] = (string) $xml->Offers->Offer[0]->OfferListing->Price->FormattedPrice;
  }
  $participant_types = preg_split('/,/', AMAZON_PARTICIPANT_TYPES);
  
  foreach ((array) $xml->ItemAttributes as $key => $value) {
    if (is_string($value) && !in_array($key, $participant_types)) {
      $key = strtolower($key);
      $item[$key] = $value;
    }
  }
  
  foreach ($participant_types as $key) {
    if (isset($xml->ItemAttributes->{$key})) {
      foreach ($xml->ItemAttributes->{$key} as $value) {
        $item[strtolower($key)][] = (string) $value;
        $item['participants'][] = (string) $value;
      }
    }
  }
  
  $supported_sizes = preg_split('/,/', AMAZON_IMAGE_SIZES);
  if (isset($xml->ImageSets->ImageSet)) {
    foreach ((array) $xml->ImageSets->ImageSet as $key => $data) {
      if (in_array($key, $supported_sizes)) {
        $item['imagesets'][strtolower($key)] = array(
          'url' => (string) $data->URL,
          'height' => intval($data->Height),
          'width' => intval($data->Width),
        );
      }
    }
  }
  
  if (isset($xml->EditorialReviews)) {
    foreach ($xml->EditorialReviews->EditorialReview as $data) {
      $item['editorialreviews'][] = array(
        'source' => (string) $data->Source,
        'content' => (string) $data->Content,
      );
    }
  }
  
  if (isset($xml->CustomerReviews)) {
    $item['customerreviews_iframe'] = (string) $xml->CustomerReviews->IFrameURL;
  }
  
  foreach (module_implements('amazon_item_clean_xml') as $module) {
    $function = $module . '_amazon_item_clean_xml';
    $function($item, $xml);
  }
  return $item;
}
function amazon_item_insert($item) {
  static $item_keys = NULL;
  if (empty($item_keys)) {
    require_once 'amazon.install';
    $schema = amazon_schema();
    $item_keys = $schema['amazon_item']['fields'];
  }
  
  amazon_item_delete($item['asin']);
  $metadata = amazon_data_cache();
  $item['timestamp'] = REQUEST_TIME;
  
  $db_item = array_intersect_key($item, $item_keys);
  
  $replacements = array(
    '%7E' => '~',
    '%3D' => '=',
    '%3A' => ':',
    '%2C' => ',',
    '%2F' => '/',
    '%26' => '&',
    '%3F' => '?',
  );
  if (isset($db_item['detailpageurl'])) {
    $db_item['detailpageurl'] = str_replace(array_keys($replacements), $replacements, $db_item['detailpageurl']);
  }
  if (isset($db_item['customerreviews_iframe'])) {
    $db_item['customerreviews_iframe'] = str_replace(array_keys($replacements), $replacements, $db_item['customerreviews_iframe']);
  }
  try {
    db_insert('amazon_item')
      ->fields($db_item)
      ->execute();
  } catch (Exception $e) {
    amazon_db_error_watchdog("Failed to insert item into amazon_item table", $e, $db_item);
  }
  
  if (in_array('creators', variable_get('amazon_core_data', array(
    'creators',
    'images',
  )))) {
    $participant_types = preg_split('/,/', AMAZON_PARTICIPANT_TYPES);
    foreach ($participant_types as $type) {
      if (isset($item[strtolower($type)])) {
        foreach ((array) $item[strtolower($type)] as $participant) {
          $item_participant = array(
            'asin' => $item['asin'],
            'type' => strtolower($type),
            'participant' => $participant,
          );
          try {
            db_insert('amazon_item_participant')
              ->fields($item_participant)
              ->execute();
          } catch (Exception $e) {
            amazon_db_error_watchdog("Failed to insert item into amazon_item_participant table", $e, $item_participant);
          }
        }
      }
    }
  }
  
  if (in_array('images', variable_get('amazon_core_data', array(
    'creators',
    'images',
  )))) {
    if (isset($item['imagesets'])) {
      foreach ($item['imagesets'] as $size => $data) {
        $image = array(
          'asin' => $item['asin'],
          'size' => $size,
          'height' => $data['height'],
          'width' => $data['width'],
          'url' => $data['url'],
        );
        try {
          db_insert('amazon_item_image')
            ->fields($image)
            ->execute();
        } catch (Exception $e) {
          amazon_db_error_watchdog("Failed to insert item into amazon_item_image table", $e, $image);
        }
      }
    }
  }
  
  if (in_array('editorial_reviews', variable_get('amazon_core_data', array(
    'creators',
    'images',
    'editorial_reviews',
  )))) {
    if (isset($item['editorialreviews'])) {
      foreach ($item['editorialreviews'] as $data) {
        $review = array(
          'asin' => $item['asin'],
          'source' => $data['source'],
          'content' => $data['content'],
        );
        try {
          db_insert('amazon_item_editorial_review')
            ->fields($review)
            ->execute();
        } catch (Exception $e) {
          amazon_db_error_watchdog("Failed to insert item into amazon_item_editorial_review table", $e, $review);
        }
      }
    }
  }
  module_invoke_all('amazon_item_insert', $item);
}
function amazon_item_delete($asin) {
  module_invoke_all('amazon_item_delete', $asin);
  db_delete('amazon_item')
    ->condition('asin', $asin)
    ->execute();
  db_delete('amazon_item_participant')
    ->condition('asin', $asin)
    ->execute();
  db_delete('amazon_item_image')
    ->condition('asin', $asin)
    ->execute();
  db_delete('amazon_item_editorial_review')
    ->condition('asin', $asin)
    ->execute();
}
function amazon_convert_to_asin($input) {
  $input = preg_replace('/-/', '', $input);
  
  if (preg_match('/^https?:/', $input)) {
    $parts = preg_split('/\\//', $input);
    $asin = $parts[5];
    
    return $asin;
  }
  
  if (strlen($input) == 13 && is_numeric($input)) {
    $asin = amazon_ean_to_asin($input);
    return $asin;
  }
  return $input;
}
function amazon_ean_to_asin($ean, $locale = NULL) {
  $asin = NULL;
  $params = array(
    'ItemId' => $ean,
    'IdType' => 'EAN',
    'SearchIndex' => 'Books',
  );
  $results = amazon_http_request('ItemLookup', $params, $locale);
  if (!empty($results->Items->Item->ASIN)) {
    $asin = (string) $results->Items->Item->ASIN;
  }
  return $asin;
}
function amazon_data_cache($reset = FALSE) {
  static $data;
  if (!isset($data) || $reset) {
    if (!$reset && ($cache = cache_get('amazon:metadata')) && !empty($cache->data)) {
      $data = $cache->data;
    }
    else {
      $data = array();
      $data['locales'] = _amazon_default_locales();
      drupal_alter('amazon_metadata', $data);
      cache_set('amazon:metadata', $data);
    }
  }
  return $data;
}
function _amazon_default_locales() {
  $locales = array();
  
  require_once drupal_get_path('module', 'amazon') . '/includes/amazon.locales.inc';
  $locales = _amazon_load_locales();
  
  drupal_alter('amazon_locales', $locales);
  return $locales;
}
function amazon_get_associate_id($locale = NULL) {
  if (!$locale) {
    $locale = variable_get('amazon_default_locale', 'US');
  }
  $cache = amazon_data_cache();
  return variable_get('amazon_locale_' . $locale . '_associate_id', $cache['locales'][$locale]['da_associate_id']);
}
function amazon_cron() {
  
  $per_cron_limit = 50;
  $needs_update_time = REQUEST_TIME - variable_get('amazon_refresh_schedule', 86400);
  $result = db_select('amazon_item', NULL, array(
    'fetch' => PDO::FETCH_ASSOC,
  ))
    ->fields('amazon_item', array(
    'asin',
  ))
    ->condition('timestamp', $needs_update_time, '<')
    ->range(0, $per_cron_limit)
    ->execute();
  $asins = $result
    ->FetchCol();
  if (!empty($asins)) {
    if ($items = amazon_item_lookup_from_web($asins)) {
      foreach ($items as $item) {
        amazon_item_insert($item);
      }
      watchdog('amazon', 'Amazon items were updated.');
    }
    else {
      watchdog('amazon', 'Amazon items could not be updated.');
    }
  }
}
function amazon_views_api() {
  return array(
    'api' => 2,
    'path' => drupal_get_path('module', 'amazon') . '/includes',
  );
}
function template_preprocess_amazon_views_view_row_item(&$vars) {
  $options = $vars['options'];
  $vars['amazon_item'] = '';
  
  $asin = $vars['row']->asin;
  $items = amazon_item_lookup($asin);
  if (empty($items[$asin])) {
    return;
  }
  else {
    $item = $items[$asin];
    $item['view'] = $vars['view'];
    $vars['amazon_item'] = $item;
    if ($options['display_format'] == 'inline') {
      $vars['content'] = theme('amazon_item_inline', array(
        'item' => $item,
        'style' => $options['display_format'],
      ));
    }
    else {
      $vars['content'] = theme('amazon_item', array(
        'item' => $item,
        'style' => $options['display_format'],
      ));
    }
  }
}
function amazon_init() {
  drupal_add_css(drupal_get_path('module', 'amazon') . '/amazon.css');
}
function amazon_db_error_watchdog($msg, $e, $extra = array()) {
  watchdog('amazon', "{$msg}: Message = %message, query= %query fields=<pre>%fields</pre>", array(
    '%message' => $e
      ->getMessage(),
    '%query' => $e->query_string,
    '%fields' => print_r($extra, TRUE),
  ));
}
function amazon_get_response_groups() {
  $response_groups = array(
    'Large',
  );
  
  drupal_alter('amazon_response_groups', $response_groups);
  return implode(',', $response_groups);
}
function amazon_expire_items(array $asins = array(), array $types = array()) {
  $query = db_update('amazon_item')
    ->fields(array(
    'timestamp' => 0,
  ));
  if (!empty($asins)) {
    $query
      ->condition('asin', $asins, 'IN');
  }
  if (!empty($types)) {
    foreach ($types as $key => $value) {
      $types[$key] = strtolower($value);
    }
    $query
      ->condition('lower(productgroup)', $types, 'IN');
  }
  $updated = $query
    ->execute();
  $update_msg = format_plural($updated, '1 Amazon Item has been expired', '@count Amazon Items have been expired');
  watchdog('amazon', $update_msg, NULL, WATCHDOG_INFO, NULL);
}
function amazon_flush_caches() {
  
  $trace = debug_backtrace(FALSE);
  while (in_array($trace[0]['function'], array(
    'amazon_flush_caches',
    'call_user_func_array',
    'module_invoke_all',
    'drupal_flush_all_caches',
  ))) {
    $foo = array_shift($trace);
  }
  
  if ($trace[0]['function'] != 'system_cron') {
    amazon_expire_items();
  }
  return array();
}