table_options = $wpdb->prefix . "amazonfeed_options"; $this->table_cache = $wpdb->prefix . "amazonfeed_cache"; // Load Options $this->options = get_option('amazonFeedOptions'); // Default REST Parameters (can be over-ridden) $this->params = array( 'Operation' => 'ItemSearch', 'SearchIndex' => 'Books', 'ResponseGroup' => 'Small,Images' ); // If we're ready to run live, activate the controls. if( isset($this->options['ServicePath']) AND isset($this->options['AWSAccessKeyId']) AND isset($this->options['AssociateTag']) AND isset($this->options['DefaultTags']) AND isset($this->options['DefaultSearchField']) AND isset($this->options['MaxResults']) AND isset($this->options['Version']) AND function_exists('simplexml_load_string') ) { $this->live = true; } } function unInstall() { global $wpdb; $sql = "DROP TABLE `" . $this->table_cache . "`;"; $wpdb->query($sql); delete_option('amazonFeedOptions'); } function checkInstall() { global $wpdb; if(!function_exists('simplexml_load_string')) { $this->admin_alert("WARNING: This plugin currently only works on servers running PHP v 5.x or higher."); return(false); } // Plugin options are not installed, implying that the plugin itself has not yet been installed either. if(!$this->options['Version']) { $this->admin_alert("Previous installation not found. Installing necessary tables now."); $sql = "CREATE TABLE IF NOT EXISTS `" . $this->table_cache . "` ( `keyword` varchar(255) NOT NULL, `timestamp` bigint(20) unsigned zerofill NOT NULL, `data` longblob NOT NULL, PRIMARY KEY (`keyword`) );"; $result = $wpdb->query($sql); if($result === false) { $this->admin_alert("Failed to create table."); return(false); } $this->options = array( 'Locale' => 'United States', 'LocaleTipTag' => 'usamazonfeed-20', 'ServicePath' => 'http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService', 'AWSAccessKeyId' => '', 'AssociateTag' => '', 'SearchFrom' => 'categories', 'DefaultTags' => '', 'ShowOnPosts' => true, 'ShowOnPages' => true, 'ShowOnHome' => true, 'ShowOnCategories' => true, 'ShowOnTags' => true, 'ShowOnSearch' => true, 'TitleText' => '

Related Reading:

', 'DefaultSearchField'=> 'Keywords', 'MaxResults' => 5, 'ShowImages' => true, 'CacheExpiry' => 60*24, 'AllowTip' => true, 'Version' => $this->version ); update_option('amazonFeedOptions', $this->options); } elseif($this->options['Version'] < $this->version) { $this->admin_alert("Plugin files version do not match installed version. Running upgrade scripts now."); if($this->options['Version'] < '1.1') { $this->options['Version'] = '1.1'; $this->options['ShowOnPosts'] = true; $this->options['ShowOnPages'] = true; $this->options['ShowOnHome'] = true; $this->options['ShowOnCategories'] = true; $this->options['ShowOnTags'] = true; $this->options['ShowOnSearch'] = true; update_option('amazonFeedOptions', $this->options); $this->admin_alert("Plugin upgraded to v. 1.1 This version allows you to limit display of products on various categories of blog pages. Some CSS tweaks were also added."); } if($this->options['Version'] < '1.2') { $this->options['Version'] = '1.2'; $this->options['Locale'] = 'United States'; $this->options['LocaleTipTag'] = 'usamazonfeed-20'; update_option('amazonFeedOptions', $this->options); $this->admin_alert("Plugin upgraded to v. 1.2 This version allows you to select the locale from where you wish your products to be selected. Please be aware that in order to collect referral rewards, your associate account must be registered in the same locale as you are using to pull products from."); } if($this->options['Version'] < '1.3') { /* * Bug fixes * Limit hits to amazon * Select Search index to be displayed * Clear cache button * Pretty icon for notices */ $this->options['Version'] = '1.3'; if(!$this->options['SearchIndex']) $this->options['SearchIndex'] = $this->params['SearchIndex']; update_option('amazonFeedOptions', $this->options); $this->admin_alert("Plugin upgraded to v. 1.3 -- Tired of promoting just books? This version gives you access to promote many different types of products from Amazon. Simply check off the products you would like to promote in the Items to Feature field below."); } return(true); } } // Allow showing an alert to the user when necessary. function admin_alert($msg = '') { if($msg) echo "

$msg

