Plugin Directory

Changeset 372771


Ignore:
Timestamp:
04/14/2011 05:36:57 AM (15 years ago)
Author:
warkior
Message:

Preparing for 2.1 launch.

Location:
amazonfeed/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • amazonfeed/trunk/amazonfeed.php

    r222264 r372771  
    44Plugin URI: http://www.warkensoft.com/products/amazonfeed-wordpress-plugin/
    55Description: Make money from your blog by advertising Amazon.com products specifically related to the topic of your posts.
    6 Version: 2.0
     6Version: 2.1
    77Author: WarkenSoft Productions
    88Author URI: http://warkensoft.com/
  • amazonfeed/trunk/php/amazonfeed.class.php

    r372759 r372771  
    11<?php
    22
    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()
     3if(!class_exists("AmazonFeed"))
     4{
     5    class AmazonFeed
    776    {
    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 &gt; 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-&gt;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 &gt; 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   
    312152                $sql = "CREATE TABLE IF NOT EXISTS `" . $this->table_log . "` (
    313153                  `id` bigint(20) NOT NULL auto_increment,
     
    316156                  PRIMARY KEY  (`id`),
    317157                  KEY `timestamp` (`timestamp`)
    318                 ) ENGINE=MyISAM ;";
    319                 $result = $wpdb->query($sql);
     158                ) ENGINE=MyISAM ;"; 
     159                $result = $wpdb->query($sql); 
    320160                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);
    350175                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-&gt;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               
    505422                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);
    539442            }
    540443            else
    541444            {
    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)
    752757                        {
    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)
    794762                            {
    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;
    797766                            }
    798767                            else
    799768                            {
    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;
    802773                            }
    803774                        }
    804775                        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))
    805790                        {
    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                            }
    807818                        }
     819                        else
     820                            $this->debug("Unable to properly load XML string for word '$word'.");
    808821                    }
    809822                    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);
    861960                    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                    }
    880994                    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 &gt;</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                    }
    9761012                    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 &gt;</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';
    10491071            ?>
    10501072            <link rel='stylesheet' href='<?php echo $csspath; ?>' type='text/css' media='all' />
    10511073            <?php
    10521074        }
     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       
    10531996    }
    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         <?php
    1064     }
    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             else
    1098                 $tags = get_the_tags();
    1099 
    1100             if(count($tags) == 0 OR $tags == "") {
    1101                 $keywords = $this->options['DefaultTags'];
    1102             }
    1103             else
    1104             {
    1105                 foreach($tags as $tag)
    1106                     $search_string[] = $tag->name;
    1107                 $keywords = implode(', ', $search_string);
    1108             }
    1109         }
    1110         else
    1111             $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         else
    1121             $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 pages
    1131         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 Installation
    1148         $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         else
    1156         {
    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 List
    1198         $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             else
    1246             {
    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                 else
    1256                 {
    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             else
    1265             {
    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             else
    1273             {
    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             else
    1280             {
    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             else
    1287             {
    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             else
    1294             {
    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             else
    1301             {
    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             else
    1308             {
    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             else
    1315             {
    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             else
    1359             {
    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             else
    1367             {
    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             else
    1375             {
    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             else
    1383             {
    1384                 $this->options['ShowImages'] = false;
    1385             }
    1386 
    1387             if(isset($_POST['ImageSize']) AND is_numeric($_POST['ImageSize']))
    1388                 $this->options['ImageSize'] = $_POST['ImageSize'];
    1389             else
    1390             {
    1391                 $this->options['ImageSize'] = '0';
    1392             }
    1393 
    1394             if(isset($_POST['ShowText']) AND $_POST['ShowText'] == 'yes')
    1395                 $this->options['ShowText'] = true;
    1396             else
    1397             {
    1398                 $this->options['ShowText'] = false;
    1399             }
    1400 
    1401             if(isset($_POST['ShowDesc']) AND is_numeric($_POST['ShowDesc']))
    1402                 $this->options['ShowDesc'] = $_POST['ShowDesc'];
    1403             else
    1404             {
    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             else
    1411             {
    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             else
    1418             {
    1419                 $this->options['DisplayPosition'] = '0';
    1420             }
    1421 
    1422             if(isset($_POST['LinkTarget']) AND $_POST['LinkTarget'] == '_blank')
    1423                 $this->options['LinkTarget'] = '_blank';
    1424             else
    1425             {
    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                 else
    1442                     $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             else
    1448             {
    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             else
    1467             {
    1468                 $this->options['AllowTip'] = false;
    1469             }
    1470 
    1471             if(!$post_errors)
    1472             {
    1473                 // Save current options
    1474                 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             else
    1491                 $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 page
    1501         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         else
    1549             $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-1
    1649                     OR $i == $page+1
    1650                     OR $i == 1
    1651                     OR $i == $total_pages
    1652                     OR $i == floor($total_pages/2)
    1653                     OR $i == floor($total_pages/2)+1
    1654                     )
    1655                     {
    1656                         $output .= "<a href='$new_url'>$i</a> ";
    1657                     }
    1658                     else
    1659                         $output .= '. ';
    1660             }
    1661             else
    1662                 $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         <?php
    1715     }
    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 data
    1736 
    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 Request
    1760      */
    1761     function aws_signed_request($region, $params, $public_key, $private_key)
    1762     {
    1763         /*
    1764         Copyright (c) 2009 Ulrich Mierendorff
    1765    
    1766         Permission is hereby granted, free of charge, to any person obtaining a
    1767         copy of this software and associated documentation files (the "Software"),
    1768         to deal in the Software without restriction, including without limitation
    1769         the rights to use, copy, modify, merge, publish, distribute, sublicense,
    1770         and/or sell copies of the Software, and to permit persons to whom the
    1771         Software is furnished to do so, subject to the following conditions:
    1772    
    1773         The above copyright notice and this permission notice shall be included in
    1774         all copies or substantial portions of the Software.
    1775    
    1776         THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    1777         IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    1778         FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    1779         THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    1780         LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    1781         FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    1782         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 paramters
    1795         $method = "GET";
    1796         $host = "ecs.amazonaws.".$region;
    1797         $uri = "/onca/xml";
    1798        
    1799         // additional parameters
    1800         $params["Service"] = "AWSECommerceService";
    1801         $params["AWSAccessKeyId"] = $public_key;
    1802         // GMT timestamp
    1803         $params["Timestamp"] = gmdate("Y-m-d\TH:i:s\Z");
    1804         // API version
    1805         $params["Version"] = "2009-03-31";
    1806        
    1807         // sort the parameters
    1808         ksort($params);
    1809        
    1810         // create the canonicalized query
    1811         $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 request
    1821         if($private_key)
    1822         {
    1823             // create the string to sign
    1824             $string_to_sign = $method."\n".$host."\n".$uri."\n".$canonicalized_query;
    1825            
    1826             // calculate HMAC with SHA256 and base64-encoding
    1827             $signature = base64_encode(hash_hmac("sha256", $string_to_sign, $this->decrypt($private_key), True));
    1828            
    1829             // encode the signature for the request
    1830             $signature = str_replace("%7E", "~", rawurlencode($signature));
    1831            
    1832             $request = "http://".$host.$uri."?".$canonicalized_query."&Signature=".$signature;
    1833         }
    1834         else
    1835             $request = "http://".$host.$uri."?".$canonicalized_query;
    1836                    
    1837         // do request
    1838         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         else
    1853         {
    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_RAND
    1867         $key = md5($key); //to improve variance
    1868         /* 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 message
    1880             return base64_encode($c_t);
    1881        } //end if
    1882     }
    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 variance
    1890         /* 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 iv
    1895         $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 if
    1904     }
    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 fatal
    1912         // 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         else
    1924         {
    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 process
    1963         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    
    19811997}
    1982 }
  • amazonfeed/trunk/readme.txt

    r223813 r372771  
    55Requires at least: 2.3.2
    66Tested up to: 2.9.2
    7 Stable tag: 2.0
     7Stable tag: 2.1
    88
    99This 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.