Index: amazon.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/amazon/amazon.module,v retrieving revision 1.27.2.12 diff -u -r1.27.2.12 amazon.module --- amazon.module 12 Sep 2008 23:22:20 -0000 1.27.2.12 +++ amazon.module 4 Nov 2008 03:25:14 -0000 @@ -15,6 +15,8 @@ // Other common sizes include SwatchImage, TinyImage, and ThumbnailImage. define('AMAZON_IMAGE_SIZES', 'SmallImage,MediumImage,LargeImage'); +define('AMAZON_DOS_LIMIT', 10); + /** * Implementation of hook_menu. Adds the url path for the Amazon * settings page. @@ -237,19 +239,16 @@ } } $items_from_web = amazon_item_lookup_from_web($items_to_fetch); - return array_merge($items, $items_from_web); + return $items + $items_from_web; } function amazon_item_lookup_from_web($item_ids = array()) { - // We do this to avoid bombing Amazon.com with 1000 item requests. - $amazon_limit = 10; - $asins = array(); + // We chunk requests into size AMAZON_DOS_LIMIT to avoid bombing Amazon with thousands of item requests. $results = array(); - foreach ($item_ids as $asin) { - $asins[] = $asin; - if (count($asins) >= $amazon_limit || count($asins) == count($item_ids)) { + if ($count = count($item_ids)) { + for ($start = 0; $start < $count; $start += AMAZON_DOS_LIMIT) { + $asins = array_slice($item_ids, $start, AMAZON_DOS_LIMIT); $results += _amazon_item_batch_lookup_from_web($asins); - $asins = array(); } } return $results; @@ -257,19 +256,49 @@ function _amazon_item_batch_lookup_from_web($item_ids = array()) { if (!empty($item_ids)) { - $params = array( - 'ItemId' => implode(',', $item_ids), - 'ResponseGroup' => 'Large', - ); - $results = amazon_http_request('ItemLookup', $params); - if (!empty($results->Error)) { - return FALSE; + $eans = array(); + $asins = array(); + // Partition identifiers into two groups: ASINs (10 characters) and EANs (13 characters) + foreach ($item_ids as $item_id) { + if (strlen($item_id) == 13) { + $eans[] = $item_id; + } + else { + $asins[] = $item_id; + } + } + $results = array(); + // Batch retrieve all the products identified by a 10 character ASIN + if (!empty($asins)) { + $params = array( + 'IdType' => 'ASIN', + 'ItemId' => implode(',', $asins), + 'ResponseGroup' => 'Large', + ); + $results[] = amazon_http_request('ItemLookup', $params); + } + // Batch retrieve all the products identified by a 13 character EAN + if (!empty($eans)) { + $params = array( + 'IdType' => 'EAN', + 'SearchIndex' => variable_get('amazon_locale_ean_search_index', 'Books'), + 'ItemId' => implode(',', $eans), + 'ResponseGroup' => 'Large', + ); + $results[] = amazon_http_request('ItemLookup', $params); } $items = array(); - foreach($results->Items->Item as $xml) { - $item = amazon_item_clean_xml($xml); - amazon_item_save($item); - $items[$item['asin']] = $item; + // Merge the ASIN and EAN result sets together + foreach ($results as $result) { + // Return FALSE if either result set fails + if (!empty($result->Error)) { + return FALSE; + } + foreach($result->Items->Item as $xml) { + $item = amazon_item_clean_xml($xml); + amazon_item_save($item); + $items[$item['asin']] = $item; + } } return $items; Index: amazon.admin.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/amazon/amazon.admin.inc,v retrieving revision 1.1.2.5 diff -u -r1.1.2.5 amazon.admin.inc --- amazon.admin.inc 28 Jun 2008 18:12:14 -0000 1.1.2.5 +++ amazon.admin.inc 4 Nov 2008 03:25:14 -0000 @@ -14,6 +14,64 @@ '#description' => t('Amazon.com uses separate product databases and Ecommerce features in different locales; pricing and availability information, as well as product categorization, differs from one locale to the next. Be sure to select the locale your site will be running in.'), ); + $options = array( + 'All' => 'All', + 'Apparel' => 'Apparel', + 'Automotive' => 'Automotive', + 'Baby' => 'Baby', + 'Beauty' => 'Beauty', + 'Blended' => 'Blended', + 'Books' => 'Books', + 'Classical' => 'Classical', + 'DigitalMusic' => 'DigitalMusic', + 'DVD' => 'DVD', + 'Electronics' => 'Electronics', + 'ForeignBooks' => 'ForeignBooks', + 'GourmetFood' => 'GourmetFood', + 'Grocery' => 'Grocery', + 'HealthPersonalCare' => 'HealthPersonalCare', + 'Hobbies' => 'Hobbies', + 'HomeGarden' => 'HomeGarden', + 'HomeImprovement' => 'HomeImprovement', + 'Industrial' => 'Industrial', + 'Jewelry' => 'Jewelry', + 'KindleStore' => 'KindleStore', + 'Kitchen' => 'Kitchen', + 'Magazines' => 'Magazines', + 'Merchants' => 'Merchants', + 'Miscellaneous' => 'Miscellaneous', + 'MP3Downloads' => 'MP3Downloads', + 'Music' => 'Music', + 'MusicalInstruments' => 'MusicalInstruments', + 'MusicTracks' => 'MusicTracks', + 'OfficeProducts' => 'OfficeProducts', + 'OutdoorLiving' => 'OutdoorLiving', + 'PCHardware' => 'PCHardware', + 'PetSupplies' => 'PetSupplies', + 'Photo' => 'Photo', + 'Shoes' => 'Shoes', + 'SilverMerchant' => 'SilverMerchant', + 'Software' => 'Software', + 'SoftwareVideoGames' => 'SoftwareVideoGames', + 'SportingGoods' => 'SportingGoods', + 'Tools' => 'Tools', + 'Toys' => 'Toys', + 'VHS' => 'VHS', + 'Video' => 'Video', + 'VideoGames' => 'VideoGames', + 'Watches' => 'Watches', + 'Wireless' => 'Wireless', + 'WirelessAccessories' => 'WirelessAccessories', + ); + $form['amazon_locale_ean_search_index'] = array( + '#type' => 'select', + '#title' => t('EAN search index'), + '#default_value' => variable_get('amazon_locale_ean_search_index', 'Books'), + '#options' => $options, + '#description' => t('A search index must be specified when looking up by a 13 character EAN. Amazon.com makes different search indices available in different locales. Be sure to select a search index available for your locale. Read the !amazon documentation for more. Note: the EAN search index is not used when looking up a 10 character ASIN/ISBN.', + array("!amazon" => l("Search Index Support by Locale", 'http://docs.amazonwebservices.com/AWSECommerceService/2008-08-19/DG/index.html?APPNDX_SearchIndexValues.html'))) + ); + $form['amazon_associate_setting'] = array( '#type' => 'select', '#title' => t('Amazon referral settings'), @@ -127,9 +185,15 @@ return $form; } +function amazon_test_form_validate($form, &$form_state) { + if (!preg_match("/^[0-9A-Z]{10}|[0-9A-Z]{13}$/i", $form_state['values']['asin'], $matches)) { + form_set_error('asin', t("Invalid identifier. The identifier must a valid ASIN/ISBN (exactly 10 characters long) or EAN (exactly 13 characters long).")); + } +} + function amazon_test_form_submit($form, &$form_state) { - $items = amazon_item_lookup($form_state['values']['asin']); - if (is_array($items)) { + $items = amazon_item_lookup($form_state['values']['asin'], TRUE); + if (!empty($items)) { $item = array_pop($items); amazon_item_delete($item['asin']); amazon_item_save($item); @@ -140,4 +204,7 @@ $form_state['amazon_item'] = $item; $form_state['rebuild'] = TRUE; } + else { + drupal_set_message(t("No item found with an identifier of %asin", array("%asin" => $form_state['values']['asin'])), 'error'); + } } Index: asin/asin.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/amazon/asin/asin.module,v retrieving revision 1.2.2.3 diff -u -r1.2.2.3 asin.module --- asin/asin.module 12 Sep 2008 23:22:21 -0000 1.2.2.3 +++ asin/asin.module 4 Nov 2008 03:25:14 -0000 @@ -85,16 +85,45 @@ function asin_field($op, &$node, $field, &$items, $teaser, $page) { switch ($op) { case 'validate': + // Validate both EANs and ASINs $results = _asin_load_items($items); foreach ($items as $delta => $item) { if (is_array($item)) { - if (!empty($item['asin']) && empty($results[$item['asin']])) { + // Is there a result keyed by this identifier + $found = !empty($results[$item['asin']]); + if (!$found) { + // If not, look for an EAN that matches + foreach ($results as $result) { + if ($result['ean'] == $item['asin']) { + $found = TRUE; + break; + } + } + } + if (!empty($item['asin']) && !$found) { form_set_error($field['field_name'] .']['. $delta .'][asin', t('%name : No Amazon product with the ID %id could be located.', array('%name' => t($field['widget']['label']), '%id' => $item['asin']))); } } } return $items; + case 'presave': + // Convert any EANs into their ASIN equivalents + $results = _asin_load_items($items); + foreach ($items as $delta => $item) { + if (is_array($item)) { + if (empty($results[$item['asin']])) { + foreach ($results as $result) { + if ($result['ean'] == $item['asin']) { + $items[$delta]['asin'] = $result['asin']; + break; + } + } + } + } + } + break; + case 'load': $results = _asin_load_items($items); foreach ($items as $delta => $item) {