"; } function debug($msg = '') { # echo "
"; print_r($msg); echo "
"; } function getpath($path, $username = false, $password = false) { $this->debug("Using built-in function to load data. Slower, but should work."); // Test URL and ensure that it is valid. if(false !== $username AND false !== $password) $match = "^([a-z]{2,10})\://" . $username . "\:" . $password . "([a-z0-9\.\-]+)/?([^\?]*)(.*)$"; else $match = "^([a-z]{2,10})\://([a-z0-9\.\-]+)(/?[^\?]*)(.*)$"; // Return false if the path does not look like a url. if(!eregi($match, $path, $regs)) { return(false); } else { list($path, $protocol, $hostname, $request, $query) = $regs; // Determine port protocol. switch(strtoupper($protocol)) { case "HTTPS": $port = 443; break; case "FTP": $port = 21; break; default: $port = 80; break; } } // Load url data $fp = fsockopen($hostname, $port, $errno, $errstr, 10); if (!$fp) { echo "$errstr ($errno)
\n"; return(false); } else { $out = "GET " . $request . $query . " HTTP/1.0\r\n"; $out .= "Host: $hostname\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); unset($data); while (!feof($fp)) { $data .= fgets($fp); } fclose($fp); $data_start = strpos($data, "\r\n\r\n"); $header = substr($data, 0, $data_start); $body = substr($data, $data_start + 4, strlen($data)); $regs = ""; if(eregi("[\r\n]+Location\: *([^\r\n]+)", $header, $regs) AND eregi("HTTP/[0-9]*\.[0-9]*[ ]*3[0-9]{2}", $header)) { $location = $regs[1]; return($this->getpath($location)); } else { return($body); } } } // Main data loader. function request_data($new_params = array()) { // Only run a request from Amazon once per page load in order to comply with amazon regs. if($this->done_request == true) { $this->debug("Do not run request for '" . implode(",", $new_params) . "' in order to comply " . "with Amazon speed limit regulations"); return(false); } if($this->options['SearchIndex']) $this->params['SearchIndex'] = $this->options['SearchIndex']; // Update the options with anything passed on the function. $params = array_merge($this->params, $new_params); // Create the request $request = $this->options['ServicePath'] . "&AWSAccessKeyId=" . $this->options['AWSAccessKeyId'] . "&AssociateTag=" . $this->options['AssociateTag']; // Iterate through the parameters adding to the request. foreach($params as $key=>$param) { if($param != "") { $request .= "&" . $key . "=" . $param; } } $this->debug("Running Request: $request
"); if(function_exists('file_get_contents')) $xml_data = file_get_contents($request); else { $xml_data = $this->getpath($request); } $this->done_request = true; if($xml_data) return($xml_data); } // Load related reading either from database table, or from Amazon.com function load($keyword) { global $wpdb; $keyword = addslashes($keyword); $sql = "SELECT * FROM " . $this->table_cache . " WHERE `keyword` = '" . $keyword . "' LIMIT 0,1"; $data = $wpdb->get_row($sql, ARRAY_A); if($data !== false AND $data['keyword'] != "") { $data['keyword'] = stripslashes($data['keyword']); $data['data'] = stripslashes($data['data']); return($data); } } // Save related reading to cache when necessary function save($keyword, $xml) { global $wpdb; $keyword = trim(addslashes($keyword)); $data = trim(addslashes($xml)); $timestamp = time() + ($this->options['CacheExpiry']*60); $sql = "SELECT * FROM " . $this->table_cache . " WHERE `keyword` = '" . $keyword . "' LIMIT 0,1"; $existing_data = $wpdb->get_row($sql, ARRAY_A); if($existing_data['keyword'] != "") $sql = "UPDATE " . $this->table_cache . " SET `timestamp` = '$timestamp', `data` = '$data' WHERE `keyword` = '" . $keyword . "' LIMIT 1;"; else $sql = "INSERT INTO " . $this->table_cache . " (`keyword`, `timestamp`, `data`) VALUES ('$keyword', '$timestamp', '$data');"; $results = $wpdb->query($sql); return; } // Specific search functions function search($search_keywords, $searchResults=false, $searchField=false, $searchIndex=false) { global $wpdb; $this->debug("Searching For: $search_keywords
\n"); if($searchResults == false) $searchResults = $this->options['MaxResults']; if($searchField == false) $searchField = $this->options['DefaultSearchField']; if($searchIndex == false) $searchIndex = $this->params['SearchIndex']; $keywords = explode(",", $search_keywords); $tmp_items = array(); foreach($keywords as $word) { if(trim($word) != "") { $data = $this->load(trim($word)); if($data['data'] != "" AND $data['timestamp'] > time()) { $xml_data = $data['data']; } else { $new_params = array( $searchField => urlencode(trim($word)) ); $xml_data = $this->request_data($new_params); $this->save($word, $xml_data); } if($xml_data) { $xml = simplexml_load_string($xml_data); $counter = 0; foreach($xml->Items->Item as $item) { $tmp_items[] = $item; } } } } $items = array(); $counter = 0; while($counter++ < count($tmp_items)*2) { $rand = rand(0, count($tmp_items)-1); $tmp_item = $tmp_items[$rand]; $id = $tmp_item->ASIN; if(!$items["$id"]) $items["$id"] = $tmp_item; if(count($items) >= $searchResults) break; } return($items); } function display($keywords, $echo = true) { $items = $this->search($keywords); $numBooks = count($items); if($numBooks == 0 AND $keywords != $this->options['DefaultTags']) { $items = $this->search($this->options['DefaultTags']); $numBooks = count($items); } if($numBooks > 0) { // Allow for tipping the author, if enabled if($this->options['AllowTip'] == true) { // If there is only one result, show the author's link 50% of the time. if($numBooks == 1) $tip_random_number = rand(1, 2); else $tip_random_number = rand(1, $numBooks); } $result = "
" . stripslashes($this->options['TitleText']) . "\n"; $counter = 0; foreach($items as $item) { $result .= "
"; $counter++; $image = $item->SmallImage->URL; $title = $item->ItemAttributes->Title; $link = urldecode($item->DetailPageURL); $link_target = $this->options['LinkTarget']; // Do the tip if($this->options['AllowTip'] == true AND $counter == $tip_random_number) { $link = str_replace($this->options['AssociateTag'], $this->options['LocaleTipTag'], $link); } if($this->options['ShowImages'] == true AND trim($image) != "") $image_html = "\n "; else $image_html = ""; $result .= "$image_html$title\n"; $result .= "
"; } $result .= "

