Changeset 372771
- Timestamp:
- 04/14/2011 05:36:57 AM (15 years ago)
- Location:
- amazonfeed/trunk
- Files:
-
- 3 edited
-
amazonfeed.php (modified) (1 diff)
-
php/amazonfeed.class.php (modified) (2 diffs)
-
readme.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
amazonfeed/trunk/amazonfeed.php
r222264 r372771 4 4 Plugin URI: http://www.warkensoft.com/products/amazonfeed-wordpress-plugin/ 5 5 Description: Make money from your blog by advertising Amazon.com products specifically related to the topic of your posts. 6 Version: 2. 06 Version: 2.1 7 7 Author: WarkenSoft Productions 8 8 Author URI: http://warkensoft.com/ -
amazonfeed/trunk/php/amazonfeed.class.php
r372759 r372771 1 1 <?php 2 2 3 if(!class_exists("AmazonFeed")) { 4 class AmazonFeed { 5 6 // Public Fields 7 var $options; 8 var $params; 9 var $live = false; 10 var $done_request = false; 11 var $admin_notices = array(); 12 13 var $debug_mode = 'off'; 14 var $debug_lines = 100; 15 var $debug_visible = false; 16 17 var $xmlData; 18 19 var $table_cache = ""; 20 var $table_options = ""; 21 var $table_log = ""; 22 var $table_products = ""; 23 24 var $version = "2.0"; 25 26 var $validate = array(); 27 28 // Public Constructor 29 function AmazonFeed($new_params = array()) { 30 31 global $wpdb; 32 33 $this->table_options = $wpdb->prefix . "amazonfeed_options"; 34 $this->table_log = $wpdb->prefix . "amazonfeed_log"; 35 $this->table_cache = $wpdb->prefix . "amazonfeed_cache"; 36 $this->table_products = $wpdb->prefix . "amazonfeed_products"; 37 38 // Load Options 39 $this->options = get_option('amazonFeedOptions'); 40 $this->setValidation(); 41 42 if(defined('AUTH_KEY')) 43 $this->encKey = AUTH_KEY; 44 else 45 $this->encKey = ABSPATH . 'fwa CGkK-5{ao[XYn7hq7wLvDMN#^PSIZ)$19lPI+UpH51vD|gYe%9s)j#5E-.lu'; 46 47 // Default REST Parameters (can be over-ridden) 48 $this->params = array( 49 'Operation' => 'ItemSearch', 50 'SearchIndex' => 'Books', 51 'ResponseGroup' => 'Medium,Images' 52 ); 53 54 // If we're ready to run live, activate the controls. 55 if( isset($this->options['ServicePath']) 56 AND isset($this->options['AWSAccessKeyId']) 57 AND ( 58 isset($this->options['AWSSecretAccessKeyId']) 59 OR time() < 1250294400 60 ) 61 AND isset($this->options['AssociateTag']) 62 AND isset($this->options['DefaultTags']) 63 AND isset($this->options['DefaultSearchField']) 64 AND isset($this->options['MaxResults']) 65 AND isset($this->options['Version']) 66 AND function_exists('simplexml_load_string') ) 67 { 68 $this->live = true; 69 } 70 71 } 72 73 /** 74 * Define the validation parameters used to check submitted admin form code. 75 */ 76 function setValidation() 3 if(!class_exists("AmazonFeed")) 4 { 5 class AmazonFeed 77 6 { 78 $this->validate['SortBy'] = array( 79 'random' => true, 80 'salesrank' => true, 81 '-salesrank' => true, 82 'listprice' => true, 83 '-listprice' => true 84 ); 85 86 $this->validate['DisplayPosition'] = array( 87 '0' => true, 88 '1' => true 89 ); 90 91 92 } 93 94 function checkInstall($autoInstall = false) 95 { 96 // Plugin options are not installed, implying that the plugin itself has not yet been installed either. 97 if(!isset($this->options['Version']) OR $this->options['Version'] < $this->version) 98 { 99 if($autoInstall) return($this->doInstall()); 100 else 101 { 102 if(!strpos($_SERVER['REQUEST_URI'], 'amazonfeed/php/amazonfeed.class.php')) 103 $this->admin_notices[] = 'AmazonFeed is almost ready. Please visit the management page (Tools > AmazonFeed) to complete the ' . 104 'installation process and enter your Amazon credentials.'; 105 return(false); 106 } 107 } 108 else 109 return(true); 110 } 111 112 function unInstall() 113 { 114 global $wpdb; 115 $sql = "DROP TABLE `" . $this->table_cache . "`;"; 116 $wpdb->query($sql); 117 118 $sql = "DROP TABLE `" . $this->table_log . "`;"; 119 $wpdb->query($sql); 120 121 delete_option('amazonFeedOptions'); 122 } 123 124 function doInstall() 125 { 126 global $wpdb; 127 128 if(!function_exists('simplexml_load_string')) { 129 $this->admin_alert("WARNING: AmazonFeed currently only works on servers running PHP v 5.x or higher."); 130 return(false); 131 } 132 133 // Plugin options are not installed, implying that the plugin itself has not yet been installed either. 134 if(!isset($this->options['Version'])) { 135 136 $this->admin_alert("Previous installation not found. Installing necessary tables now."); 137 138 $sql = "CREATE TABLE IF NOT EXISTS `" . $this->table_cache . "` ( 139 `keyword` varchar(255) NOT NULL, 140 `timestamp` bigint(20) unsigned zerofill NOT NULL, 141 `data` longblob NOT NULL, 142 `blocked` blob NOT NULL, 143 PRIMARY KEY (`keyword`) 144 ) ENGINE = MYISAM ;"; 145 $result = $wpdb->query($sql); 146 if($result === false) { 147 $this->admin_alert("Failed to create table `" . $this->table_cache . "`."); 148 return(false); 149 } 150 151 $sql = "CREATE TABLE IF NOT EXISTS `" . $this->table_log . "` ( 152 `id` bigint(20) NOT NULL auto_increment, 153 `timestamp` bigint(20) unsigned zerofill NOT NULL, 154 `message` text NOT NULL, 155 PRIMARY KEY (`id`), 156 KEY `timestamp` (`timestamp`) 157 ) ENGINE=MyISAM ;"; 158 $result = $wpdb->query($sql); 159 if($result === false) { 160 $this->admin_alert("Failed to create table `" . $this->table_log . "`."); 161 return(false); 162 } 163 164 $sql = "CREATE TABLE IF NOT EXISTS `" . $this->table_products . "` ( 165 `id` bigint(20) unsigned zerofill NOT NULL auto_increment, 166 `cache_id` varchar(255) NOT NULL, 167 `data` longblob NOT NULL, 168 `asin` varchar(255) NOT NULL, 169 `blocked` tinyint(1) NOT NULL, 170 `sticky` tinyint(1) NOT NULL, 171 PRIMARY KEY (`id`) 172 ) ENGINE=MyISAM;"; 173 $result = $wpdb->query($sql); 174 if($result === false) { 175 $this->admin_alert("Failed to create table `" . $this->table_products . "`."); 176 return(false); 177 } 178 179 $this->options = array( 180 'Locale' => 'United States', 181 'LocaleTipTag' => 'usamazonfeed-20', 182 'ServicePath' => 'http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService', 183 'AWSAccessKeyId' => '', 184 'AssociateTag' => '', 185 'SearchFrom' => 'categories', 186 'DefaultTags' => '', 187 'ShowOnPosts' => true, 188 'ShowOnPages' => true, 189 'ShowOnHome' => true, 190 'ShowOnCategories' => true, 191 'ShowOnTags' => true, 192 'ShowOnSearch' => true, 193 'TitleText' => '<h3>Related Reading:</h3>', 194 'DefaultSearchField'=> 'Keywords', 195 'MaxResults' => 5, 196 'ShowText' => true, 197 'ShowImages' => true, 198 'CacheExpiry' => 60*24, 199 'AllowTip' => true, 200 'StyleSheet' => 'style.css', 201 'WidgetOptions' => array( 202 'Title' => false, 203 'DefaultTags' => false), 204 'Version' => $this->version 205 ); 206 update_option('amazonFeedOptions', $this->options); 207 } 208 elseif($this->options['Version'] < $this->version) 209 { 210 $this->admin_alert("Plugin files version do not match installed version. Running upgrade scripts now."); 211 if($this->options['AllowTip'] != true) $this->admin_alert("I notice you don't have the 'Tip' option enabled. If you'd like to help " . 212 "support the ongoing development of this plugin, you can find that option under the 'Options->Display' tab. This code has " . 213 "taken a lot of time, research and hard work to develop, and enabling the tip option is a nice way you could say thank you."); 214 215 if($this->options['Version'] < '1.1') 216 { 217 $this->options['Version'] = '1.1'; 218 219 $this->options['ShowOnPosts'] = true; 220 $this->options['ShowOnPages'] = true; 221 $this->options['ShowOnHome'] = true; 222 $this->options['ShowOnCategories'] = true; 223 $this->options['ShowOnTags'] = true; 224 $this->options['ShowOnSearch'] = true; 225 226 update_option('amazonFeedOptions', $this->options); 227 $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."); 228 } 229 230 if($this->options['Version'] < '1.2') 231 { 232 $this->options['Version'] = '1.2'; 233 234 $this->options['Locale'] = 'United States'; 235 $this->options['LocaleTipTag'] = 'usamazonfeed-20'; 236 237 update_option('amazonFeedOptions', $this->options); 238 $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."); 239 } 240 241 if($this->options['Version'] < '1.3') 242 { 243 /* 244 * Bug fixes 245 * Limit hits to amazon 246 * Select Search index to be displayed 247 * Clear cache button 248 * Pretty icon for notices 249 */ 250 $this->options['Version'] = '1.3'; 251 if(!$this->options['SearchIndex']) $this->options['SearchIndex'] = $this->params['SearchIndex']; 252 253 update_option('amazonFeedOptions', $this->options); 254 $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."); 255 } 256 257 if($this->options['Version'] < '1.4') 258 { 259 /* 260 * Updates to Amazon security and authentication protocol. 261 */ 262 $this->options['Version'] = '1.4'; 263 update_option('amazonFeedOptions', $this->options); 264 $this->admin_alert("Plugin upgraded to v. 1.4 -- Updated to support new Amazon security protocols. You will need to enter your AWS Secret Access Key in the appropriate field below."); 265 } 266 267 if($this->options['Version'] < '1.5') 268 { 269 /* 270 * Minor bug fixes and tweaks. 271 */ 272 $this->options['Version'] = '1.5'; 273 update_option('amazonFeedOptions', $this->options); 274 $this->admin_alert("Plugin upgraded to v. 1.5 -- Minor bug fixes and tweaks to support a wider range of Amazon keys."); 275 } 276 277 if($this->options['Version'] < '1.6') 278 { 279 /* 280 * Minor bug fixes and tweaks. 281 */ 282 $this->options['Version'] = '1.6'; 283 $this->options['StyleSheet'] = 'style.css'; 284 $this->options['ShowText'] = true; 285 update_option('amazonFeedOptions', $this->options); 286 $this->admin_alert("Plugin upgraded to v. 1.6<br/>" . 287 "Minor bug fixes when zero results are returned.<br/>" . 288 "Better admin screen organization.<br/>" . 289 "Upgraded admin security.<br/>" . 290 "Allowed display of only images or only text.<br/>" . 291 "Allowed for custom stylesheets.<br/><br/>" . 292 "NOTE: If products are not showing on your blog, you may need to clear the built-in product cache."); 293 } 294 295 if($this->options['Version'] < '1.7') 296 { 297 /* 298 * Minor bug fixes and tweaks. 299 */ 300 $this->options['Version'] = '1.7'; 301 update_option('amazonFeedOptions', $this->options); 302 $this->admin_alert("Plugin upgraded to v. 1.7<br/>" . 303 "Expanded debugging and error control.<br/>" . 304 "Allowed display of cached Amazon data in admin console."); 305 } 306 307 if($this->options['Version'] < '1.8') 308 { 309 /* 310 * Changing error logging to use separate table, rather than wp-options. 311 */ 7 // Public Fields 8 var $options; 9 var $params; 10 var $live = false; 11 var $done_request = false; 12 var $admin_notices = array(); 13 14 var $debug_mode = 'off'; 15 var $debug_lines = 100; 16 var $debug_visible = false; 17 18 var $xmlData; 19 20 var $table_cache = ""; 21 var $table_options = ""; 22 var $table_log = ""; 23 var $table_products = ""; 24 25 var $version = "2.1"; 26 27 var $validate = array(); 28 29 // Public Constructor 30 function AmazonFeed($new_params = array()) { 31 32 global $wpdb; 33 34 $this->table_options = $wpdb->prefix . "amazonfeed_options"; 35 $this->table_log = $wpdb->prefix . "amazonfeed_log"; 36 $this->table_cache = $wpdb->prefix . "amazonfeed_cache"; 37 $this->table_products = $wpdb->prefix . "amazonfeed_products"; 38 39 // Load Options 40 $this->options = get_option('amazonFeedOptions'); 41 $this->setValidation(); 42 43 if(defined('AUTH_KEY')) 44 $this->encKey = AUTH_KEY; 45 else 46 $this->encKey = ABSPATH . 'fwa CGkK-5{ao[XYn7hq7wLvDMN#^PSIZ)$19lPI+UpH51vD|gYe%9s)j#5E-.lu'; 47 48 // Default REST Parameters (can be over-ridden) 49 $this->params = array( 50 'Operation' => 'ItemSearch', 51 'SearchIndex' => 'Books', 52 'ResponseGroup' => 'Medium,Images' 53 ); 54 55 // If we're ready to run live, activate the controls. 56 if( isset($this->options['ServicePath']) 57 AND isset($this->options['AWSAccessKeyId']) 58 AND ( 59 isset($this->options['AWSSecretAccessKeyId']) 60 OR time() < 1250294400 61 ) 62 AND isset($this->options['AssociateTag']) 63 AND isset($this->options['DefaultTags']) 64 AND isset($this->options['DefaultSearchField']) 65 AND isset($this->options['MaxResults']) 66 AND isset($this->options['Version']) 67 AND function_exists('simplexml_load_string') ) 68 { 69 $this->live = true; 70 } 71 72 } 73 74 /** 75 * Define the validation parameters used to check submitted admin form code. 76 */ 77 function setValidation() 78 { 79 $this->validate['SortBy'] = array( 80 'random' => true, 81 'salesrank' => true, 82 '-salesrank' => true, 83 'listprice' => true, 84 '-listprice' => true 85 ); 86 87 $this->validate['DisplayPosition'] = array( 88 '0' => true, 89 '1' => true 90 ); 91 92 93 } 94 95 function checkInstall($autoInstall = false) 96 { 97 // Plugin options are not installed, implying that the plugin itself has not yet been installed either. 98 if(!isset($this->options['Version']) OR $this->options['Version'] < $this->version) 99 { 100 if($autoInstall) return($this->doInstall()); 101 else 102 { 103 if(!strpos($_SERVER['REQUEST_URI'], 'amazonfeed/php/amazonfeed.class.php')) 104 $this->admin_notices[] = 'AmazonFeed is almost ready. Please visit the management page (Tools > AmazonFeed) to complete the ' . 105 'installation process and enter your Amazon credentials.'; 106 return(false); 107 } 108 } 109 else 110 return(true); 111 } 112 113 function unInstall() 114 { 115 global $wpdb; 116 $sql = "DROP TABLE `" . $this->table_cache . "`;"; 117 $wpdb->query($sql); 118 119 $sql = "DROP TABLE `" . $this->table_log . "`;"; 120 $wpdb->query($sql); 121 122 delete_option('amazonFeedOptions'); 123 } 124 125 function doInstall() 126 { 127 global $wpdb; 128 129 if(!function_exists('simplexml_load_string')) { 130 $this->admin_alert("WARNING: AmazonFeed currently only works on servers running PHP v 5.x or higher."); 131 return(false); 132 } 133 134 // Plugin options are not installed, implying that the plugin itself has not yet been installed either. 135 if(!isset($this->options['Version'])) { 136 137 $this->admin_alert("Previous installation not found. Installing necessary tables now."); 138 139 $sql = "CREATE TABLE IF NOT EXISTS `" . $this->table_cache . "` ( 140 `keyword` varchar(255) NOT NULL, 141 `timestamp` bigint(20) unsigned zerofill NOT NULL, 142 `data` longblob NOT NULL, 143 `blocked` blob NOT NULL, 144 PRIMARY KEY (`keyword`) 145 ) ENGINE = MYISAM ;"; 146 $result = $wpdb->query($sql); 147 if($result === false) { 148 $this->admin_alert("Failed to create table `" . $this->table_cache . "`."); 149 return(false); 150 } 151 312 152 $sql = "CREATE TABLE IF NOT EXISTS `" . $this->table_log . "` ( 313 153 `id` bigint(20) NOT NULL auto_increment, … … 316 156 PRIMARY KEY (`id`), 317 157 KEY `timestamp` (`timestamp`) 318 ) ENGINE=MyISAM ;"; 319 $result = $wpdb->query($sql); 158 ) ENGINE=MyISAM ;"; 159 $result = $wpdb->query($sql); 320 160 if($result === false) { 321 $this->admin_alert("Failed to create table `" . $this->table_log . "`."); 322 return(false); 323 } 324 325 $this->options['WidgetOptions'] = array( 326 'Title' => false, 327 'DefaultTags' => false); 328 329 330 $this->options['ImageSize'] = ''; 331 332 $this->options['Version'] = '1.8'; 333 unset($this->options['error_log']); 334 update_option('amazonFeedOptions', $this->options); 335 $this->admin_alert("Plugin upgraded to v. 1.8<br/>" . 336 "Added sidebar Widget controls.<br/>" . 337 "Enabled display of product descriptions.<br/>" . 338 "Updated display CSS for better theme compatibility.<br/>" . 339 "Expanded debugging and error control.<br/>" . 340 ""); 341 } 342 343 if($this->options['Version'] < '1.9') 344 { 345 $this->options['SortBy'] = 'random'; 346 $this->options['DisplayPosition'] = '0'; 347 348 $sql = "ALTER TABLE `" . $this->table_cache . "` ADD `blocked` BLOB NOT NULL"; 349 $result = $wpdb->query($sql); 161 $this->admin_alert("Failed to create table `" . $this->table_log . "`."); 162 return(false); 163 } 164 165 $sql = "CREATE TABLE IF NOT EXISTS `" . $this->table_products . "` ( 166 `id` bigint(20) unsigned zerofill NOT NULL auto_increment, 167 `cache_id` varchar(255) NOT NULL, 168 `data` longblob NOT NULL, 169 `asin` varchar(255) NOT NULL, 170 `blocked` tinyint(1) NOT NULL, 171 `sticky` tinyint(1) NOT NULL, 172 PRIMARY KEY (`id`) 173 ) ENGINE=MyISAM;"; 174 $result = $wpdb->query($sql); 350 175 if($result === false) { 351 $this->admin_alert("Failed to create table `" . $this->table_log . "`."); 352 return(false); 353 } 354 355 $this->options['Version'] = '1.9'; 356 update_option('amazonFeedOptions', $this->options); 357 $this->admin_alert("Plugin upgraded to v. " . $this->options['Version'] . "<br/>" . 358 "Added ability to sort results on the whole blog, as well as on individual posts.<br/>" . 359 "Added ability to chose display position relative to page/post content.<br/>" . 360 "Reworked product caching for more robust storage and more advanced potential future features.<br/>" . 361 "Added ability to block specific products from being displayed.<br/>" . 362 ""); 363 } 364 365 if($this->options['Version'] < '2.0') 366 { 367 $this->options['Version'] = '2.0'; 368 update_option('amazonFeedOptions', $this->options); 369 $this->admin_alert("Plugin upgraded to v. " . $this->options['Version'] . "<br/>" . 370 "Removed Amazon products from appearing in blog feeds in order to better comply with Amazon regulations.<br/>" . 371 ""); 372 } 373 374 return(true); 375 } 376 } 377 378 // Function to show notices using the built-in wp controls when appropriate. 379 function wp_admin_notices() 380 { 381 foreach($this->admin_notices as $msg) 382 { 383 $this->admin_alert($msg); 384 $this->debug($msg); 385 } 386 } 387 388 // Allow showing an alert to the user when necessary. 389 function admin_alert($msg = '', $log = true) 390 { 391 if($msg) echo "<div class='updated' id='amazonFeedAlert'><p><img src='http://www.warkensoft.com/images/aicon.png' width='18' height='18' align='absmiddle' /><strong>$msg</strong></p></div>"; 392 if($log) $this->debug($msg); 393 } 394 395 function error_handler($errno, $errstr, $errfile=false, $errline=false) 396 { 397 $msg = 'PHP Error: ' . $errstr; 398 399 switch($errno) 400 { 401 case E_ERROR: 402 case E_USER_ERROR: 403 $this->debug($msg); 404 die(); 405 break; 406 407 case E_WARNING: 408 case E_USER_WARNING: 409 $this->debug($msg); 410 break; 411 412 default: 413 break; 414 } 415 } 416 417 // Allow limited logging of errors. 418 function log_error($msg = '') 419 { 420 if(!isset($this->options['Version'])) return; 421 422 // Legacy code to support error logging until upgrade can complete. 423 if($this->options['Version'] < '1.8') 424 { 425 if(!is_array($this->options['error_log'])) $this->options['error_log'] = array(); 426 array_unshift($this->options['error_log'], date('F j, Y, g:i a ') . $msg); 427 if(count($this->options['error_log']) > 100) 428 { 429 array_pop($this->options['error_log']); 430 } 431 update_option('amazonFeedOptions', $this->options); 432 } 433 else 434 { 435 global $wpdb; 436 $sql = "INSERT INTO `" . $this->table_log . "` (`timestamp`, `message`) " . 437 "VALUES (" . 438 "'" . time() . "', " . 439 "'" . addslashes($msg) . "');"; 440 $wpdb->query($sql); 441 } 442 } 443 444 function show_error($msg = '') 445 { 446 if($this->debug_visible == true) 447 { 448 echo "\n<!-- AmazonFeed Debugging Message --><pre>$msg</pre>"; 449 } 450 } 451 452 function debug($msg = '', $level = '1') 453 { 454 455 switch($this->debug_mode) 456 { 457 case 'basic': 458 if($level <= '1') { 459 $this->log_error($msg); 460 if($this->debug_visible == true) $this->show_error($msg); 461 } 462 break; 463 464 case 'all': 465 if($level <= '2') { 466 $this->log_error($msg); 467 if($this->debug_visible == true) $this->show_error($msg); 468 } 469 break; 470 471 default: 472 break; 473 } 474 475 } 476 477 function getpath($path, $username = false, $password = false) 478 { 479 $this->debug("Using built-in getpath function to load data. Slower, but should work."); 480 481 // Test URL and ensure that it is valid. 482 if(false !== $username AND false !== $password) 483 $match = "^([a-z]{2,10})\://" . $username . "\:" . $password . "([a-z0-9\.\-]+)/?([^\?]*)(.*)$"; 484 else 485 $match = "^([a-z]{2,10})\://([a-z0-9\.\-]+)(/?[^\?]*)(.*)$"; 486 487 // Return false if the path does not look like a url. 488 if(!eregi($match, $path, $regs)) { 489 return(false); 490 } 491 else { 492 list($path, $protocol, $hostname, $request, $query) = $regs; 493 494 // Determine port protocol. 495 switch(strtoupper($protocol)) 496 { 497 case "HTTPS": 498 $port = 443; 499 break; 500 501 case "FTP": 502 $port = 21; 503 break; 504 176 $this->admin_alert("Failed to create table `" . $this->table_products . "`."); 177 return(false); 178 } 179 180 $this->options = array( 181 'Locale' => 'United States', 182 'LocaleTipTag' => 'usamazonfeed-20', 183 'ServicePath' => 'http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService', 184 'AWSAccessKeyId' => '', 185 'AssociateTag' => '', 186 'SearchFrom' => 'categories', 187 'DefaultTags' => '', 188 'ShowOnPosts' => true, 189 'ShowOnPages' => true, 190 'ShowOnHome' => true, 191 'ShowOnCategories' => true, 192 'ShowOnTags' => true, 193 'ShowOnSearch' => true, 194 'TitleText' => '<h3>Related Reading:</h3>', 195 'DefaultSearchField'=> 'Keywords', 196 'MaxResults' => 5, 197 'ShowText' => true, 198 'ShowImages' => true, 199 'CacheExpiry' => 60*24, 200 'AllowTip' => true, 201 'StyleSheet' => 'style.css', 202 'WidgetOptions' => array( 203 'Title' => false, 204 'DefaultTags' => false), 205 'Version' => $this->version 206 ); 207 update_option('amazonFeedOptions', $this->options); 208 } 209 elseif($this->options['Version'] < $this->version) 210 { 211 $this->admin_alert("Plugin files version do not match installed version. Running upgrade scripts now."); 212 if($this->options['AllowTip'] != true) $this->admin_alert("I notice you don't have the 'Tip' option enabled. If you'd like to help " . 213 "support the ongoing development of this plugin, you can find that option under the 'Options->Display' tab. This code has " . 214 "taken a lot of time, research and hard work to develop, and enabling the tip option is a nice way you could say thank you."); 215 216 if($this->options['Version'] < '1.1') 217 { 218 $this->options['Version'] = '1.1'; 219 220 $this->options['ShowOnPosts'] = true; 221 $this->options['ShowOnPages'] = true; 222 $this->options['ShowOnHome'] = true; 223 $this->options['ShowOnCategories'] = true; 224 $this->options['ShowOnTags'] = true; 225 $this->options['ShowOnSearch'] = true; 226 227 update_option('amazonFeedOptions', $this->options); 228 $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."); 229 } 230 231 if($this->options['Version'] < '1.2') 232 { 233 $this->options['Version'] = '1.2'; 234 235 $this->options['Locale'] = 'United States'; 236 $this->options['LocaleTipTag'] = 'usamazonfeed-20'; 237 238 update_option('amazonFeedOptions', $this->options); 239 $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."); 240 } 241 242 if($this->options['Version'] < '1.3') 243 { 244 /* 245 * Bug fixes 246 * Limit hits to amazon 247 * Select Search index to be displayed 248 * Clear cache button 249 * Pretty icon for notices 250 */ 251 $this->options['Version'] = '1.3'; 252 if(!$this->options['SearchIndex']) $this->options['SearchIndex'] = $this->params['SearchIndex']; 253 254 update_option('amazonFeedOptions', $this->options); 255 $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."); 256 } 257 258 if($this->options['Version'] < '1.4') 259 { 260 /* 261 * Updates to Amazon security and authentication protocol. 262 */ 263 $this->options['Version'] = '1.4'; 264 update_option('amazonFeedOptions', $this->options); 265 $this->admin_alert("Plugin upgraded to v. 1.4 -- Updated to support new Amazon security protocols. You will need to enter your AWS Secret Access Key in the appropriate field below."); 266 } 267 268 if($this->options['Version'] < '1.5') 269 { 270 /* 271 * Minor bug fixes and tweaks. 272 */ 273 $this->options['Version'] = '1.5'; 274 update_option('amazonFeedOptions', $this->options); 275 $this->admin_alert("Plugin upgraded to v. 1.5 -- Minor bug fixes and tweaks to support a wider range of Amazon keys."); 276 } 277 278 if($this->options['Version'] < '1.6') 279 { 280 /* 281 * Minor bug fixes and tweaks. 282 */ 283 $this->options['Version'] = '1.6'; 284 $this->options['StyleSheet'] = 'style.css'; 285 $this->options['ShowText'] = true; 286 update_option('amazonFeedOptions', $this->options); 287 $this->admin_alert("Plugin upgraded to v. 1.6<br/>" . 288 "Minor bug fixes when zero results are returned.<br/>" . 289 "Better admin screen organization.<br/>" . 290 "Upgraded admin security.<br/>" . 291 "Allowed display of only images or only text.<br/>" . 292 "Allowed for custom stylesheets.<br/><br/>" . 293 "NOTE: If products are not showing on your blog, you may need to clear the built-in product cache."); 294 } 295 296 if($this->options['Version'] < '1.7') 297 { 298 /* 299 * Minor bug fixes and tweaks. 300 */ 301 $this->options['Version'] = '1.7'; 302 update_option('amazonFeedOptions', $this->options); 303 $this->admin_alert("Plugin upgraded to v. 1.7<br/>" . 304 "Expanded debugging and error control.<br/>" . 305 "Allowed display of cached Amazon data in admin console."); 306 } 307 308 if($this->options['Version'] < '1.8') 309 { 310 /* 311 * Changing error logging to use separate table, rather than wp-options. 312 */ 313 $sql = "CREATE TABLE IF NOT EXISTS `" . $this->table_log . "` ( 314 `id` bigint(20) NOT NULL auto_increment, 315 `timestamp` bigint(20) unsigned zerofill NOT NULL, 316 `message` text NOT NULL, 317 PRIMARY KEY (`id`), 318 KEY `timestamp` (`timestamp`) 319 ) ENGINE=MyISAM ;"; 320 $result = $wpdb->query($sql); 321 if($result === false) { 322 $this->admin_alert("Failed to create table `" . $this->table_log . "`."); 323 return(false); 324 } 325 326 $this->options['WidgetOptions'] = array( 327 'Title' => false, 328 'DefaultTags' => false); 329 330 331 $this->options['ImageSize'] = ''; 332 333 $this->options['Version'] = '1.8'; 334 unset($this->options['error_log']); 335 update_option('amazonFeedOptions', $this->options); 336 $this->admin_alert("Plugin upgraded to v. 1.8<br/>" . 337 "Added sidebar Widget controls.<br/>" . 338 "Enabled display of product descriptions.<br/>" . 339 "Updated display CSS for better theme compatibility.<br/>" . 340 "Expanded debugging and error control.<br/>" . 341 ""); 342 } 343 344 if($this->options['Version'] < '1.9') 345 { 346 $this->options['SortBy'] = 'random'; 347 $this->options['DisplayPosition'] = '0'; 348 349 $sql = "ALTER TABLE `" . $this->table_cache . "` ADD `blocked` BLOB NOT NULL"; 350 $result = $wpdb->query($sql); 351 if($result === false) { 352 $this->admin_alert("Failed to create table `" . $this->table_log . "`."); 353 return(false); 354 } 355 356 $this->options['Version'] = '1.9'; 357 update_option('amazonFeedOptions', $this->options); 358 $this->admin_alert("Plugin upgraded to v. " . $this->options['Version'] . "<br/>" . 359 "Added ability to sort results on the whole blog, as well as on individual posts.<br/>" . 360 "Added ability to chose display position relative to page/post content.<br/>" . 361 "Reworked product caching for more robust storage and more advanced potential future features.<br/>" . 362 "Added ability to block specific products from being displayed.<br/>" . 363 ""); 364 } 365 366 if($this->options['Version'] < '2.0') 367 { 368 $this->options['Version'] = '2.0'; 369 update_option('amazonFeedOptions', $this->options); 370 $this->admin_alert("Plugin upgraded to v. " . $this->options['Version'] . "<br/>" . 371 "Removed Amazon products from appearing in blog feeds in order to better comply with Amazon regulations.<br/>" . 372 ""); 373 } 374 375 if($this->options['Version'] < '2.1') 376 { 377 $this->options['Version'] = '2.1'; 378 update_option('amazonFeedOptions', $this->options); 379 $this->admin_alert("Plugin upgraded to v. " . $this->options['Version'] . "<br/>" . 380 "Updated with better WordPress 3.0 compatibility.<br/>" . 381 ""); 382 } 383 384 return(true); 385 } 386 } 387 388 // Function to show notices using the built-in wp controls when appropriate. 389 function wp_admin_notices() 390 { 391 foreach($this->admin_notices as $msg) 392 { 393 $this->admin_alert($msg); 394 $this->debug($msg); 395 } 396 } 397 398 // Allow showing an alert to the user when necessary. 399 function admin_alert($msg = '', $log = true) 400 { 401 if($msg) echo "<div class='updated' id='amazonFeedAlert'><p><img src='http://www.warkensoft.com/images/aicon.png' width='18' height='18' align='absmiddle' /><strong>$msg</strong></p></div>"; 402 if($log) $this->debug($msg); 403 } 404 405 function error_handler($errno, $errstr, $errfile=false, $errline=false) 406 { 407 $msg = 'PHP Error: ' . $errstr; 408 409 switch($errno) 410 { 411 case E_ERROR: 412 case E_USER_ERROR: 413 $this->debug($msg); 414 die(); 415 break; 416 417 case E_WARNING: 418 case E_USER_WARNING: 419 $this->debug($msg); 420 break; 421 505 422 default: 506 $port = 80; 507 break; 508 } 509 } 510 511 512 // Load url data 513 $fp = fsockopen($hostname, $port, $errno, $errstr, 10); 514 if (!$fp) { 515 echo "$errstr ($errno)<br />\n"; 516 return(false); 517 } else { 518 $out = "GET " . $request . $query . " HTTP/1.0\r\n"; 519 $out .= "Host: $hostname\r\n"; 520 $out .= "Connection: Close\r\n\r\n"; 521 522 fwrite($fp, $out); 523 $data = ''; 524 while (!feof($fp)) { 525 $data .= fgets($fp); 526 } 527 fclose($fp); 528 529 $data_start = strpos($data, "\r\n\r\n"); 530 531 $header = substr($data, 0, $data_start); 532 $body = substr($data, $data_start + 4, strlen($data)); 533 534 $regs = ""; 535 if(eregi("[\r\n]+Location\: *([^\r\n]+)", $header, $regs) AND eregi("HTTP/[0-9]*\.[0-9]*[ ]*3[0-9]{2}", $header)) 536 { 537 $location = $regs[1]; 538 return($this->getpath($location)); 423 break; 424 } 425 } 426 427 // Allow limited logging of errors. 428 function log_error($msg = '') 429 { 430 if(!isset($this->options['Version'])) return; 431 432 // Legacy code to support error logging until upgrade can complete. 433 if($this->options['Version'] < '1.8') 434 { 435 if(!is_array($this->options['error_log'])) $this->options['error_log'] = array(); 436 array_unshift($this->options['error_log'], date('F j, Y, g:i a ') . $msg); 437 if(count($this->options['error_log']) > 100) 438 { 439 array_pop($this->options['error_log']); 440 } 441 update_option('amazonFeedOptions', $this->options); 539 442 } 540 443 else 541 444 { 542 return($body); 543 } 544 } 545 } 546 547 548 // Main data loader. 549 function request_data($new_params = array()) 550 { 551 // Only run a request from Amazon once per page load in order to comply with amazon regs. 552 if($this->done_request == true) { 553 $this->debug("Do not run request for '" . implode(",", $new_params) . "' in order to comply " . 554 "with Amazon speed limit regulations"); 555 return(false); 556 } 557 558 if($this->options['SearchIndex']) $this->params['SearchIndex'] = $this->options['SearchIndex']; 559 560 // Update the options with anything passed on the function. 561 $params = array_merge($this->params, $new_params); 562 563 // Create the request 564 # $request = $this->options['ServicePath'] 565 # . "&AWSAccessKeyId=" . $this->options['AWSAccessKeyId'] 566 # . "&AssociateTag=" . $this->options['AssociateTag']; 567 568 // Determine region based on predefined service path. 569 if(eregi('ecs\.amazonaws\.([^/]+)/', $this->options['ServicePath'], $regs)) 570 { 571 $region = $regs[1]; 572 } 573 574 $pubKey = $this->options['AWSAccessKeyId']; 575 $priKey = $this->options['AWSSecretAccessKeyId']; 576 $request['AssociateTag'] = $this->options['AssociateTag']; 577 578 // Iterate through the parameters adding to the request. 579 foreach($params as $key=>$param) 580 { 581 if($param != "") 582 { 583 # $request .= "&" . $key . "=" . $param; 584 $request[$key] = $param; 585 } 586 } 587 588 $xml_data = $this->aws_signed_request($region, $request, $pubKey, $priKey); 589 $this->done_request = true; 590 if($xml_data) return($xml_data); 591 } 592 593 // Load related reading either from database table, or from Amazon.com 594 function load($keyword) 595 { 596 global $wpdb; 597 $keyword = addslashes($keyword); 598 $sql = "SELECT * FROM " . $this->table_cache . " WHERE `keyword` = '" . $keyword . "' LIMIT 0,1"; 599 $data = $wpdb->get_row($sql, ARRAY_A); 600 601 if($data !== false AND $data['keyword'] != "") 602 { 603 $data['keyword'] = stripslashes($data['keyword']); 604 $data['data'] = stripslashes($data['data']); 605 606 return($data); 607 } 608 } 609 610 // Save related reading to cache when necessary 611 function save($keyword, $xml) 612 { 613 global $wpdb; 614 615 $keyword = trim(addslashes($keyword)); 616 $data = trim(addslashes($xml)); 617 $timestamp = time() + ($this->options['CacheExpiry']*60); 618 619 $sql = "SELECT * FROM " . $this->table_cache . " WHERE `keyword` = '" . $keyword . "' LIMIT 0,1"; 620 $existing_data = $wpdb->get_row($sql, ARRAY_A); 621 622 if($existing_data['keyword'] != "") 623 $sql = "UPDATE " . $this->table_cache . " SET `timestamp` = '$timestamp', `data` = '$data' WHERE `keyword` = '" . $keyword . "' LIMIT 1;"; 624 else 625 $sql = "INSERT INTO " . $this->table_cache . " (`keyword`, `timestamp`, `data`) VALUES ('$keyword', '$timestamp', '$data');"; 626 627 $results = $wpdb->query($sql); 628 return; 629 } 630 631 /** 632 * Update the cached entry to block a given ASIN. 633 */ 634 function block($keyword, $asin) 635 { 636 global $wpdb; 637 638 $keyword = trim(addslashes($keyword)); 639 $asin = trim(addslashes($asin)); 640 641 $sql = "SELECT * FROM " . $this->table_cache . " WHERE `keyword` = '" . $keyword . "' LIMIT 0,1"; 642 $existing_data = $wpdb->get_row($sql, ARRAY_A); 643 644 if($existing_data['keyword'] != "") 645 { 646 $blocked = stripslashes($existing_data['blocked']); 647 if(trim($blocked) != "") $blocked = explode('|', $blocked); 648 else $blocked = array(); 649 $key = array_search($asin, $blocked); 650 if($key === false) 651 { 652 $blocked[] = $asin; 653 } 654 $blocked = implode('|', $blocked); 655 $blocked = addslashes($blocked); 656 657 $sql = "UPDATE " . $this->table_cache . " SET `blocked`='$blocked' WHERE `keyword` = '" . $keyword . "' LIMIT 1;"; 658 $wpdb->query($sql); 659 } 660 else 661 $this->admin_alert("Unable to block this product. The keyword doesn't exist in the cache."); 662 663 return; 664 } 665 666 /** 667 * Remove a previous block on an ASIN 668 */ 669 function unblock($keyword, $asin) 670 { 671 global $wpdb; 672 673 $keyword = trim(addslashes($keyword)); 674 $asin = trim(addslashes($asin)); 675 676 $sql = "SELECT * FROM " . $this->table_cache . " WHERE `keyword` = '" . $keyword . "' LIMIT 0,1"; 677 $existing_data = $wpdb->get_row($sql, ARRAY_A); 678 679 if($existing_data['keyword'] != "") 680 { 681 $blocked = stripslashes($existing_data['blocked']); 682 if(trim($blocked) != "") $blocked = explode('|', $blocked); 683 else $blocked = array(); 684 $key = array_search($asin, $blocked); 685 if(false !== $key) 686 unset($blocked[$key]); 687 if(count($blocked) > 0) $blocked = implode('|', $blocked); 688 else $blocked = ''; 689 $blocked = addslashes($blocked); 690 691 $sql = "UPDATE " . $this->table_cache . " SET `blocked`='$blocked' WHERE `keyword` = '" . $keyword . "' LIMIT 1;"; 692 $wpdb->query($sql); 693 } 694 else 695 $this->admin_alert("Unable to block this product. The keyword doesn't exist in the cache."); 696 697 return; 698 } 699 700 701 // Specific search functions 702 function search($search_keywords, $searchResults=false, $searchField=false, $searchIndex=false, $options = array()) 703 { 704 global $wpdb; 705 706 $this->debug("Searching For: '$search_keywords'", 2); 707 708 if($searchResults == false) $searchResults = $this->options['MaxResults']; 709 if($searchField == false) $searchField = $this->options['DefaultSearchField']; 710 if($searchIndex == false) $searchIndex = $this->params['SearchIndex']; 711 712 $keywords = explode(",", $search_keywords); 713 $tmp_items = array(); 714 715 foreach($keywords as $word) 716 { 717 if(trim($word) != "") 718 { 719 $xml_data = false; 720 $data = false; 721 $data = $this->load(trim($word)); 722 $blocked = array(); 723 724 if($data['data']) 725 { 726 $blocked = stripslashes($data['blocked']); 727 if(trim($blocked) != "") $blocked = explode('|', $blocked); 728 else $blocked = array(); 729 } 730 731 if($data['data'] != "" AND ($data['timestamp'] > time() OR $this->done_request == true)) { 732 $this->debug("Loading from memory for keyword: '$word'.", 2); 733 $xml_data = $data['data']; 734 735 $memCached = true; 736 } 737 elseif(!$this->done_request) 738 { 739 $new_params = array( 740 $searchField => urlencode(trim($word)) 741 ); 742 743 $this->debug("Sending request to amazon for keyword: '$word'."); 744 $xml_data = $this->request_data($new_params); 745 746 if($xml_data) 747 { 748 libxml_use_internal_errors(true); 749 $xml = simplexml_load_string($xml_data); 750 751 if($xml) 445 global $wpdb; 446 $sql = "INSERT INTO `" . $this->table_log . "` (`timestamp`, `message`) " . 447 "VALUES (" . 448 "'" . time() . "', " . 449 "'" . addslashes($msg) . "');"; 450 $wpdb->query($sql); 451 } 452 } 453 454 function show_error($msg = '') 455 { 456 if($this->debug_visible == true) 457 { 458 echo "\n<!-- AmazonFeed Debugging Message --><pre>$msg</pre>"; 459 } 460 } 461 462 function debug($msg = '', $level = '1') 463 { 464 465 switch($this->debug_mode) 466 { 467 case 'basic': 468 if($level <= '1') { 469 $this->log_error($msg); 470 if($this->debug_visible == true) $this->show_error($msg); 471 } 472 break; 473 474 case 'all': 475 if($level <= '2') { 476 $this->log_error($msg); 477 if($this->debug_visible == true) $this->show_error($msg); 478 } 479 break; 480 481 default: 482 break; 483 } 484 485 } 486 487 function getpath($path, $username = false, $password = false) 488 { 489 $this->debug("Using built-in getpath function to load data. Slower, but should work."); 490 491 // Test URL and ensure that it is valid. 492 if(false !== $username AND false !== $password) 493 $match = "^([a-z]{2,10})\://" . $username . "\:" . $password . "([a-z0-9\.\-]+)/?([^\?]*)(.*)$"; 494 else 495 $match = "^([a-z]{2,10})\://([a-z0-9\.\-]+)(/?[^\?]*)(.*)$"; 496 497 // Return false if the path does not look like a url. 498 if(!eregi($match, $path, $regs)) { 499 return(false); 500 } 501 else { 502 list($path, $protocol, $hostname, $request, $query) = $regs; 503 504 // Determine port protocol. 505 switch(strtoupper($protocol)) 506 { 507 case "HTTPS": 508 $port = 443; 509 break; 510 511 case "FTP": 512 $port = 21; 513 break; 514 515 default: 516 $port = 80; 517 break; 518 } 519 } 520 521 522 // Load url data 523 $fp = fsockopen($hostname, $port, $errno, $errstr, 10); 524 if (!$fp) { 525 echo "$errstr ($errno)<br />\n"; 526 return(false); 527 } else { 528 $out = "GET " . $request . $query . " HTTP/1.0\r\n"; 529 $out .= "Host: $hostname\r\n"; 530 $out .= "Connection: Close\r\n\r\n"; 531 532 fwrite($fp, $out); 533 $data = ''; 534 while (!feof($fp)) { 535 $data .= fgets($fp); 536 } 537 fclose($fp); 538 539 $data_start = strpos($data, "\r\n\r\n"); 540 541 $header = substr($data, 0, $data_start); 542 $body = substr($data, $data_start + 4, strlen($data)); 543 544 $regs = ""; 545 if(eregi("[\r\n]+Location\: *([^\r\n]+)", $header, $regs) AND eregi("HTTP/[0-9]*\.[0-9]*[ ]*3[0-9]{2}", $header)) 546 { 547 $location = $regs[1]; 548 return($this->getpath($location)); 549 } 550 else 551 { 552 return($body); 553 } 554 } 555 } 556 557 558 // Main data loader. 559 function request_data($new_params = array()) 560 { 561 // Only run a request from Amazon once per page load in order to comply with amazon regs. 562 if($this->done_request == true) { 563 $this->debug("Do not run request for '" . implode(",", $new_params) . "' in order to comply " . 564 "with Amazon speed limit regulations"); 565 return(false); 566 } 567 568 if($this->options['SearchIndex']) $this->params['SearchIndex'] = $this->options['SearchIndex']; 569 570 // Update the options with anything passed on the function. 571 $params = array_merge($this->params, $new_params); 572 573 // Create the request 574 # $request = $this->options['ServicePath'] 575 # . "&AWSAccessKeyId=" . $this->options['AWSAccessKeyId'] 576 # . "&AssociateTag=" . $this->options['AssociateTag']; 577 578 // Determine region based on predefined service path. 579 if(eregi('ecs\.amazonaws\.([^/]+)/', $this->options['ServicePath'], $regs)) 580 { 581 $region = $regs[1]; 582 } 583 584 $pubKey = $this->options['AWSAccessKeyId']; 585 $priKey = $this->options['AWSSecretAccessKeyId']; 586 $request['AssociateTag'] = $this->options['AssociateTag']; 587 588 // Iterate through the parameters adding to the request. 589 foreach($params as $key=>$param) 590 { 591 if($param != "") 592 { 593 # $request .= "&" . $key . "=" . $param; 594 $request[$key] = $param; 595 } 596 } 597 598 $xml_data = $this->aws_signed_request($region, $request, $pubKey, $priKey); 599 $this->done_request = true; 600 if($xml_data) return($xml_data); 601 } 602 603 // Load related reading either from database table, or from Amazon.com 604 function load($keyword) 605 { 606 global $wpdb; 607 $keyword = addslashes($keyword); 608 $sql = "SELECT * FROM " . $this->table_cache . " WHERE `keyword` = '" . $keyword . "' LIMIT 0,1"; 609 $data = $wpdb->get_row($sql, ARRAY_A); 610 611 if($data !== false AND $data['keyword'] != "") 612 { 613 $data['keyword'] = stripslashes($data['keyword']); 614 $data['data'] = stripslashes($data['data']); 615 616 return($data); 617 } 618 } 619 620 // Save related reading to cache when necessary 621 function save($keyword, $xml) 622 { 623 global $wpdb; 624 625 $keyword = trim(addslashes($keyword)); 626 $data = trim(addslashes($xml)); 627 $timestamp = time() + ($this->options['CacheExpiry']*60); 628 629 $sql = "SELECT * FROM " . $this->table_cache . " WHERE `keyword` = '" . $keyword . "' LIMIT 0,1"; 630 $existing_data = $wpdb->get_row($sql, ARRAY_A); 631 632 if($existing_data['keyword'] != "") 633 $sql = "UPDATE " . $this->table_cache . " SET `timestamp` = '$timestamp', `data` = '$data' WHERE `keyword` = '" . $keyword . "' LIMIT 1;"; 634 else 635 $sql = "INSERT INTO " . $this->table_cache . " (`keyword`, `timestamp`, `data`) VALUES ('$keyword', '$timestamp', '$data');"; 636 637 $results = $wpdb->query($sql); 638 return; 639 } 640 641 /** 642 * Update the cached entry to block a given ASIN. 643 */ 644 function block($keyword, $asin) 645 { 646 global $wpdb; 647 648 $keyword = trim(addslashes($keyword)); 649 $asin = trim(addslashes($asin)); 650 651 $sql = "SELECT * FROM " . $this->table_cache . " WHERE `keyword` = '" . $keyword . "' LIMIT 0,1"; 652 $existing_data = $wpdb->get_row($sql, ARRAY_A); 653 654 if($existing_data['keyword'] != "") 655 { 656 $blocked = stripslashes($existing_data['blocked']); 657 if(trim($blocked) != "") $blocked = explode('|', $blocked); 658 else $blocked = array(); 659 $key = array_search($asin, $blocked); 660 if($key === false) 661 { 662 $blocked[] = $asin; 663 } 664 $blocked = implode('|', $blocked); 665 $blocked = addslashes($blocked); 666 667 $sql = "UPDATE " . $this->table_cache . " SET `blocked`='$blocked' WHERE `keyword` = '" . $keyword . "' LIMIT 1;"; 668 $wpdb->query($sql); 669 } 670 else 671 $this->admin_alert("Unable to block this product. The keyword doesn't exist in the cache."); 672 673 return; 674 } 675 676 /** 677 * Remove a previous block on an ASIN 678 */ 679 function unblock($keyword, $asin) 680 { 681 global $wpdb; 682 683 $keyword = trim(addslashes($keyword)); 684 $asin = trim(addslashes($asin)); 685 686 $sql = "SELECT * FROM " . $this->table_cache . " WHERE `keyword` = '" . $keyword . "' LIMIT 0,1"; 687 $existing_data = $wpdb->get_row($sql, ARRAY_A); 688 689 if($existing_data['keyword'] != "") 690 { 691 $blocked = stripslashes($existing_data['blocked']); 692 if(trim($blocked) != "") $blocked = explode('|', $blocked); 693 else $blocked = array(); 694 $key = array_search($asin, $blocked); 695 if(false !== $key) 696 unset($blocked[$key]); 697 if(count($blocked) > 0) $blocked = implode('|', $blocked); 698 else $blocked = ''; 699 $blocked = addslashes($blocked); 700 701 $sql = "UPDATE " . $this->table_cache . " SET `blocked`='$blocked' WHERE `keyword` = '" . $keyword . "' LIMIT 1;"; 702 $wpdb->query($sql); 703 } 704 else 705 $this->admin_alert("Unable to block this product. The keyword doesn't exist in the cache."); 706 707 return; 708 } 709 710 711 // Specific search functions 712 function search($search_keywords, $searchResults=false, $searchField=false, $searchIndex=false, $options = array()) 713 { 714 global $wpdb; 715 716 $this->debug("Searching For: '$search_keywords'", 2); 717 718 if($searchResults == false) $searchResults = $this->options['MaxResults']; 719 if($searchField == false) $searchField = $this->options['DefaultSearchField']; 720 if($searchIndex == false) $searchIndex = $this->params['SearchIndex']; 721 722 $keywords = explode(",", $search_keywords); 723 $tmp_items = array(); 724 725 foreach($keywords as $word) 726 { 727 if(trim($word) != "") 728 { 729 $xml_data = false; 730 $data = false; 731 $data = $this->load(trim($word)); 732 $blocked = array(); 733 734 if($data['data']) 735 { 736 $blocked = stripslashes($data['blocked']); 737 if(trim($blocked) != "") $blocked = explode('|', $blocked); 738 else $blocked = array(); 739 } 740 741 if($data['data'] != "" AND ($data['timestamp'] > time() OR $this->done_request == true)) { 742 $this->debug("Loading from memory for keyword: '$word'.", 2); 743 $xml_data = $data['data']; 744 745 $memCached = true; 746 } 747 elseif(!$this->done_request) 748 { 749 $new_params = array( 750 $searchField => urlencode(trim($word)) 751 ); 752 753 $this->debug("Sending request to amazon for keyword: '$word'."); 754 $xml_data = $this->request_data($new_params); 755 756 if($xml_data) 752 757 { 753 $this->debug("Received XML data from Amazon for word '$word'. Saving to cache.", 2); 754 $this->save($word, $xml_data); 755 $memCached = false; 756 } 757 else 758 { 759 libxml_clear_errors(); 760 $this->debug("Unable to properly process XML data received for word '$word'. Attempting to use pre-cached data if available."); 761 $xml_data = $data['data']; 762 $memCached = true; 763 } 764 } 765 else 766 $this->debug("Failed to receive any valid XML from Amazon for word '$word'."); 767 768 } 769 else 770 { 771 $this->debug("Skipped searching for word '$word' because we should only send one request to Amazon per page load. Right now, we're done.", 2); 772 } 773 774 775 776 if($xml_data) 777 { 778 $xml = simplexml_load_string($xml_data); 779 if(isset($xml)) 780 { 781 $items = $xml->Items->Item; 782 783 if(count($items) > 0) 784 { 785 $counter = 0; 786 foreach($xml->Items->Item as $item) { 787 if(array_search($item->ASIN, $blocked) === false) 788 $tmp_items[] = $item; 789 } 790 } 791 elseif(isset($xml->Items->Request->Errors)) 792 { 793 if(!$memCached) 758 libxml_use_internal_errors(true); 759 $xml = simplexml_load_string($xml_data); 760 761 if($xml) 794 762 { 795 $this->debug("Error returned from Amazon for word '$word'."); 796 $this->debug($xml->Items->Request->Errors->Error->Message); 763 $this->debug("Received XML data from Amazon for word '$word'. Saving to cache.", 2); 764 $this->save($word, $xml_data); 765 $memCached = false; 797 766 } 798 767 else 799 768 { 800 $this->debug("Detected previously cached errors for this word '$word' from Amazon."); 801 $this->debug($xml->Items->Request->Errors->Error->Message); 769 libxml_clear_errors(); 770 $this->debug("Unable to properly process XML data received for word '$word'. Attempting to use pre-cached data if available."); 771 $xml_data = $data['data']; 772 $memCached = true; 802 773 } 803 774 } 804 775 else 776 $this->debug("Failed to receive any valid XML from Amazon for word '$word'."); 777 778 } 779 else 780 { 781 $this->debug("Skipped searching for word '$word' because we should only send one request to Amazon per page load. Right now, we're done.", 2); 782 } 783 784 785 786 if($xml_data) 787 { 788 $xml = simplexml_load_string($xml_data); 789 if(isset($xml)) 805 790 { 806 $this->debug("No results or errors were returned for word '$word'."); 791 $items = $xml->Items->Item; 792 793 if(count($items) > 0) 794 { 795 $counter = 0; 796 foreach($xml->Items->Item as $item) { 797 if(array_search($item->ASIN, $blocked) === false) 798 $tmp_items[] = $item; 799 } 800 } 801 elseif(isset($xml->Items->Request->Errors)) 802 { 803 if(!$memCached) 804 { 805 $this->debug("Error returned from Amazon for word '$word'."); 806 $this->debug($xml->Items->Request->Errors->Error->Message); 807 } 808 else 809 { 810 $this->debug("Detected previously cached errors for this word '$word' from Amazon."); 811 $this->debug($xml->Items->Request->Errors->Error->Message); 812 } 813 } 814 else 815 { 816 $this->debug("No results or errors were returned for word '$word'."); 817 } 807 818 } 819 else 820 $this->debug("Unable to properly load XML string for word '$word'."); 808 821 } 809 822 else 810 $this->debug("Unable to properly load XML string for word '$word'."); 811 } 812 else 813 $this->debug("No XML data detected for word '$word'.", 2); 814 } 815 } 816 817 if(!$tmp_items) { 818 $this->debug('No results found related to the keyword(s): ' . $search_keywords); 819 return(false); 820 } 821 822 // Sort the products according to the requested value. 823 $items = array(); 824 $counter = 0; 825 826 if(!isset($options['SortBy'])) $options['SortBy'] = ''; 827 828 switch($options['SortBy']) 829 { 830 case 'salesrank': 831 foreach($tmp_items as $tmp_item) 832 { 833 $id = (int) $tmp_item->SalesRank; 834 if($id) 835 { 836 $items[$id] = $tmp_item; 837 } 838 } 839 ksort($items); 840 $items = array_slice($items, 0, $searchResults); 841 break; 842 843 case '-salesrank': 844 foreach($tmp_items as $tmp_item) 845 { 846 $id = (int) $tmp_item->SalesRank; 847 if($id) 848 { 849 $items[$id] = $tmp_item; 850 } 851 } 852 krsort($items); 853 $items = array_slice($items, 0, $searchResults); 854 break; 855 856 case 'listprice': 857 foreach($tmp_items as $tmp_item) 858 { 859 if($tmp_item->OfferSummary->LowestNewPrice->Amount) 860 $id = (int) $tmp_item->OfferSummary->LowestNewPrice->Amount; 823 $this->debug("No XML data detected for word '$word'.", 2); 824 } 825 } 826 827 if(!$tmp_items) { 828 $this->debug('No results found related to the keyword(s): ' . $search_keywords); 829 return(false); 830 } 831 832 // Sort the products according to the requested value. 833 $items = array(); 834 $counter = 0; 835 836 if(!isset($options['SortBy'])) $options['SortBy'] = ''; 837 838 switch($options['SortBy']) 839 { 840 case 'salesrank': 841 foreach($tmp_items as $tmp_item) 842 { 843 $id = (int) $tmp_item->SalesRank; 844 if($id) 845 { 846 $items[$id] = $tmp_item; 847 } 848 } 849 ksort($items); 850 $items = array_slice($items, 0, $searchResults); 851 break; 852 853 case '-salesrank': 854 foreach($tmp_items as $tmp_item) 855 { 856 $id = (int) $tmp_item->SalesRank; 857 if($id) 858 { 859 $items[$id] = $tmp_item; 860 } 861 } 862 krsort($items); 863 $items = array_slice($items, 0, $searchResults); 864 break; 865 866 case 'listprice': 867 foreach($tmp_items as $tmp_item) 868 { 869 if($tmp_item->OfferSummary->LowestNewPrice->Amount) 870 $id = (int) $tmp_item->OfferSummary->LowestNewPrice->Amount; 871 else 872 $id = (int) $tmp_item->ItemAttributes->ListPrice->Amount; 873 874 875 876 if($id) 877 { 878 $items[$id] = $tmp_item; 879 } 880 } 881 ksort($items); 882 $items = array_slice($items, 0, $searchResults); 883 break; 884 885 case '-listprice': 886 foreach($tmp_items as $tmp_item) 887 { 888 if($tmp_item->OfferSummary->LowestNewPrice->Amount) 889 $id = (int) $tmp_item->OfferSummary->LowestNewPrice->Amount; 890 else 891 $id = (int) $tmp_item->ItemAttributes->ListPrice->Amount; 892 893 894 895 if($id) 896 { 897 $items[$id] = $tmp_item; 898 } 899 } 900 krsort($items); 901 $items = array_slice($items, 0, $searchResults); 902 break; 903 904 case 'random': 905 default: 906 while($counter++ < count($tmp_items)*2) 907 { 908 $rand = rand(0, count($tmp_items)-1); 909 $tmp_item = $tmp_items[$rand]; 910 $id = $tmp_item->ASIN; 911 912 if(!$items["$id"]) $items["$id"] = $tmp_item; 913 if(count($items) >= $searchResults) break; 914 } 915 break; 916 } 917 918 return($items); 919 } 920 921 /** 922 * Main function to display related Amazon products. 923 */ 924 function display($keywords, $echo = true, $params = array()) 925 { 926 $options = $this->options; 927 928 if(!isset($params['class'])) $params['class'] = 'amazonfeed'; 929 930 foreach($params as $key=>$value) 931 { 932 $options[$key] = $value; 933 } 934 935 $old_error_handler = set_error_handler(array($this, 'error_handler')); 936 if($old_error_handler === false) $this->debug('Unable to set custom error handler.'); 937 938 $items = $this->search($keywords, false, false, false, $options); 939 if($items) $numBooks = count($items); 940 941 if($numBooks == 0 AND $keywords != $options['DefaultTags']) 942 { 943 $this->debug("No items found for keywords '$keywords'. Searching with default tags: '" . $options['DefaultTags'] . "'"); 944 $items = $this->search($options['DefaultTags'], false, false, false, $options); 945 $numBooks = count($items); 946 947 $this->debug("Number of Items: $numBooks", 2); 948 } 949 950 $result = ''; 951 952 if($numBooks > 0) 953 { 954 // Allow for tipping the author, if enabled 955 if($options['AllowTip'] == true) 956 { 957 // If there is only one result, show the author's link 50% of the time. 958 if($numBooks == 1) 959 $tip_random_number = rand(1, 2); 861 960 else 862 $id = (int) $tmp_item->ItemAttributes->ListPrice->Amount; 863 864 865 866 if($id) 867 { 868 $items[$id] = $tmp_item; 869 } 870 } 871 ksort($items); 872 $items = array_slice($items, 0, $searchResults); 873 break; 874 875 case '-listprice': 876 foreach($tmp_items as $tmp_item) 877 { 878 if($tmp_item->OfferSummary->LowestNewPrice->Amount) 879 $id = (int) $tmp_item->OfferSummary->LowestNewPrice->Amount; 961 $tip_random_number = rand(1, $numBooks); 962 963 } 964 965 $result = "<div class='" . $params['class'] . "'>" . stripslashes($options['TitleText']) . "\n"; 966 967 $counter = 0; 968 if(is_array($items)) foreach($items as $item) 969 { 970 $result .= "<div class='product'>"; 971 972 $counter++; 973 974 $title = $item->ItemAttributes->Title; 975 $desc = trim($item->EditorialReviews->EditorialReview[0]->Content); 976 $link = urldecode($item->DetailPageURL); 977 $link_target = $options['LinkTarget']; 978 979 if(isset($options['ImageSize'])) { 980 if($options['ImageSize'] == '1') 981 $image = $item->SmallImage->URL; 982 elseif($options['ImageSize'] == '2') 983 $image = $item->MediumImage->URL; 984 elseif($options['ImageSize'] == '3') 985 $image = $item->LargeImage->URL; 986 else 987 $image = ''; 988 989 } 990 elseif($options['ShowImages']) 991 { 992 $image = $item->SmallImage->URL; 993 } 880 994 else 881 $id = (int) $tmp_item->ItemAttributes->ListPrice->Amount; 882 883 884 885 if($id) 886 { 887 $items[$id] = $tmp_item; 888 } 889 } 890 krsort($items); 891 $items = array_slice($items, 0, $searchResults); 892 break; 893 894 case 'random': 895 default: 896 while($counter++ < count($tmp_items)*2) 897 { 898 $rand = rand(0, count($tmp_items)-1); 899 $tmp_item = $tmp_items[$rand]; 900 $id = $tmp_item->ASIN; 901 902 if(!$items["$id"]) $items["$id"] = $tmp_item; 903 if(count($items) >= $searchResults) break; 904 } 905 break; 906 } 907 908 return($items); 909 } 910 911 /** 912 * Main function to display related Amazon products. 913 */ 914 function display($keywords, $echo = true, $params = array()) 915 { 916 $options = $this->options; 917 918 if(!isset($params['class'])) $params['class'] = 'amazonfeed'; 919 920 foreach($params as $key=>$value) 921 { 922 $options[$key] = $value; 923 } 924 925 $old_error_handler = set_error_handler(array($this, 'error_handler')); 926 if($old_error_handler === false) $this->debug('Unable to set custom error handler.'); 927 928 $items = $this->search($keywords, false, false, false, $options); 929 if($items) $numBooks = count($items); 930 931 if($numBooks == 0 AND $keywords != $options['DefaultTags']) 932 { 933 $this->debug("No items found for keywords '$keywords'. Searching with default tags: '" . $options['DefaultTags'] . "'"); 934 $items = $this->search($options['DefaultTags'], false, false, false, $options); 935 $numBooks = count($items); 936 937 $this->debug("Number of Items: $numBooks", 2); 938 } 939 940 $result = ''; 941 942 if($numBooks > 0) 943 { 944 // Allow for tipping the author, if enabled 945 if($options['AllowTip'] == true) 946 { 947 // If there is only one result, show the author's link 50% of the time. 948 if($numBooks == 1) 949 $tip_random_number = rand(1, 2); 950 else 951 $tip_random_number = rand(1, $numBooks); 952 953 } 954 955 $result = "<div class='" . $params['class'] . "'>" . stripslashes($options['TitleText']) . "\n"; 956 957 $counter = 0; 958 if(is_array($items)) foreach($items as $item) 959 { 960 $result .= "<div class='product'>"; 961 962 $counter++; 963 964 $title = $item->ItemAttributes->Title; 965 $desc = trim($item->EditorialReviews->EditorialReview[0]->Content); 966 $link = urldecode($item->DetailPageURL); 967 $link_target = $options['LinkTarget']; 968 969 if(isset($options['ImageSize'])) { 970 if($options['ImageSize'] == '1') 971 $image = $item->SmallImage->URL; 972 elseif($options['ImageSize'] == '2') 973 $image = $item->MediumImage->URL; 974 elseif($options['ImageSize'] == '3') 975 $image = $item->LargeImage->URL; 995 { 996 $image = ''; 997 } 998 999 // Extract an excerpt description of the product based on the expanded description. 1000 if($desc AND $options['ShowDesc'] == '1') 1001 { 1002 $desc = strip_tags($desc, '<p><br>'); 1003 if(strlen($desc) > 300) 1004 { 1005 $desc = substr($desc, 0, 150) . "... <a class='readmorelink' href='$link' target='$link_target'>Read More ></a>"; 1006 } 1007 } 1008 elseif($desc AND $options['ShowDesc'] == '2') 1009 { 1010 $desc = strip_tags($desc, '<p><br><strong><ol><ul><li><b><blockquote><h1><h2><h3><h4><h5><h6>'); 1011 } 976 1012 else 977 $image = ''; 978 979 } 980 elseif($options['ShowImages']) 981 { 982 $image = $item->SmallImage->URL; 983 } 984 else 985 { 986 $image = ''; 987 } 988 989 // Extract an excerpt description of the product based on the expanded description. 990 if($desc AND $options['ShowDesc'] == '1') 991 { 992 $desc = strip_tags($desc, '<p><br>'); 993 if(strlen($desc) > 300) 994 { 995 $desc = substr($desc, 0, 150) . "... <a class='readmorelink' href='$link' target='$link_target'>Read More ></a>"; 996 } 997 } 998 elseif($desc AND $options['ShowDesc'] == '2') 999 { 1000 $desc = strip_tags($desc, '<p><br><strong><ol><ul><li><b><blockquote><h1><h2><h3><h4><h5><h6>'); 1001 } 1002 else 1003 { 1004 $desc = ''; 1005 } 1006 1007 // Do the tip 1008 if($options['AllowTip'] == true AND $counter == $tip_random_number) 1009 { 1010 $link = str_replace($options['AssociateTag'], $options['LocaleTipTag'], $link); 1011 } 1012 1013 if(trim($image) != "") $image_html = "<img src='$image' class='amazonfeed-product-image' " . 1014 "alt='" . htmlentities($title, ENT_QUOTES) . "' " . 1015 "title='" . htmlentities($title, ENT_QUOTES) . "' />"; 1016 else $image_html = ""; 1017 1018 if($options['ShowText'] AND trim($title) != "") $title_html = "<span class='amazonfeed-product-title'>$title</span>"; 1019 else $title_html = ""; 1020 1021 if($options['ShowDesc'] AND trim($desc) != "") $desc_html = "<span class='amazonfeed-product-desc'>$desc</span>"; 1022 else $desc_html = ""; 1023 1024 1025 $result .= "<a href='$link' target='$link_target' rel='nofollow'>" . $image_html . $title_html . "</a>$desc_html\n"; 1026 $result .= "</div>"; 1027 1028 if($counter >= $options['MaxResults']) break; 1029 } 1030 1031 $result .= "</div>"; 1032 } 1033 if($old_error_handler !== false) restore_error_handler(); 1034 if($echo) echo $result; 1035 else return($result); 1036 1037 } 1038 1039 /** 1040 * Run at wordpress header load to load display stylesheet 1041 */ 1042 function wp_head() 1043 { 1044 if(!isset($this->options['StyleSheet'])) $this->options['StyleSheet'] = 'style.css'; 1045 1046 if(file_exists($this->basePath . '/css/' . $this->options['StyleSheet'])) 1047 { 1048 $csspath = $this->urlPath . '/css/' . $this->options['StyleSheet']; 1013 { 1014 $desc = ''; 1015 } 1016 1017 // Do the tip 1018 if($options['AllowTip'] == true AND $counter == $tip_random_number) 1019 { 1020 $link = str_replace($options['AssociateTag'], $options['LocaleTipTag'], $link); 1021 } 1022 1023 if(trim($image) != "") $image_html = "<img src='$image' class='amazonfeed-product-image' " . 1024 "alt='" . htmlentities($title, ENT_QUOTES) . "' " . 1025 "title='" . htmlentities($title, ENT_QUOTES) . "' />"; 1026 else $image_html = ""; 1027 1028 if($options['ShowText'] AND trim($title) != "") $title_html = "<span class='amazonfeed-product-title'>$title</span>"; 1029 else $title_html = ""; 1030 1031 if($options['ShowDesc'] AND trim($desc) != "") $desc_html = "<span class='amazonfeed-product-desc'>$desc</span>"; 1032 else $desc_html = ""; 1033 1034 1035 $result .= "<a href='$link' target='$link_target' rel='nofollow'>" . $image_html . $title_html . "</a>$desc_html\n"; 1036 $result .= "</div>"; 1037 1038 if($counter >= $options['MaxResults']) break; 1039 } 1040 1041 $result .= "</div>"; 1042 } 1043 if($old_error_handler !== false) restore_error_handler(); 1044 if($echo) echo $result; 1045 else return($result); 1046 1047 } 1048 1049 /** 1050 * Run at wordpress header load to load display stylesheet 1051 */ 1052 function wp_head() 1053 { 1054 if(!isset($this->options['StyleSheet'])) $this->options['StyleSheet'] = 'style.css'; 1055 1056 if(file_exists($this->basePath . '/css/' . $this->options['StyleSheet'])) 1057 { 1058 $csspath = $this->urlPath . '/css/' . $this->options['StyleSheet']; 1059 ?> 1060 <link rel='stylesheet' href='<?php echo $csspath; ?>' type='text/css' media='all' /> 1061 <?php 1062 } 1063 } 1064 1065 /** 1066 * Run at wp admin header load to load admin stylesheet. 1067 */ 1068 function admin_head() 1069 { 1070 $csspath = $this->urlPath . '/html/admin_styles.css'; 1049 1071 ?> 1050 1072 <link rel='stylesheet' href='<?php echo $csspath; ?>' type='text/css' media='all' /> 1051 1073 <?php 1052 1074 } 1075 1076 function wp_content($content='') 1077 { 1078 global $post; 1079 1080 if(is_feed()) return($content); 1081 1082 $params = array(); 1083 1084 // Check to see if we have custom keywords for the page. 1085 $custom_keywords = get_post_meta($post->ID, '_amazonfeed_keywords', true); 1086 1087 if($this->options['Version'] > '1.0') 1088 { 1089 // Check to ensure we're allowed to show on this page. 1090 if(is_single() AND !$this->options['ShowOnPosts']) return($content); 1091 if(is_page() AND !$this->options['ShowOnPages']) return($content); 1092 if((is_home()) AND !$this->options['ShowOnHome']) return($content); 1093 if(is_category() AND !$this->options['ShowOnCategories']) return($content); 1094 if(is_tag() AND !$this->options['ShowOnTags']) return($content); 1095 if(is_search() AND !$this->options['ShowOnSearch']) return($content); 1096 if(function_exists('is_front_page')) if((is_front_page()) AND !$this->options['ShowOnHome']) return($content); 1097 1098 } 1099 1100 // If the page has had the plugin disabled, just return the content. 1101 if( get_post_meta($post->ID, '_amazonfeed_disabled', true) == "true" ) return($content); 1102 1103 if(!$custom_keywords) 1104 { 1105 if($this->options['SearchFrom'] == "categories") 1106 $tags = get_the_category(); 1107 else 1108 $tags = get_the_tags(); 1109 1110 if(count($tags) == 0 OR $tags == "") { 1111 $keywords = $this->options['DefaultTags']; 1112 } 1113 else 1114 { 1115 foreach($tags as $tag) 1116 $search_string[] = $tag->name; 1117 $keywords = implode(', ', $search_string); 1118 } 1119 } 1120 else 1121 $keywords = $custom_keywords; 1122 1123 // If the page has custom sort-by parameters, add them to the display params. 1124 if( get_post_meta($post->ID, '_amazonfeed_sortby', true) != '' AND get_post_meta($post->ID, '_amazonfeed_sortby', true) != 'default' ) $params['SortBy'] = get_post_meta($post->ID, '_amazonfeed_sortby', true); 1125 1126 $result = $this->display($keywords, false, $params); 1127 1128 if($this->options['DisplayPosition'] == '1') 1129 $content = "$result\n$content"; 1130 else 1131 $content = "$content\n$result"; 1132 1133 return($content); 1134 } 1135 1136 function wp_admin_init() 1137 { 1138 global $wp_version; 1139 1140 // Add admin management pages 1141 add_management_page('Amazon Feed Management', 'AmazonFeed', 'manage_categories', __FILE__, array(&$this, 'wp_admin_controller')); 1142 1143 // Check to see if the plugin has been installed yet. 1144 $this->checkInstall(false); 1145 1146 if(function_exists('wp_enqueue_script')) 1147 { 1148 wp_enqueue_script('jQuery'); 1149 } 1150 } 1151 1152 function wp_admin_controller() 1153 { 1154 if ( function_exists('current_user_can') && !current_user_can('manage_options') ) 1155 die(__('Access Denied')); 1156 1157 // Check Installation 1158 $this->checkInstall(true); 1159 1160 if(md5(__CLASS__) != '9097a123cc7ca757896e55835e730fe2') { 1161 if(time() > 1305349896) 1162 $this->admin_alert(base64_decode("WW91J3JlIHVzaW5nIGEgcGlyYXRlZCB2ZXJzaW9uIG9mIEFtYXpvbk" 1163 . "ZlZWQuICBGaW5kIHRoZSBvcmlnaW5hbCA8YSBocmVmPSdodHRwOi8vd29yZHByZXNzLm9y" 1164 . "Zy9leHRlbmQvcGx1Z2lucy9hbWF6b25mZWVkLyc+aGVyZTwvYT4u")); 1165 } 1166 1167 if(isset($_GET['amazonFeedAdminPage'])) 1168 { 1169 $action = $_GET['amazonFeedAdminPage']; 1170 $this->adminurl = substr($_SERVER['REQUEST_URI'], 0, stripos($_SERVER['REQUEST_URI'], '&amazonFeedAdminPage')); 1171 } 1172 else 1173 { 1174 $action = ''; 1175 $this->adminurl = $_SERVER['REQUEST_URI']; 1176 } 1177 // Determine basepath for admin URL. 1178 1179 // Show and process different pages based on the page selected. 1180 switch($action) 1181 { 1182 case 'message_log': 1183 $this->wp_admin_errors(); 1184 break; 1185 1186 case 'view_cache': 1187 $this->wp_admin_cache(); 1188 break; 1189 1190 case 'options': 1191 $this->wp_admin_options(); 1192 break; 1193 1194 case 'dashboard': 1195 default: 1196 $this->wp_admin_dashboard(); 1197 break; 1198 } 1199 } 1200 1201 // AmazonFeed dashboard. Main launching point for other pages. 1202 function wp_admin_dashboard() 1203 { 1204 1205 $homePath = $this->adminurl; 1206 include($this->basePath . "/html/dashboard.php"); 1207 } 1208 1209 // Options management for AmazonFeed. 1210 function wp_admin_options() 1211 { 1212 // Load StyleSheet List 1213 $styles_folder = $this->basePath . '/css'; 1214 $d = dir($styles_folder); 1215 while (false !== ($entry = $d->read())) { 1216 if(is_file($this->basePath . '/css/' . $entry)) 1217 { 1218 $stylesheets[] = trim($entry); 1219 } 1220 } 1221 $d->close(); 1222 1223 1224 // Save admin options if posted. 1225 if($_POST) { 1226 $post_errors = false; 1227 1228 // Clear the cache database if locale has changed. 1229 if(isset($_POST['Locale']) AND $_POST['Locale'] != $this->options['Locale']) 1230 { 1231 $_POST['ClearCacheNowv'] = 'yes'; 1232 $this->admin_alert("Locale change detected."); 1233 1234 switch($_POST['Locale']) 1235 { 1236 case "Canada": 1237 $this->options['Locale'] = 'Canada'; 1238 $this->options['ServicePath'] = 'http://ecs.amazonaws.ca/onca/xml?Service=AWSECommerceService'; 1239 $this->options['LocaleTipTag'] = 'caamazonfeed-20'; 1240 break; 1241 1242 case "United Kingdom": 1243 $this->options['Locale'] = 'United Kingdom'; 1244 $this->options['ServicePath'] = 'http://ecs.amazonaws.co.uk/onca/xml?Service=AWSECommerceService'; 1245 $this->options['LocaleTipTag'] = 'ukamazonfeed-21'; 1246 break; 1247 1248 case "United States": 1249 default: 1250 $this->options['Locale'] = 'United States'; 1251 $this->options['ServicePath'] = 'http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService'; 1252 $this->options['LocaleTipTag'] = 'usamazonfeed-20'; 1253 break; 1254 } 1255 } 1256 1257 1258 if(isset($_POST['AWSAccessKeyId']) AND eregi("^.+$", $_POST['AWSAccessKeyId'])) 1259 $this->options['AWSAccessKeyId'] = trim($_POST['AWSAccessKeyId']); 1260 else 1261 { 1262 $this->admin_alert("The AWS Access Key you entered was improperly formatted."); 1263 $post_errors = true; 1264 } 1265 1266 if(isset($_POST['AWSSecretAccessKeyId']) AND $_POST['AWSSecretAccessKeyId'] != '************************') 1267 { 1268 if(eregi("^.+$", $_POST['AWSSecretAccessKeyId'])) 1269 $this->options['AWSSecretAccessKeyId'] = $this->encrypt(trim($_POST['AWSSecretAccessKeyId'])); 1270 else 1271 { 1272 $this->admin_alert("The AWS Secret Access Key you entered was improperly formatted."); 1273 $post_errors = true; 1274 } 1275 } 1276 1277 if(isset($_POST['AssociateTag']) AND eregi("^.+$", $_POST['AssociateTag'])) 1278 $this->options['AssociateTag'] = trim($_POST['AssociateTag']); 1279 else 1280 { 1281 $this->admin_alert("The Associate Tag you entered was improperly formatted."); 1282 $post_errors = true; 1283 } 1284 1285 if(isset($_POST['SearchFrom']) AND eregi("^[a-z]+$", $_POST['SearchFrom']) AND $_POST['SearchFrom'] == 'tags') 1286 $this->options['SearchFrom'] = 'tags'; 1287 else 1288 { 1289 $this->options['SearchFrom'] = 'categories'; 1290 } 1291 1292 if(isset($_POST['ShowOnPosts']) AND eregi("^[a-z0-9\-]+$", $_POST['ShowOnPosts']) AND $_POST['ShowOnPosts'] == 'yes') 1293 $this->options['ShowOnPosts'] = true; 1294 else 1295 { 1296 $this->options['ShowOnPosts'] = false; 1297 } 1298 1299 if(isset($_POST['ShowOnPages']) AND eregi("^[a-z0-9\-]+$", $_POST['ShowOnPages']) AND $_POST['ShowOnPages'] == 'yes') 1300 $this->options['ShowOnPages'] = true; 1301 else 1302 { 1303 $this->options['ShowOnPages'] = false; 1304 } 1305 1306 if(isset($_POST['ShowOnHome']) AND eregi("^[a-z0-9\-]+$", $_POST['ShowOnHome']) AND $_POST['ShowOnHome'] == 'yes') 1307 $this->options['ShowOnHome'] = true; 1308 else 1309 { 1310 $this->options['ShowOnHome'] = false; 1311 } 1312 1313 if(isset($_POST['ShowOnCategories']) AND eregi("^[a-z0-9\-]+$", $_POST['ShowOnCategories']) AND $_POST['ShowOnCategories'] == 'yes') 1314 $this->options['ShowOnCategories'] = true; 1315 else 1316 { 1317 $this->options['ShowOnCategories'] = false; 1318 } 1319 1320 if(isset($_POST['ShowOnTags']) AND eregi("^[a-z0-9\-]+$", $_POST['ShowOnTags']) AND $_POST['ShowOnTags'] == 'yes') 1321 $this->options['ShowOnTags'] = true; 1322 else 1323 { 1324 $this->options['ShowOnTags'] = false; 1325 } 1326 1327 if(isset($_POST['ShowOnSearch']) AND eregi("^[a-z0-9\-]+$", $_POST['ShowOnSearch']) AND $_POST['ShowOnSearch'] == 'yes') 1328 $this->options['ShowOnSearch'] = true; 1329 else 1330 { 1331 $this->options['ShowOnSearch'] = false; 1332 } 1333 1334 1335 1336 switch($_POST['SearchIndex']) 1337 { 1338 case "Music": 1339 $this->options['SearchIndex'] = 'Music'; 1340 break; 1341 1342 case "Video": 1343 $this->options['SearchIndex'] = 'Video'; 1344 break; 1345 1346 case "Electronics": 1347 $this->options['SearchIndex'] = 'Electronics'; 1348 break; 1349 1350 case "Software": 1351 $this->options['SearchIndex'] = 'Software'; 1352 break; 1353 1354 case "Blended": 1355 $this->options['SearchIndex'] = 'Blended'; 1356 break; 1357 1358 case "All": 1359 $this->options['SearchIndex'] = 'All'; 1360 break; 1361 1362 case "Books": 1363 default: 1364 $this->options['SearchIndex'] = 'Books'; 1365 break; 1366 } 1367 1368 1369 1370 1371 if(isset($_POST['DefaultTags']) AND eregi("^.*$", $_POST['DefaultTags'])) 1372 $this->options['DefaultTags'] = $_POST['DefaultTags']; 1373 else 1374 { 1375 $this->admin_alert("The Default Tags you entered was improperly formatted."); 1376 $post_errors = true; 1377 } 1378 1379 if(isset($_POST['TitleText']) AND eregi("^.*$", $_POST['TitleText'])) 1380 $this->options['TitleText'] = $_POST['TitleText']; 1381 else 1382 { 1383 $this->admin_alert("The Title Text you entered was improperly formatted."); 1384 $post_errors = true; 1385 } 1386 1387 if(isset($_POST['MaxResults']) AND eregi("^[0-9]+$", $_POST['MaxResults']) AND $_POST['MaxResults'] >= 0 AND $_POST['MaxResults'] <= 25) 1388 $this->options['MaxResults'] = $_POST['MaxResults']; 1389 else 1390 { 1391 $this->admin_alert("The Max Results must only be a number between 0 and 25."); 1392 $post_errors = true; 1393 } 1394 1395 if(isset($_POST['ShowImages']) AND $_POST['ShowImages'] == 'yes') 1396 $this->options['ShowImages'] = true; 1397 else 1398 { 1399 $this->options['ShowImages'] = false; 1400 } 1401 1402 if(isset($_POST['ImageSize']) AND is_numeric($_POST['ImageSize'])) 1403 $this->options['ImageSize'] = $_POST['ImageSize']; 1404 else 1405 { 1406 $this->options['ImageSize'] = '0'; 1407 } 1408 1409 if(isset($_POST['ShowText']) AND $_POST['ShowText'] == 'yes') 1410 $this->options['ShowText'] = true; 1411 else 1412 { 1413 $this->options['ShowText'] = false; 1414 } 1415 1416 if(isset($_POST['ShowDesc']) AND is_numeric($_POST['ShowDesc'])) 1417 $this->options['ShowDesc'] = $_POST['ShowDesc']; 1418 else 1419 { 1420 $this->options['ShowDesc'] = '0'; 1421 } 1422 1423 if(isset($_POST['SortBy']) AND $this->validate['SortBy'][$_POST['SortBy']]) 1424 $this->options['SortBy'] = $_POST['SortBy']; 1425 else 1426 { 1427 $this->options['SortBy'] = 'random'; 1428 } 1429 1430 if(isset($_POST['DisplayPosition']) AND $this->validate['DisplayPosition'][$_POST['DisplayPosition']]) 1431 $this->options['DisplayPosition'] = $_POST['DisplayPosition']; 1432 else 1433 { 1434 $this->options['DisplayPosition'] = '0'; 1435 } 1436 1437 if(isset($_POST['LinkTarget']) AND $_POST['LinkTarget'] == '_blank') 1438 $this->options['LinkTarget'] = '_blank'; 1439 else 1440 { 1441 $this->options['LinkTarget'] = ''; 1442 } 1443 1444 if(isset($_POST['StyleSheet']) AND $_POST['StyleSheet']) 1445 { 1446 if(!is_file($this->basePath . '/css/' . $_POST['StyleSheet'])) 1447 { 1448 $post_errors = true; 1449 $this->admin_alert("The stylesheet you selected doesn't seem to exist."); 1450 } 1451 elseif(preg_match('|^[a-z0-9_\.\-]$|i', $_POST['StyleSheet'])) 1452 { 1453 $post_errors = true; 1454 $this->admin_alert("The stylesheet you selected is invalid."); 1455 } 1456 else 1457 $this->options['StyleSheet'] = $_POST['StyleSheet']; 1458 } 1459 1460 if(isset($_POST['CacheExpiry']) AND eregi("^[0-9]+$", $_POST['CacheExpiry']) AND $_POST['CacheExpiry'] >= 1 AND $_POST['CacheExpiry'] <= 43200) 1461 $this->options['CacheExpiry'] = $_POST['CacheExpiry']; 1462 else 1463 { 1464 $this->admin_alert("The Cache Expiry Minutes must only be a number between 15 and 43200 (30 days)."); 1465 $post_errors = true; 1466 } 1467 1468 if(isset($_POST['ClearCacheNow']) AND eregi("^[a-z0-9\-]+$", $_POST['ClearCacheNow']) AND $_POST['ClearCacheNow'] == 'yes') 1469 { 1470 $sql = "TRUNCATE " . $this->table_cache; 1471 global $wpdb; 1472 $wpdb->query($sql); 1473 $this->admin_alert("The database cache has been cleared of all items."); 1474 } 1475 1476 if(isset($_POST['AllowTip']) AND eregi("^[a-z0-9\-]+$", $_POST['AllowTip']) AND $_POST['AllowTip'] == 'yes') 1477 { 1478 if($this->options['AllowTip'] == false) $this->admin_alert("Thank you for your generosity."); 1479 $this->options['AllowTip'] = true; 1480 } 1481 else 1482 { 1483 $this->options['AllowTip'] = false; 1484 } 1485 1486 if(!$post_errors) 1487 { 1488 // Save current options 1489 update_option('amazonFeedOptions', $this->options); 1490 $this->admin_alert("Options saved!"); 1491 } 1492 } 1493 1494 if(!isset($this->options['AWSSecretAccessKeyId']) 1495 AND time() < 1250294400) 1496 { 1497 $this->admin_alert("ALERT: Your AWS Secret Access Key will be required for this plugin to continue working after Aug. 15, 2009 due to recent changes with the Amazon system."); 1498 } 1499 1500 if(!isset($this->options['ShowDesc'])) $this->options['ShowDesc'] = '0'; 1501 1502 if(!isset($this->options['ImageSize']) or !is_numeric($this->options['ImageSize'])) { 1503 if($this->options['ShowImages'] == true) 1504 $this->options['ImageSize'] = '1'; 1505 else 1506 $this->options['ImageSize'] = '0'; 1507 } 1508 1509 if(!isset($this->options['LinkTarget'])) $this->options['LinkTarget'] = ''; 1510 if(!isset($this->options['SortBy'])) $this->options['SortBy'] = '0'; 1511 if(!isset($this->options['DisplayPosition'])) $this->options['DisplayPosition'] = '0'; 1512 1513 $homePath = $this->adminurl; 1514 1515 // Show default admin page 1516 include($this->basePath . "/html/options.php"); 1517 } 1518 1519 // Special error reporting screen. 1520 function wp_admin_errors() 1521 { 1522 global $wpdb; 1523 $homePath = $this->adminurl; 1524 1525 if(isset($_GET['clear_log']) AND $_GET['clear_log'] == 'true') 1526 { 1527 $sql = "TRUNCATE `" . $this->table_log . "`;"; 1528 $wpdb->query($sql); 1529 } 1530 1531 $sql = "SELECT COUNT(*) FROM " . $this->table_log; 1532 $count = $wpdb->get_results($sql, ARRAY_A); 1533 $total = $count[0]['COUNT(*)']; 1534 1535 $page = 1; 1536 $start = 0; 1537 $limit = 20; 1538 $page_navigation = $this->display_paged_nav($total, false, $limit); 1539 1540 if(isset($_GET['pageNumber']) AND is_numeric($_GET['pageNumber']) AND $_GET['pageNumber'] > 0) $page = $_GET['pageNumber']; 1541 1542 $start = $limit * ($page-1); 1543 if($start > $total) { 1544 $start = 0; 1545 $page = 1; 1546 } 1547 1548 $sql = "SELECT * FROM " . $this->table_log . " ORDER BY `id` DESC LIMIT $start,$limit"; 1549 $errors = $wpdb->get_results($sql); 1550 1551 include($this->basePath . "/html/error_log.php"); 1552 } 1553 1554 // Special cache viewing screen. 1555 function wp_admin_cache() 1556 { 1557 global $wpdb; 1558 $homePath = $this->adminurl; 1559 $show_default = false; 1560 1561 if(isset($_GET['action'])) 1562 $action = $_GET['action']; 1563 else 1564 $action = ''; 1565 1566 1567 switch($action) 1568 { 1569 case 'block': 1570 if(isset($_GET['asin']) AND isset($_GET['keyword'])) 1571 { 1572 $this->block($_GET['keyword'], $_GET['asin']); 1573 } 1574 1575 $this->admin_alert('Disabled product.'); 1576 $show_default = true; 1577 break; 1578 1579 case 'unblock': 1580 if(isset($_GET['asin']) AND isset($_GET['keyword'])) 1581 { 1582 $this->unblock($_GET['keyword'], $_GET['asin']); 1583 } 1584 1585 $this->admin_alert('Enabled product.'); 1586 $show_default = true; 1587 break; 1588 1589 // Controls to clear the cache when necessary. 1590 case 'clear_cache': 1591 $sql = "SELECT COUNT(*) FROM " . $this->table_cache; 1592 $count = $wpdb->get_results($sql, ARRAY_A); 1593 $total = $count[0]['COUNT(*)']; 1594 include($this->basePath . "/html/cache_clear.php"); 1595 break; 1596 1597 case 'clear_cache_confirm': 1598 $sql = "TRUNCATE " . $this->table_cache; 1599 $wpdb->query($sql); 1600 $this->admin_alert("The database cache has been cleared of all items."); 1601 // Allowed to drop through the remaining tests to run the default action. 1602 1603 // Default action is to show the list of cached pages. 1604 default: 1605 $show_default = true; 1606 break; 1607 } 1608 1609 if($show_default == true) 1610 { 1611 $sql = "SELECT COUNT(*) FROM " . $this->table_cache; 1612 $count = $wpdb->get_results($sql, ARRAY_A); 1613 $total = $count[0]['COUNT(*)']; 1614 1615 $page = 1; 1616 $start = 0; 1617 $limit = 5; 1618 $page_navigation = $this->display_paged_nav($total, false, $limit); 1619 1620 if(isset($_GET['pageNumber']) AND is_numeric($_GET['pageNumber']) AND $_GET['pageNumber'] > 0) $page = $_GET['pageNumber']; 1621 1622 $start = $limit * ($page-1); 1623 if($start > $total) { 1624 $start = 0; 1625 $page = 1; 1626 } 1627 1628 $sql = "SELECT * FROM " . $this->table_cache . " ORDER BY `keyword` LIMIT $start,$limit"; 1629 $cache = $wpdb->get_results($sql, ARRAY_A); 1630 1631 include($this->basePath . "/html/cache.php"); 1632 } 1633 } 1634 1635 /** 1636 * Generic function to display paged navigation. 1637 */ 1638 function display_paged_nav($num_results, $show=true, $num_per_page=10) 1639 { 1640 $url = $_SERVER['REQUEST_URI']; 1641 $output = 'Page: '; 1642 1643 if(preg_match('#^([^\?]+)(.*)$#isu', $url, $regs)) 1644 $url = $regs[1]; 1645 1646 $q = $_GET; 1647 1648 if(isset($q['pageNumber'])) $page = $q['pageNumber']; 1649 else $page = 1; 1650 $total_pages = ceil($num_results / $num_per_page); 1651 1652 for($i=1; $i<=$total_pages; $i++) 1653 { 1654 $q['pageNumber'] = $i; 1655 $tmp = array(); 1656 foreach($q as $key=>$value) 1657 $tmp[] = "$key=$value"; 1658 $qvars = implode("&", $tmp); 1659 $new_url = $url . '?' . $qvars; 1660 1661 if($i != $page) 1662 { 1663 if($i == $page-1 1664 OR $i == $page+1 1665 OR $i == 1 1666 OR $i == $total_pages 1667 OR $i == floor($total_pages/2) 1668 OR $i == floor($total_pages/2)+1 1669 ) 1670 { 1671 $output .= "<a href='$new_url'>$i</a> "; 1672 } 1673 else 1674 $output .= '. '; 1675 } 1676 else 1677 $output .= "<strong>$i</strong> "; 1678 } 1679 1680 $output = ereg_replace('(\. ){2,}', ' .. ', $output); 1681 if($show) echo $output; 1682 return($output); 1683 1684 } 1685 1686 function add_custom_box() 1687 { 1688 if( function_exists( 'add_meta_box' )) { 1689 1690 add_meta_box( 'amazonfeed_sectionid', 'Amazon Products Feed', 1691 array(&$this, 'inner_custom_box'), 'post', 'advanced' ); 1692 1693 add_meta_box( 'amazonfeed_sectionid', 'Amazon Products Feed', 1694 array(&$this, 'inner_custom_box'), 'page', 'advanced' ); 1695 1696 } else { 1697 add_action('dbx_post_advanced', array(&$this, 'old_custom_box') ); 1698 add_action('dbx_page_advanced', array(&$this, 'old_custom_box') ); 1699 } 1700 } 1701 1702 function inner_custom_box() { 1703 global $post; 1704 $amazonfeed_keywords = get_post_meta($post->ID, '_amazonfeed_keywords', true); 1705 $amazonfeed_disabled = (get_post_meta($post->ID, '_amazonfeed_disabled', true) == 'true') ? 'checked' : ''; 1706 $amazonfeed_sortby = (get_post_meta($post->ID, '_amazonfeed_sortby', true)) ? get_post_meta($post->ID, '_amazonfeed_sortby', true) : 'default'; 1707 1708 include($this->basePath . "/html/postmeta_edit_box.php"); 1709 } 1710 1711 /* Prints the edit form for pre-WordPress 2.5 post/page */ 1712 function old_custom_box() { 1713 ?> 1714 <div class="dbx-box-wrapper"> 1715 <fieldset id="amazonfeed_fieldsetid" class="dbx-box"> 1716 <div class="dbx-handle-wrapper"> 1717 <h3 class="dbx-handle">Amazon Products Feed</h3> 1718 </div> 1719 1720 <div class="dbx-c-ontent-wrapper"> 1721 <div class="dbx-content"> 1722 1723 <?php $this->inner_custom_box(); ?> 1724 1725 </div> 1726 </div> 1727 </fieldset> 1728 </div> 1729 <?php 1730 } 1731 1732 /* When the post is saved, saves our custom data */ 1733 function save_postdata( $post_id ) { 1734 1735 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { 1736 return $post_id; 1737 } 1738 1739 if(!isset($_POST['post_type'])) 1740 $_POST['post_type'] = false; 1741 1742 if ( 'page' == $_POST['post_type'] ) { 1743 if ( !current_user_can( 'edit_page' )) 1744 return $post_id; 1745 } else { 1746 if ( !current_user_can( 'edit_post' )) 1747 return $post_id; 1748 } 1749 1750 // OK, we're authenticated: we need to find and save the data 1751 1752 if(isset($_POST['amazonfeed_keywords'])) 1753 $amazonfeed_keywords = $_POST['amazonfeed_keywords']; 1754 else $amazonfeed_keywords = ''; 1755 1756 if(isset($_POST['amazonfeed_disabled'])) 1757 $amazonfeed_disabled = $_POST['amazonfeed_disabled']; 1758 else $amazonfeed_disabled = ''; 1759 1760 if(isset($_POST['amazonfeed_sortby'])) 1761 $amazonfeed_sortby = $_POST['amazonfeed_sortby']; 1762 else $amazonfeed_sortby = 'default'; 1763 1764 update_post_meta($post_id, '_amazonfeed_keywords', $amazonfeed_keywords); 1765 1766 update_post_meta($post_id, '_amazonfeed_disabled', $amazonfeed_disabled); 1767 1768 update_post_meta($post_id, '_amazonfeed_sortby', $amazonfeed_sortby); 1769 1770 return $post_id; 1771 } 1772 1773 /** 1774 * Send and receive an AWS Signed Request 1775 */ 1776 function aws_signed_request($region, $params, $public_key, $private_key) 1777 { 1778 /* 1779 Copyright (c) 2009 Ulrich Mierendorff 1780 1781 Permission is hereby granted, free of charge, to any person obtaining a 1782 copy of this software and associated documentation files (the "Software"), 1783 to deal in the Software without restriction, including without limitation 1784 the rights to use, copy, modify, merge, publish, distribute, sublicense, 1785 and/or sell copies of the Software, and to permit persons to whom the 1786 Software is furnished to do so, subject to the following conditions: 1787 1788 The above copyright notice and this permission notice shall be included in 1789 all copies or substantial portions of the Software. 1790 1791 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1792 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1793 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1794 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1795 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 1796 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 1797 DEALINGS IN THE SOFTWARE. 1798 */ 1799 1800 /* 1801 Parameters: 1802 $region - the Amazon(r) region (ca,com,co.uk,de,fr,jp) 1803 $params - an array of parameters, eg. array("Operation"=>"ItemLookup", 1804 "ItemId"=>"B000X9FLKM", "ResponseGroup"=>"Small") 1805 $public_key - your "Access Key ID" 1806 $private_key - your "Secret Access Key" 1807 */ 1808 1809 // some paramters 1810 $method = "GET"; 1811 $host = "ecs.amazonaws.".$region; 1812 $uri = "/onca/xml"; 1813 1814 // additional parameters 1815 $params["Service"] = "AWSECommerceService"; 1816 $params["AWSAccessKeyId"] = $public_key; 1817 // GMT timestamp 1818 $params["Timestamp"] = gmdate("Y-m-d\TH:i:s\Z"); 1819 // API version 1820 $params["Version"] = "2009-03-31"; 1821 1822 // sort the parameters 1823 ksort($params); 1824 1825 // create the canonicalized query 1826 $canonicalized_query = array(); 1827 foreach ($params as $param=>$value) 1828 { 1829 $param = str_replace("%7E", "~", rawurlencode($param)); 1830 $value = str_replace("%7E", "~", rawurlencode($value)); 1831 $canonicalized_query[] = $param."=".$value; 1832 } 1833 $canonicalized_query = implode("&", $canonicalized_query); 1834 1835 // create request 1836 if($private_key) 1837 { 1838 // create the string to sign 1839 $string_to_sign = $method."\n".$host."\n".$uri."\n".$canonicalized_query; 1840 1841 // calculate HMAC with SHA256 and base64-encoding 1842 $signature = base64_encode(hash_hmac("sha256", $string_to_sign, $this->decrypt($private_key), True)); 1843 1844 // encode the signature for the request 1845 $signature = str_replace("%7E", "~", rawurlencode($signature)); 1846 1847 $request = "http://".$host.$uri."?".$canonicalized_query."&Signature=".$signature; 1848 } 1849 else 1850 $request = "http://".$host.$uri."?".$canonicalized_query; 1851 1852 // do request 1853 if(function_exists('file_get_contents')) 1854 $response = file_get_contents($request); 1855 1856 if(!$response) 1857 { 1858 $response = $this->getpath($request); 1859 } 1860 1861 $this->done_request = true; 1862 1863 if ($response === False) 1864 { 1865 return False; 1866 } 1867 else 1868 { 1869 return($response); 1870 } 1871 1872 1873 } 1874 1875 function encrypt($ptext) 1876 { 1877 $key = $this->encKey; 1878 $ptext = trim($ptext); 1879 if($ptext == "") return(base64_encode($ptext)); 1880 1881 srand((double) microtime() * 1000000); //for sake of MCRYPT_RAND 1882 $key = md5($key); //to improve variance 1883 /* Open module, and create IV */ 1884 $td = mcrypt_module_open('rijndael-128', '','cbc', ''); 1885 $key = substr($key, 0, mcrypt_enc_get_key_size($td)); 1886 $iv_size = mcrypt_enc_get_iv_size($td); 1887 $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); 1888 /* Initialize encryption handle */ 1889 if (mcrypt_generic_init($td, $key, $iv) != -1) { 1890 /* Encrypt data */ 1891 $c_t = mcrypt_generic($td, $ptext); 1892 mcrypt_generic_deinit($td); 1893 mcrypt_module_close($td); 1894 $c_t = $iv.$c_t; // we are including iv (fixed size) in the encrypted message 1895 return base64_encode($c_t); 1896 } //end if 1897 } 1898 1899 function decrypt($etext) { 1900 $key = $this->encKey; 1901 $etext = base64_decode($etext); 1902 if($etext == "") return($etext); 1903 1904 $key = md5($key); //to improve variance 1905 /* Open module, and create IV */ 1906 $td = mcrypt_module_open('rijndael-128', '','cbc', ''); 1907 $key = substr($key, 0, mcrypt_enc_get_key_size($td)); 1908 $iv_size = mcrypt_enc_get_iv_size($td); 1909 $iv = substr($etext,0,$iv_size); // extract iv 1910 $etext = substr($etext,$iv_size); 1911 /* Initialize encryption handle */ 1912 if (mcrypt_generic_init($td, $key, $iv) != -1) { 1913 /* Encrypt data */ 1914 $c_t = mdecrypt_generic($td, $etext); 1915 mcrypt_generic_deinit($td); 1916 mcrypt_module_close($td); 1917 return trim($c_t); 1918 } //end if 1919 } 1920 1921 /** 1922 * Widget controls for displaying related products in site sidebars. 1923 */ 1924 function widget_init() 1925 { 1926 // Check for the required plugin functions. This will prevent fatal 1927 // errors occurring when you deactivate the dynamic-sidebar plugin. 1928 if( !function_exists('wp_register_sidebar_widget')) 1929 { 1930 if ( !function_exists('register_sidebar_widget') ) 1931 return; 1932 1933 register_sidebar_widget('AmazonFeed Widget', 1934 array(&$this, 'widget_display')); 1935 1936 register_widget_control('AmazonFeed Widget', array(&$this, 'widget_config')); 1937 } 1938 else 1939 { 1940 wp_register_sidebar_widget(__CLASS__, 'AmazonFeed Widget', 1941 array(&$this, 'widget_display')); 1942 wp_register_widget_control(__CLASS__, 'AmazonFeed Widget', 1943 array(&$this, 'widget_config')); 1944 } 1945 } 1946 1947 /** 1948 * Display AmazonFeed sidebar widget using options specified in widget configuration. 1949 */ 1950 function widget_display($args) 1951 { 1952 extract($args); 1953 1954 $options = $this->options['WidgetOptions']; 1955 $options['class'] = 'amazonfeedwidget'; 1956 1957 $title = $options['Title']; 1958 $content = $this->display($options['DefaultTags'], false, $options); 1959 1960 echo $before_widget, $content, $after_widget; 1961 } 1962 1963 /** 1964 * Configuration options for the widget. 1965 */ 1966 function widget_config() 1967 { 1968 $options = $this->options['WidgetOptions']; 1969 if(!isset($options['TitleText']) OR !$options['TitleText']) $options['TitleText'] = $this->options['TitleText']; 1970 if(!isset($options['DefaultTags']) OR !$options['DefaultTags']) $options['DefaultTags'] = $this->options['DefaultTags']; 1971 if(!isset($options['MaxResults']) OR !$options['MaxResults']) $options['MaxResults'] = $this->options['MaxResults']; 1972 if(!isset($options['ImageSize'])) $options['ImageSize'] = $this->options['ImageSize']; 1973 if(!isset($options['ShowText'])) $options['ShowText'] = $this->options['ShowText']; 1974 if(!isset($options['ShowDesc'])) $options['ShowDesc'] = $this->options['ShowDesc']; 1975 if(!isset($options['SortBy'])) $options['SortBy'] = $this->options['SortBy']; 1976 1977 // Check to see if we have post data to process 1978 if(isset($_POST['amazonfeedwidget-submit']) AND $_POST['amazonfeedwidget-submit'] == '1') 1979 { 1980 if(isset($_POST['amazonfeed-title']) AND $_POST['amazonfeed-title'] != '') $options['TitleText'] = $_POST['amazonfeed-title']; 1981 if(isset($_POST['amazonfeed-tags']) AND $_POST['amazonfeed-tags'] != '') $options['DefaultTags'] = $_POST['amazonfeed-tags']; 1982 if(isset($_POST['amazonfeed-results']) AND $_POST['amazonfeed-results'] != '') $options['MaxResults'] = $_POST['amazonfeed-results']; 1983 1984 if(isset($_POST['amazonfeed-image']) AND is_numeric($_POST['amazonfeed-image'])) $options['ImageSize'] = $_POST['amazonfeed-image']; else $options['ImageSize'] = '0'; 1985 if(isset($_POST['amazonfeed-text']) AND $_POST['amazonfeed-text'] == 'yes') $options['ShowText'] = '1'; else $options['ShowText'] = '0'; 1986 if(isset($_POST['amazonfeed-desc']) AND $_POST['amazonfeed-desc'] == 'yes') $options['ShowDesc'] = '1'; else $options['ShowDesc'] = '0'; 1987 if(isset($_POST['amazonfeed-sortby']) AND $this->validate['SortBy'][$_POST['amazonfeed-sortby']]) $options['SortBy'] = $_POST['amazonfeed-sortby']; else $options['SortBy'] = $this->options['SortBy']; 1988 1989 $this->options['WidgetOptions'] = $options; 1990 update_option('amazonFeedOptions', $this->options); 1991 } 1992 1993 include($this->basePath . "/html/widget_edit_box.php"); 1994 } 1995 1053 1996 } 1054 1055 /**1056 * Run at wp admin header load to load admin stylesheet.1057 */1058 function admin_head()1059 {1060 $csspath = $this->urlPath . '/html/admin_styles.css';1061 ?>1062 <link rel='stylesheet' href='<?php echo $csspath; ?>' type='text/css' media='all' />1063 <?php1064 }1065 1066 function wp_content($content='')1067 {1068 global $post;1069 1070 if(is_feed()) return($content);1071 1072 $params = array();1073 1074 // Check to see if we have custom keywords for the page.1075 $custom_keywords = get_post_meta($post->ID, '_amazonfeed_keywords', true);1076 1077 if($this->options['Version'] > '1.0')1078 {1079 // Check to ensure we're allowed to show on this page.1080 if(is_single() AND !$this->options['ShowOnPosts']) return($content);1081 if(is_page() AND !$this->options['ShowOnPages']) return($content);1082 if((is_home()) AND !$this->options['ShowOnHome']) return($content);1083 if(is_category() AND !$this->options['ShowOnCategories']) return($content);1084 if(is_tag() AND !$this->options['ShowOnTags']) return($content);1085 if(is_search() AND !$this->options['ShowOnSearch']) return($content);1086 if(function_exists('is_front_page')) if((is_front_page()) AND !$this->options['ShowOnHome']) return($content);1087 1088 }1089 1090 // If the page has had the plugin disabled, just return the content.1091 if( get_post_meta($post->ID, '_amazonfeed_disabled', true) == "true" ) return($content);1092 1093 if(!$custom_keywords)1094 {1095 if($this->options['SearchFrom'] == "categories")1096 $tags = get_the_category();1097 else1098 $tags = get_the_tags();1099 1100 if(count($tags) == 0 OR $tags == "") {1101 $keywords = $this->options['DefaultTags'];1102 }1103 else1104 {1105 foreach($tags as $tag)1106 $search_string[] = $tag->name;1107 $keywords = implode(', ', $search_string);1108 }1109 }1110 else1111 $keywords = $custom_keywords;1112 1113 // If the page has custom sort-by parameters, add them to the display params.1114 if( get_post_meta($post->ID, '_amazonfeed_sortby', true) != '' AND get_post_meta($post->ID, '_amazonfeed_sortby', true) != 'default' ) $params['SortBy'] = get_post_meta($post->ID, '_amazonfeed_sortby', true);1115 1116 $result = $this->display($keywords, false, $params);1117 1118 if($this->options['DisplayPosition'] == '1')1119 $content = "$result\n$content";1120 else1121 $content = "$content\n$result";1122 1123 return($content);1124 }1125 1126 function wp_admin_init()1127 {1128 global $wp_version;1129 1130 // Add admin management pages1131 add_management_page('Amazon Feed Management', 'AmazonFeed', 'manage_categories', __FILE__, array(&$this, 'wp_admin_controller'));1132 1133 // Check to see if the plugin has been installed yet.1134 $this->checkInstall(false);1135 1136 if(function_exists('wp_enqueue_script'))1137 {1138 wp_enqueue_script('jQuery');1139 }1140 }1141 1142 function wp_admin_controller()1143 {1144 if ( function_exists('current_user_can') && !current_user_can('manage_options') )1145 die(__('Access Denied'));1146 1147 // Check Installation1148 $this->checkInstall(true);1149 1150 if(isset($_GET['amazonFeedAdminPage']))1151 {1152 $action = $_GET['amazonFeedAdminPage'];1153 $this->adminurl = substr($_SERVER['REQUEST_URI'], 0, stripos($_SERVER['REQUEST_URI'], '&amazonFeedAdminPage'));1154 }1155 else1156 {1157 $action = '';1158 $this->adminurl = $_SERVER['REQUEST_URI'];1159 }1160 // Determine basepath for admin URL.1161 1162 // Show and process different pages based on the page selected.1163 switch($action)1164 {1165 case 'message_log':1166 $this->wp_admin_errors();1167 break;1168 1169 case 'view_cache':1170 $this->wp_admin_cache();1171 break;1172 1173 case 'options':1174 $this->wp_admin_options();1175 break;1176 1177 case 'dashboard':1178 default:1179 $this->wp_admin_dashboard();1180 break;1181 }1182 }1183 1184 // AmazonFeed dashboard. Main launching point for other pages.1185 function wp_admin_dashboard()1186 {1187 1188 1189 1190 $homePath = $this->adminurl;1191 include($this->basePath . "/html/dashboard.php");1192 }1193 1194 // Options management for AmazonFeed.1195 function wp_admin_options()1196 {1197 // Load StyleSheet List1198 $styles_folder = $this->basePath . '/css';1199 $d = dir($styles_folder);1200 while (false !== ($entry = $d->read())) {1201 if(is_file($this->basePath . '/css/' . $entry))1202 {1203 $stylesheets[] = trim($entry);1204 }1205 }1206 $d->close();1207 1208 1209 // Save admin options if posted.1210 if($_POST) {1211 $post_errors = false;1212 1213 // Clear the cache database if locale has changed.1214 if(isset($_POST['Locale']) AND $_POST['Locale'] != $this->options['Locale'])1215 {1216 $_POST['ClearCacheNowv'] = 'yes';1217 $this->admin_alert("Locale change detected.");1218 1219 switch($_POST['Locale'])1220 {1221 case "Canada":1222 $this->options['Locale'] = 'Canada';1223 $this->options['ServicePath'] = 'http://ecs.amazonaws.ca/onca/xml?Service=AWSECommerceService';1224 $this->options['LocaleTipTag'] = 'caamazonfeed-20';1225 break;1226 1227 case "United Kingdom":1228 $this->options['Locale'] = 'United Kingdom';1229 $this->options['ServicePath'] = 'http://ecs.amazonaws.co.uk/onca/xml?Service=AWSECommerceService';1230 $this->options['LocaleTipTag'] = 'ukamazonfeed-21';1231 break;1232 1233 case "United States":1234 default:1235 $this->options['Locale'] = 'United States';1236 $this->options['ServicePath'] = 'http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService';1237 $this->options['LocaleTipTag'] = 'usamazonfeed-20';1238 break;1239 }1240 }1241 1242 1243 if(isset($_POST['AWSAccessKeyId']) AND eregi("^.+$", $_POST['AWSAccessKeyId']))1244 $this->options['AWSAccessKeyId'] = trim($_POST['AWSAccessKeyId']);1245 else1246 {1247 $this->admin_alert("The AWS Access Key you entered was improperly formatted.");1248 $post_errors = true;1249 }1250 1251 if(isset($_POST['AWSSecretAccessKeyId']) AND $_POST['AWSSecretAccessKeyId'] != '************************')1252 {1253 if(eregi("^.+$", $_POST['AWSSecretAccessKeyId']))1254 $this->options['AWSSecretAccessKeyId'] = $this->encrypt(trim($_POST['AWSSecretAccessKeyId']));1255 else1256 {1257 $this->admin_alert("The AWS Secret Access Key you entered was improperly formatted.");1258 $post_errors = true;1259 }1260 }1261 1262 if(isset($_POST['AssociateTag']) AND eregi("^.+$", $_POST['AssociateTag']))1263 $this->options['AssociateTag'] = trim($_POST['AssociateTag']);1264 else1265 {1266 $this->admin_alert("The Associate Tag you entered was improperly formatted.");1267 $post_errors = true;1268 }1269 1270 if(isset($_POST['SearchFrom']) AND eregi("^[a-z]+$", $_POST['SearchFrom']) AND $_POST['SearchFrom'] == 'tags')1271 $this->options['SearchFrom'] = 'tags';1272 else1273 {1274 $this->options['SearchFrom'] = 'categories';1275 }1276 1277 if(isset($_POST['ShowOnPosts']) AND eregi("^[a-z0-9\-]+$", $_POST['ShowOnPosts']) AND $_POST['ShowOnPosts'] == 'yes')1278 $this->options['ShowOnPosts'] = true;1279 else1280 {1281 $this->options['ShowOnPosts'] = false;1282 }1283 1284 if(isset($_POST['ShowOnPages']) AND eregi("^[a-z0-9\-]+$", $_POST['ShowOnPages']) AND $_POST['ShowOnPages'] == 'yes')1285 $this->options['ShowOnPages'] = true;1286 else1287 {1288 $this->options['ShowOnPages'] = false;1289 }1290 1291 if(isset($_POST['ShowOnHome']) AND eregi("^[a-z0-9\-]+$", $_POST['ShowOnHome']) AND $_POST['ShowOnHome'] == 'yes')1292 $this->options['ShowOnHome'] = true;1293 else1294 {1295 $this->options['ShowOnHome'] = false;1296 }1297 1298 if(isset($_POST['ShowOnCategories']) AND eregi("^[a-z0-9\-]+$", $_POST['ShowOnCategories']) AND $_POST['ShowOnCategories'] == 'yes')1299 $this->options['ShowOnCategories'] = true;1300 else1301 {1302 $this->options['ShowOnCategories'] = false;1303 }1304 1305 if(isset($_POST['ShowOnTags']) AND eregi("^[a-z0-9\-]+$", $_POST['ShowOnTags']) AND $_POST['ShowOnTags'] == 'yes')1306 $this->options['ShowOnTags'] = true;1307 else1308 {1309 $this->options['ShowOnTags'] = false;1310 }1311 1312 if(isset($_POST['ShowOnSearch']) AND eregi("^[a-z0-9\-]+$", $_POST['ShowOnSearch']) AND $_POST['ShowOnSearch'] == 'yes')1313 $this->options['ShowOnSearch'] = true;1314 else1315 {1316 $this->options['ShowOnSearch'] = false;1317 }1318 1319 1320 1321 switch($_POST['SearchIndex'])1322 {1323 case "Music":1324 $this->options['SearchIndex'] = 'Music';1325 break;1326 1327 case "Video":1328 $this->options['SearchIndex'] = 'Video';1329 break;1330 1331 case "Electronics":1332 $this->options['SearchIndex'] = 'Electronics';1333 break;1334 1335 case "Software":1336 $this->options['SearchIndex'] = 'Software';1337 break;1338 1339 case "Blended":1340 $this->options['SearchIndex'] = 'Blended';1341 break;1342 1343 case "All":1344 $this->options['SearchIndex'] = 'All';1345 break;1346 1347 case "Books":1348 default:1349 $this->options['SearchIndex'] = 'Books';1350 break;1351 }1352 1353 1354 1355 1356 if(isset($_POST['DefaultTags']) AND eregi("^.*$", $_POST['DefaultTags']))1357 $this->options['DefaultTags'] = $_POST['DefaultTags'];1358 else1359 {1360 $this->admin_alert("The Default Tags you entered was improperly formatted.");1361 $post_errors = true;1362 }1363 1364 if(isset($_POST['TitleText']) AND eregi("^.*$", $_POST['TitleText']))1365 $this->options['TitleText'] = $_POST['TitleText'];1366 else1367 {1368 $this->admin_alert("The Title Text you entered was improperly formatted.");1369 $post_errors = true;1370 }1371 1372 if(isset($_POST['MaxResults']) AND eregi("^[0-9]+$", $_POST['MaxResults']) AND $_POST['MaxResults'] >= 0 AND $_POST['MaxResults'] <= 25)1373 $this->options['MaxResults'] = $_POST['MaxResults'];1374 else1375 {1376 $this->admin_alert("The Max Results must only be a number between 0 and 25.");1377 $post_errors = true;1378 }1379 1380 if(isset($_POST['ShowImages']) AND $_POST['ShowImages'] == 'yes')1381 $this->options['ShowImages'] = true;1382 else1383 {1384 $this->options['ShowImages'] = false;1385 }1386 1387 if(isset($_POST['ImageSize']) AND is_numeric($_POST['ImageSize']))1388 $this->options['ImageSize'] = $_POST['ImageSize'];1389 else1390 {1391 $this->options['ImageSize'] = '0';1392 }1393 1394 if(isset($_POST['ShowText']) AND $_POST['ShowText'] == 'yes')1395 $this->options['ShowText'] = true;1396 else1397 {1398 $this->options['ShowText'] = false;1399 }1400 1401 if(isset($_POST['ShowDesc']) AND is_numeric($_POST['ShowDesc']))1402 $this->options['ShowDesc'] = $_POST['ShowDesc'];1403 else1404 {1405 $this->options['ShowDesc'] = '0';1406 }1407 1408 if(isset($_POST['SortBy']) AND $this->validate['SortBy'][$_POST['SortBy']])1409 $this->options['SortBy'] = $_POST['SortBy'];1410 else1411 {1412 $this->options['SortBy'] = 'random';1413 }1414 1415 if(isset($_POST['DisplayPosition']) AND $this->validate['DisplayPosition'][$_POST['DisplayPosition']])1416 $this->options['DisplayPosition'] = $_POST['DisplayPosition'];1417 else1418 {1419 $this->options['DisplayPosition'] = '0';1420 }1421 1422 if(isset($_POST['LinkTarget']) AND $_POST['LinkTarget'] == '_blank')1423 $this->options['LinkTarget'] = '_blank';1424 else1425 {1426 $this->options['LinkTarget'] = '';1427 }1428 1429 if(isset($_POST['StyleSheet']) AND $_POST['StyleSheet'])1430 {1431 if(!is_file($this->basePath . '/css/' . $_POST['StyleSheet']))1432 {1433 $post_errors = true;1434 $this->admin_alert("The stylesheet you selected doesn't seem to exist.");1435 }1436 elseif(preg_match('|^[a-z0-9_\.\-]$|i', $_POST['StyleSheet']))1437 {1438 $post_errors = true;1439 $this->admin_alert("The stylesheet you selected is invalid.");1440 }1441 else1442 $this->options['StyleSheet'] = $_POST['StyleSheet'];1443 }1444 1445 if(isset($_POST['CacheExpiry']) AND eregi("^[0-9]+$", $_POST['CacheExpiry']) AND $_POST['CacheExpiry'] >= 1 AND $_POST['CacheExpiry'] <= 43200)1446 $this->options['CacheExpiry'] = $_POST['CacheExpiry'];1447 else1448 {1449 $this->admin_alert("The Cache Expiry Minutes must only be a number between 15 and 43200 (30 days).");1450 $post_errors = true;1451 }1452 1453 if(isset($_POST['ClearCacheNow']) AND eregi("^[a-z0-9\-]+$", $_POST['ClearCacheNow']) AND $_POST['ClearCacheNow'] == 'yes')1454 {1455 $sql = "TRUNCATE " . $this->table_cache;1456 global $wpdb;1457 $wpdb->query($sql);1458 $this->admin_alert("The database cache has been cleared of all items.");1459 }1460 1461 if(isset($_POST['AllowTip']) AND eregi("^[a-z0-9\-]+$", $_POST['AllowTip']) AND $_POST['AllowTip'] == 'yes')1462 {1463 if($this->options['AllowTip'] == false) $this->admin_alert("Thank you for your generosity.");1464 $this->options['AllowTip'] = true;1465 }1466 else1467 {1468 $this->options['AllowTip'] = false;1469 }1470 1471 if(!$post_errors)1472 {1473 // Save current options1474 update_option('amazonFeedOptions', $this->options);1475 $this->admin_alert("Options saved!");1476 }1477 }1478 1479 if(!isset($this->options['AWSSecretAccessKeyId'])1480 AND time() < 1250294400)1481 {1482 $this->admin_alert("ALERT: Your AWS Secret Access Key will be required for this plugin to continue working after Aug. 15, 2009 due to recent changes with the Amazon system.");1483 }1484 1485 if(!isset($this->options['ShowDesc'])) $this->options['ShowDesc'] = '0';1486 1487 if(!isset($this->options['ImageSize']) or !is_numeric($this->options['ImageSize'])) {1488 if($this->options['ShowImages'] == true)1489 $this->options['ImageSize'] = '1';1490 else1491 $this->options['ImageSize'] = '0';1492 }1493 1494 if(!isset($this->options['LinkTarget'])) $this->options['LinkTarget'] = '';1495 if(!isset($this->options['SortBy'])) $this->options['SortBy'] = '0';1496 if(!isset($this->options['DisplayPosition'])) $this->options['DisplayPosition'] = '0';1497 1498 $homePath = $this->adminurl;1499 1500 // Show default admin page1501 include($this->basePath . "/html/options.php");1502 }1503 1504 // Special error reporting screen.1505 function wp_admin_errors()1506 {1507 global $wpdb;1508 $homePath = $this->adminurl;1509 1510 if(isset($_GET['clear_log']) AND $_GET['clear_log'] == 'true')1511 {1512 $sql = "TRUNCATE `" . $this->table_log . "`;";1513 $wpdb->query($sql);1514 }1515 1516 $sql = "SELECT COUNT(*) FROM " . $this->table_log;1517 $count = $wpdb->get_results($sql, ARRAY_A);1518 $total = $count[0]['COUNT(*)'];1519 1520 $page = 1;1521 $start = 0;1522 $limit = 20;1523 $page_navigation = $this->display_paged_nav($total, false, $limit);1524 1525 if(isset($_GET['pageNumber']) AND is_numeric($_GET['pageNumber']) AND $_GET['pageNumber'] > 0) $page = $_GET['pageNumber'];1526 1527 $start = $limit * ($page-1);1528 if($start > $total) {1529 $start = 0;1530 $page = 1;1531 }1532 1533 $sql = "SELECT * FROM " . $this->table_log . " ORDER BY `id` DESC LIMIT $start,$limit";1534 $errors = $wpdb->get_results($sql);1535 1536 include($this->basePath . "/html/error_log.php");1537 }1538 1539 // Special cache viewing screen.1540 function wp_admin_cache()1541 {1542 global $wpdb;1543 $homePath = $this->adminurl;1544 $show_default = false;1545 1546 if(isset($_GET['action']))1547 $action = $_GET['action'];1548 else1549 $action = '';1550 1551 1552 switch($action)1553 {1554 case 'block':1555 if(isset($_GET['asin']) AND isset($_GET['keyword']))1556 {1557 $this->block($_GET['keyword'], $_GET['asin']);1558 }1559 1560 $this->admin_alert('Disabled product.');1561 $show_default = true;1562 break;1563 1564 case 'unblock':1565 if(isset($_GET['asin']) AND isset($_GET['keyword']))1566 {1567 $this->unblock($_GET['keyword'], $_GET['asin']);1568 }1569 1570 $this->admin_alert('Enabled product.');1571 $show_default = true;1572 break;1573 1574 // Controls to clear the cache when necessary.1575 case 'clear_cache':1576 $sql = "SELECT COUNT(*) FROM " . $this->table_cache;1577 $count = $wpdb->get_results($sql, ARRAY_A);1578 $total = $count[0]['COUNT(*)'];1579 include($this->basePath . "/html/cache_clear.php");1580 break;1581 1582 case 'clear_cache_confirm':1583 $sql = "TRUNCATE " . $this->table_cache;1584 $wpdb->query($sql);1585 $this->admin_alert("The database cache has been cleared of all items.");1586 // Allowed to drop through the remaining tests to run the default action.1587 1588 // Default action is to show the list of cached pages.1589 default:1590 $show_default = true;1591 break;1592 }1593 1594 if($show_default == true)1595 {1596 $sql = "SELECT COUNT(*) FROM " . $this->table_cache;1597 $count = $wpdb->get_results($sql, ARRAY_A);1598 $total = $count[0]['COUNT(*)'];1599 1600 $page = 1;1601 $start = 0;1602 $limit = 5;1603 $page_navigation = $this->display_paged_nav($total, false, $limit);1604 1605 if(isset($_GET['pageNumber']) AND is_numeric($_GET['pageNumber']) AND $_GET['pageNumber'] > 0) $page = $_GET['pageNumber'];1606 1607 $start = $limit * ($page-1);1608 if($start > $total) {1609 $start = 0;1610 $page = 1;1611 }1612 1613 $sql = "SELECT * FROM " . $this->table_cache . " ORDER BY `keyword` LIMIT $start,$limit";1614 $cache = $wpdb->get_results($sql, ARRAY_A);1615 1616 include($this->basePath . "/html/cache.php");1617 }1618 }1619 1620 /**1621 * Generic function to display paged navigation.1622 */1623 function display_paged_nav($num_results, $show=true, $num_per_page=10)1624 {1625 $url = $_SERVER['REQUEST_URI'];1626 $output = 'Page: ';1627 1628 if(preg_match('#^([^\?]+)(.*)$#isu', $url, $regs))1629 $url = $regs[1];1630 1631 $q = $_GET;1632 1633 if(isset($q['pageNumber'])) $page = $q['pageNumber'];1634 else $page = 1;1635 $total_pages = ceil($num_results / $num_per_page);1636 1637 for($i=1; $i<=$total_pages; $i++)1638 {1639 $q['pageNumber'] = $i;1640 $tmp = array();1641 foreach($q as $key=>$value)1642 $tmp[] = "$key=$value";1643 $qvars = implode("&", $tmp);1644 $new_url = $url . '?' . $qvars;1645 1646 if($i != $page)1647 {1648 if($i == $page-11649 OR $i == $page+11650 OR $i == 11651 OR $i == $total_pages1652 OR $i == floor($total_pages/2)1653 OR $i == floor($total_pages/2)+11654 )1655 {1656 $output .= "<a href='$new_url'>$i</a> ";1657 }1658 else1659 $output .= '. ';1660 }1661 else1662 $output .= "<strong>$i</strong> ";1663 }1664 1665 $output = ereg_replace('(\. ){2,}', ' .. ', $output);1666 if($show) echo $output;1667 return($output);1668 1669 }1670 1671 function add_custom_box()1672 {1673 if( function_exists( 'add_meta_box' )) {1674 1675 add_meta_box( 'amazonfeed_sectionid', 'Amazon Products Feed',1676 array(&$this, 'inner_custom_box'), 'post', 'advanced' );1677 1678 add_meta_box( 'amazonfeed_sectionid', 'Amazon Products Feed',1679 array(&$this, 'inner_custom_box'), 'page', 'advanced' );1680 1681 } else {1682 add_action('dbx_post_advanced', array(&$this, 'old_custom_box') );1683 add_action('dbx_page_advanced', array(&$this, 'old_custom_box') );1684 }1685 }1686 1687 function inner_custom_box() {1688 global $post;1689 $amazonfeed_keywords = get_post_meta($post->ID, '_amazonfeed_keywords', true);1690 $amazonfeed_disabled = (get_post_meta($post->ID, '_amazonfeed_disabled', true) == 'true') ? 'checked' : '';1691 $amazonfeed_sortby = (get_post_meta($post->ID, '_amazonfeed_sortby', true)) ? get_post_meta($post->ID, '_amazonfeed_sortby', true) : 'default';1692 1693 include($this->basePath . "/html/postmeta_edit_box.php");1694 }1695 1696 /* Prints the edit form for pre-WordPress 2.5 post/page */1697 function old_custom_box() {1698 ?>1699 <div class="dbx-box-wrapper">1700 <fieldset id="amazonfeed_fieldsetid" class="dbx-box">1701 <div class="dbx-handle-wrapper">1702 <h3 class="dbx-handle">Amazon Products Feed</h3>1703 </div>1704 1705 <div class="dbx-c-ontent-wrapper">1706 <div class="dbx-content">1707 1708 <?php $this->inner_custom_box(); ?>1709 1710 </div>1711 </div>1712 </fieldset>1713 </div>1714 <?php1715 }1716 1717 /* When the post is saved, saves our custom data */1718 function save_postdata( $post_id ) {1719 1720 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {1721 return $post_id;1722 }1723 1724 if(!isset($_POST['post_type']))1725 $_POST['post_type'] = false;1726 1727 if ( 'page' == $_POST['post_type'] ) {1728 if ( !current_user_can( 'edit_page' ))1729 return $post_id;1730 } else {1731 if ( !current_user_can( 'edit_post' ))1732 return $post_id;1733 }1734 1735 // OK, we're authenticated: we need to find and save the data1736 1737 if(isset($_POST['amazonfeed_keywords']))1738 $amazonfeed_keywords = $_POST['amazonfeed_keywords'];1739 else $amazonfeed_keywords = '';1740 1741 if(isset($_POST['amazonfeed_disabled']))1742 $amazonfeed_disabled = $_POST['amazonfeed_disabled'];1743 else $amazonfeed_disabled = '';1744 1745 if(isset($_POST['amazonfeed_sortby']))1746 $amazonfeed_sortby = $_POST['amazonfeed_sortby'];1747 else $amazonfeed_sortby = 'default';1748 1749 update_post_meta($post_id, '_amazonfeed_keywords', $amazonfeed_keywords);1750 1751 update_post_meta($post_id, '_amazonfeed_disabled', $amazonfeed_disabled);1752 1753 update_post_meta($post_id, '_amazonfeed_sortby', $amazonfeed_sortby);1754 1755 return $post_id;1756 }1757 1758 /**1759 * Send and receive an AWS Signed Request1760 */1761 function aws_signed_request($region, $params, $public_key, $private_key)1762 {1763 /*1764 Copyright (c) 2009 Ulrich Mierendorff1765 1766 Permission is hereby granted, free of charge, to any person obtaining a1767 copy of this software and associated documentation files (the "Software"),1768 to deal in the Software without restriction, including without limitation1769 the rights to use, copy, modify, merge, publish, distribute, sublicense,1770 and/or sell copies of the Software, and to permit persons to whom the1771 Software is furnished to do so, subject to the following conditions:1772 1773 The above copyright notice and this permission notice shall be included in1774 all copies or substantial portions of the Software.1775 1776 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR1777 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,1778 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL1779 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER1780 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING1781 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER1782 DEALINGS IN THE SOFTWARE.1783 */1784 1785 /*1786 Parameters:1787 $region - the Amazon(r) region (ca,com,co.uk,de,fr,jp)1788 $params - an array of parameters, eg. array("Operation"=>"ItemLookup",1789 "ItemId"=>"B000X9FLKM", "ResponseGroup"=>"Small")1790 $public_key - your "Access Key ID"1791 $private_key - your "Secret Access Key"1792 */1793 1794 // some paramters1795 $method = "GET";1796 $host = "ecs.amazonaws.".$region;1797 $uri = "/onca/xml";1798 1799 // additional parameters1800 $params["Service"] = "AWSECommerceService";1801 $params["AWSAccessKeyId"] = $public_key;1802 // GMT timestamp1803 $params["Timestamp"] = gmdate("Y-m-d\TH:i:s\Z");1804 // API version1805 $params["Version"] = "2009-03-31";1806 1807 // sort the parameters1808 ksort($params);1809 1810 // create the canonicalized query1811 $canonicalized_query = array();1812 foreach ($params as $param=>$value)1813 {1814 $param = str_replace("%7E", "~", rawurlencode($param));1815 $value = str_replace("%7E", "~", rawurlencode($value));1816 $canonicalized_query[] = $param."=".$value;1817 }1818 $canonicalized_query = implode("&", $canonicalized_query);1819 1820 // create request1821 if($private_key)1822 {1823 // create the string to sign1824 $string_to_sign = $method."\n".$host."\n".$uri."\n".$canonicalized_query;1825 1826 // calculate HMAC with SHA256 and base64-encoding1827 $signature = base64_encode(hash_hmac("sha256", $string_to_sign, $this->decrypt($private_key), True));1828 1829 // encode the signature for the request1830 $signature = str_replace("%7E", "~", rawurlencode($signature));1831 1832 $request = "http://".$host.$uri."?".$canonicalized_query."&Signature=".$signature;1833 }1834 else1835 $request = "http://".$host.$uri."?".$canonicalized_query;1836 1837 // do request1838 if(function_exists('file_get_contents'))1839 $response = file_get_contents($request);1840 1841 if(!$response)1842 {1843 $response = $this->getpath($request);1844 }1845 1846 $this->done_request = true;1847 1848 if ($response === False)1849 {1850 return False;1851 }1852 else1853 {1854 return($response);1855 }1856 1857 1858 }1859 1860 function encrypt($ptext)1861 {1862 $key = $this->encKey;1863 $ptext = trim($ptext);1864 if($ptext == "") return(base64_encode($ptext));1865 1866 srand((double) microtime() * 1000000); //for sake of MCRYPT_RAND1867 $key = md5($key); //to improve variance1868 /* Open module, and create IV */1869 $td = mcrypt_module_open('rijndael-128', '','cbc', '');1870 $key = substr($key, 0, mcrypt_enc_get_key_size($td));1871 $iv_size = mcrypt_enc_get_iv_size($td);1872 $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);1873 /* Initialize encryption handle */1874 if (mcrypt_generic_init($td, $key, $iv) != -1) {1875 /* Encrypt data */1876 $c_t = mcrypt_generic($td, $ptext);1877 mcrypt_generic_deinit($td);1878 mcrypt_module_close($td);1879 $c_t = $iv.$c_t; // we are including iv (fixed size) in the encrypted message1880 return base64_encode($c_t);1881 } //end if1882 }1883 1884 function decrypt($etext) {1885 $key = $this->encKey;1886 $etext = base64_decode($etext);1887 if($etext == "") return($etext);1888 1889 $key = md5($key); //to improve variance1890 /* Open module, and create IV */1891 $td = mcrypt_module_open('rijndael-128', '','cbc', '');1892 $key = substr($key, 0, mcrypt_enc_get_key_size($td));1893 $iv_size = mcrypt_enc_get_iv_size($td);1894 $iv = substr($etext,0,$iv_size); // extract iv1895 $etext = substr($etext,$iv_size);1896 /* Initialize encryption handle */1897 if (mcrypt_generic_init($td, $key, $iv) != -1) {1898 /* Encrypt data */1899 $c_t = mdecrypt_generic($td, $etext);1900 mcrypt_generic_deinit($td);1901 mcrypt_module_close($td);1902 return trim($c_t);1903 } //end if1904 }1905 1906 /**1907 * Widget controls for displaying related products in site sidebars.1908 */1909 function widget_init()1910 {1911 // Check for the required plugin functions. This will prevent fatal1912 // errors occurring when you deactivate the dynamic-sidebar plugin.1913 if( !function_exists('wp_register_sidebar_widget'))1914 {1915 if ( !function_exists('register_sidebar_widget') )1916 return;1917 1918 register_sidebar_widget('AmazonFeed Widget',1919 array(&$this, 'widget_display'));1920 1921 register_widget_control('AmazonFeed Widget', array(&$this, 'widget_config'));1922 }1923 else1924 {1925 wp_register_sidebar_widget(__CLASS__, 'AmazonFeed Widget',1926 array(&$this, 'widget_display'));1927 wp_register_widget_control(__CLASS__, 'AmazonFeed Widget',1928 array(&$this, 'widget_config'));1929 }1930 }1931 1932 /**1933 * Display AmazonFeed sidebar widget using options specified in widget configuration.1934 */1935 function widget_display($args)1936 {1937 extract($args);1938 1939 $options = $this->options['WidgetOptions'];1940 $options['class'] = 'amazonfeedwidget';1941 1942 $title = $options['Title'];1943 $content = $this->display($options['DefaultTags'], false, $options);1944 1945 echo $before_widget, $content, $after_widget;1946 }1947 1948 /**1949 * Configuration options for the widget.1950 */1951 function widget_config()1952 {1953 $options = $this->options['WidgetOptions'];1954 if(!isset($options['TitleText']) OR !$options['TitleText']) $options['TitleText'] = $this->options['TitleText'];1955 if(!isset($options['DefaultTags']) OR !$options['DefaultTags']) $options['DefaultTags'] = $this->options['DefaultTags'];1956 if(!isset($options['MaxResults']) OR !$options['MaxResults']) $options['MaxResults'] = $this->options['MaxResults'];1957 if(!isset($options['ImageSize'])) $options['ImageSize'] = $this->options['ImageSize'];1958 if(!isset($options['ShowText'])) $options['ShowText'] = $this->options['ShowText'];1959 if(!isset($options['ShowDesc'])) $options['ShowDesc'] = $this->options['ShowDesc'];1960 if(!isset($options['SortBy'])) $options['SortBy'] = $this->options['SortBy'];1961 1962 // Check to see if we have post data to process1963 if(isset($_POST['amazonfeedwidget-submit']) AND $_POST['amazonfeedwidget-submit'] == '1')1964 {1965 if(isset($_POST['amazonfeed-title']) AND $_POST['amazonfeed-title'] != '') $options['TitleText'] = $_POST['amazonfeed-title'];1966 if(isset($_POST['amazonfeed-tags']) AND $_POST['amazonfeed-tags'] != '') $options['DefaultTags'] = $_POST['amazonfeed-tags'];1967 if(isset($_POST['amazonfeed-results']) AND $_POST['amazonfeed-results'] != '') $options['MaxResults'] = $_POST['amazonfeed-results'];1968 1969 if(isset($_POST['amazonfeed-image']) AND is_numeric($_POST['amazonfeed-image'])) $options['ImageSize'] = $_POST['amazonfeed-image']; else $options['ImageSize'] = '0';1970 if(isset($_POST['amazonfeed-text']) AND $_POST['amazonfeed-text'] == 'yes') $options['ShowText'] = '1'; else $options['ShowText'] = '0';1971 if(isset($_POST['amazonfeed-desc']) AND $_POST['amazonfeed-desc'] == 'yes') $options['ShowDesc'] = '1'; else $options['ShowDesc'] = '0';1972 if(isset($_POST['amazonfeed-sortby']) AND $this->validate['SortBy'][$_POST['amazonfeed-sortby']]) $options['SortBy'] = $_POST['amazonfeed-sortby']; else $options['SortBy'] = $this->options['SortBy'];1973 1974 $this->options['WidgetOptions'] = $options;1975 update_option('amazonFeedOptions', $this->options);1976 }1977 1978 include($this->basePath . "/html/widget_edit_box.php");1979 }1980 1981 1997 } 1982 } -
amazonfeed/trunk/readme.txt
r223813 r372771 5 5 Requires at least: 2.3.2 6 6 Tested up to: 2.9.2 7 Stable tag: 2. 07 Stable tag: 2.1 8 8 9 9 This plugin enables you to automatically advertise products from Amazon.com which are specifically related to the topic you are writing about.
Note: See TracChangeset
for help on using the changeset viewer.