"; } if($echo) echo $result; else return($result); } function wp_head() { $filepath = basename(__FILE__); $pluginpath = str_replace("php/$filepath", "", __FILE__); $pluginlocation = get_settings('siteurl') . str_replace(ABSPATH, "/", $pluginpath); $csspath = $pluginlocation . "css/style.css"; ?> options['Version'] > '1.0') { // Check to ensure we're allowed to show on this page. if(is_single() AND !$this->options['ShowOnPosts']) return($content); if(is_page() AND !$this->options['ShowOnPages']) return($content); if((is_home()) AND !$this->options['ShowOnHome']) return($content); if(is_category() AND !$this->options['ShowOnCategories']) return($content); if(is_tag() AND !$this->options['ShowOnTags']) return($content); if(is_search() AND !$this->options['ShowOnSearch']) return($content); if(function_exists('is_front_page')) if((is_front_page()) AND !$this->options['ShowOnHome']) return($content); } // If the page has had the plugin disabled, just return the content. if( get_post_meta($post->ID, '_amazonfeed_disabled', true) == "true" ) return($content); // Check to see if we have custom keywords for the page. $custom_keywords = get_post_meta($post->ID, '_amazonfeed_keywords', true); if(!$custom_keywords) { if($this->options['SearchFrom'] == "categories") $tags = get_the_category(); else $tags = get_the_tags(); if(count($tags) == 0 OR $tags == "") { $keywords = $this->options['DefaultTags']; } else { foreach($tags as $tag) $search_string[] = $tag->name; $keywords = implode(', ', $search_string); } } else $keywords = $custom_keywords; $result = $this->display($keywords, false); $content = "$content\n$result"; return($content); } function wp_admin_init() { // Add admin management pages add_management_page('Amazon Feed Management', 'AmazonFeed', 7, __FILE__, array(&$this, 'wp_admin_options')); } function wp_admin_options() { // Check Installation $this->checkInstall(); // Save admin options if posted. if($_POST) { $post_errors = false; // Clear the cache database if locale has changed. if($_POST['Locale'] != $this->options['Locale']) { $_POST['ClearCacheNowv'] = 'yes'; $this->admin_alert("Locale change detected."); switch($_POST['Locale']) { case "Canada": $this->options['Locale'] = 'Canada'; $this->options['ServicePath'] = 'http://ecs.amazonaws.ca/onca/xml?Service=AWSECommerceService'; $this->options['LocaleTipTag'] = 'caamazonfeed-20'; break; case "United Kingdom": $this->options['Locale'] = 'United Kingdom'; $this->options['ServicePath'] = 'http://ecs.amazonaws.co.uk/onca/xml?Service=AWSECommerceService'; $this->options['LocaleTipTag'] = 'ukamazonfeed-21'; break; case "United States": default: $this->options['Locale'] = 'United States'; $this->options['ServicePath'] = 'http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService'; $this->options['LocaleTipTag'] = 'usamazonfeed-20'; break; } } if(eregi("^[a-z0-9\-]+$", $_POST['AWSAccessKeyId'])) $this->options['AWSAccessKeyId'] = $_POST['AWSAccessKeyId']; else { $this->admin_alert("The AWS Access Key you entered was improperly formatted."); $post_errors = true; } if(eregi("^[a-z0-9\-]+$", $_POST['AssociateTag'])) $this->options['AssociateTag'] = $_POST['AssociateTag']; else { $this->admin_alert("The Associate Tag you entered was improperly formatted."); $post_errors = true; } if(eregi("^[a-z]+$", $_POST['SearchFrom']) AND $_POST['SearchFrom'] == 'tags') $this->options['SearchFrom'] = 'tags'; else { $this->options['SearchFrom'] = 'categories'; } if(eregi("^[a-z0-9\-]+$", $_POST['ShowOnPosts']) AND $_POST['ShowOnPosts'] == 'yes') $this->options['ShowOnPosts'] = true; else { $this->options['ShowOnPosts'] = false; } if(eregi("^[a-z0-9\-]+$", $_POST['ShowOnPages']) AND $_POST['ShowOnPages'] == 'yes') $this->options['ShowOnPages'] = true; else { $this->options['ShowOnPages'] = false; } if(eregi("^[a-z0-9\-]+$", $_POST['ShowOnHome']) AND $_POST['ShowOnHome'] == 'yes') $this->options['ShowOnHome'] = true; else { $this->options['ShowOnHome'] = false; } if(eregi("^[a-z0-9\-]+$", $_POST['ShowOnCategories']) AND $_POST['ShowOnCategories'] == 'yes') $this->options['ShowOnCategories'] = true; else { $this->options['ShowOnCategories'] = false; } if(eregi("^[a-z0-9\-]+$", $_POST['ShowOnTags']) AND $_POST['ShowOnTags'] == 'yes') $this->options['ShowOnTags'] = true; else { $this->options['ShowOnTags'] = false; } if(eregi("^[a-z0-9\-]+$", $_POST['ShowOnSearch']) AND $_POST['ShowOnSearch'] == 'yes') $this->options['ShowOnSearch'] = true; else { $this->options['ShowOnSearch'] = false; } switch($_POST['SearchIndex']) { case "Music": $this->options['SearchIndex'] = 'Music'; break; case "Video": $this->options['SearchIndex'] = 'Video'; break; case "Electronics": $this->options['SearchIndex'] = 'Electronics'; break; case "Software": $this->options['SearchIndex'] = 'Software'; break; case "Blended": $this->options['SearchIndex'] = 'Blended'; break; case "All": $this->options['SearchIndex'] = 'All'; break; case "Books": default: $this->options['SearchIndex'] = 'Books'; break; } if(eregi("^.*$", $_POST['DefaultTags'])) $this->options['DefaultTags'] = $_POST['DefaultTags']; else { $this->admin_alert("The Default Tags you entered was improperly formatted."); $post_errors = true; } if(eregi("^.*$", $_POST['TitleText'])) $this->options['TitleText'] = $_POST['TitleText']; else { $this->admin_alert("The Title Text you entered was improperly formatted."); $post_errors = true; } if(eregi("^[0-9]+$", $_POST['MaxResults']) AND $_POST['MaxResults'] >= 0 AND $_POST['MaxResults'] <= 25) $this->options['MaxResults'] = $_POST['MaxResults']; else { $this->admin_alert("The Max Results must only be a number between 0 and 25."); $post_errors = true; } if($_POST['ShowImages'] == 'yes') $this->options['ShowImages'] = true; else { $this->options['ShowImages'] = false; } if($_POST['LinkTarget'] == '_blank') $this->options['LinkTarget'] = '_blank'; else { $this->options['LinkTarget'] = ''; } if(eregi("^[0-9]+$", $_POST['CacheExpiry']) AND $_POST['CacheExpiry'] >= 1 AND $_POST['CacheExpiry'] <= 43200) $this->options['CacheExpiry'] = $_POST['CacheExpiry']; else { $this->admin_alert("The Cache Expiry Minutes must only be a number between 15 and 43200 (30 days)."); $post_errors = true; } if(eregi("^[a-z0-9\-]+$", $_POST['ClearCacheNow']) AND $_POST['ClearCacheNow'] == 'yes') { $sql = "TRUNCATE " . $this->table_cache; global $wpdb; $wpdb->query($sql); $this->admin_alert("The database cache has been cleared of all items."); } if(eregi("^[a-z0-9\-]+$", $_POST['AllowTip']) AND $_POST['AllowTip'] == 'yes') { if($this->options['AllowTip'] == false) $this->admin_alert("Thank you for your generosity."); $this->options['AllowTip'] = true; } else { $this->options['AllowTip'] = false; } if(!$post_errors) { // Save current options update_option('amazonFeedOptions', $this->options); $this->admin_alert("Options saved!"); } } // Show default admin page ?>

Amazon Feed Management

Select Locale:
If you reside in or wish to display products from a country other than the US (amazon.com) site, you can select your locale here. Please be aware that in order to collect referral rewards, your associate account must be registered in the same locale as you are using to pull products from.
AWS Access Key:
The access key you applied for and received from the Amazon Web Services site.
' />
Associate Tag:
Your Amazon associate tag which you received when you signed up as an Amazon associate.
' />
Search Based On:
Enter a couple default tags seperated by commas to be used on articles not having any specific tags. (used to find products related to these tags)
Show On:
Select which areas of your blog you wish these items to be displayed on.
options['ShowOnPosts'] == true) echo "checked"; ?> /> Posts
options['ShowOnPages'] == true) echo "checked"; ?> /> Pages
options['ShowOnHome'] == true) echo "checked"; ?> /> Home
options['ShowOnCategories'] == true) echo "checked"; ?> /> Categories
options['ShowOnTags'] == true) echo "checked"; ?> /> Tags
options['ShowOnSearch'] == true) echo "checked"; ?> /> Search
Search Index:
Select what types of related items you want featured on your blog. You may wish to clear the local cache after changing this in order for the changes to become visible more quickly.
options['SearchIndex'] == 'Books') echo 'checked'; ?> /> Books
options['SearchIndex'] == 'Music') echo 'checked'; ?> /> Music
options['SearchIndex'] == 'Video') echo 'checked'; ?> /> Video
options['SearchIndex'] == 'Electronics') echo 'checked'; ?> /> Electronics
options['SearchIndex'] == 'Software') echo 'checked'; ?> /> Software
options['SearchIndex'] == 'Blended') echo 'checked'; ?> /> Blended
options['SearchIndex'] == 'All') echo 'checked'; ?> /> All
Default Tags:
Enter a couple default tags seperated by commas to be used on articles not having any specific tags. (used to find products related to these tags)
' />
Title Text:
Enter the text you wish to use in the related reading title or leave it as is.
' />
Max Results:
How many products would you like to promote on each post? (maximum)
' />
Show Images:
Do you wish to show images associated with the related products?
options['ShowImages'] == true) echo "checked"; ?> /> Yes
Link Targets:
What sort of window would you like the links to open in? (ie new window? same window?)
Cache Expiry Minutes:
How many minutes would you like between when related items are refreshed from Amazon.com?
' />
Clear Cache Now:
If you wish to clear the local cache of products now, click this checkbox.
Tip the Developer:
If you find this plugin to be useful in helping you to make money with your blog, why not give a "tip" to the developer by allowing him to share a bit of the profit.

Allowing this box to be checked, will cause one of the related products to send the Amazon referral on behalf of the developer instead of using your own affiliate ID. In this way you can help to support ongoing development on this plugin.
options['AllowTip'] == true) echo "checked"; ?> /> Yes
Once you have input and saved appropriate values for these options, your site will be able to begin displaying related items on all your blog pages and posts.


ID, '_amazonfeed_disabled', true) == 'true' ) echo "checked"; ?> /> Disabled

Amazon Products Feed