/**
  * Performs paged API requests.
  * 
  * This enables to retrieve more than 10 items. However, for it, it performs multiple requests, thus, it will be slow.
  * 
  * @since            2.0.1
  */
 protected function getRequest($iCount)
 {
     $_oAPI = new AmazonAutoLinks_ProductAdvertisingAPI($this->arrArgs['country'], $this->oOption->getAccessPublicKey(), $this->oOption->getAccessPrivateKey(), $this->arrArgs['associate_id']);
     // First, perform the search for the first page regardless the specified count (number of items).
     // Keys with an empty value will be filtered out when performing the request.
     $_aResponse = $_oAPI->request($this->getAPIParameterArray($this->arrArgs['Operation']), '', $this->arrArgs['cache_duration']);
     if ($iCount <= 10) {
         return $_aResponse;
     }
     // Check necessary key is set
     if (!isset($_aResponse['Items']['Item']) || !is_array($_aResponse['Items']['Item'])) {
         return $_aResponse;
     }
     // Calculate the required number of pages.
     $_iPage = $this->_getTotalPageNumber($iCount, $_aResponse, $this->arrArgs['SearchIndex']);
     $_aResponseTrunk = $_aResponse;
     // First perform fetching data in the background if caches are not available. Parse backwards
     $_fScheduled = null;
     for ($_i = $_iPage; $_i >= 2; $_i--) {
         $_fResult = $_oAPI->scheduleInBackground($this->getAPIParameterArray($this->arrArgs['Operation'], $_i));
         $_fScheduled = $_fScheduled ? $_fScheduled : $_fResult;
     }
     if ($_fScheduled) {
         // there are items scheduled to fetch in the background, do it right now.
         AmazonAutoLinks_Shadow::gaze();
     }
     // Start from the second page since the first page has been already done.
     for ($_i = 2; $_i <= $_iPage; $_i++) {
         $_aResponse = $_oAPI->request($this->getAPIParameterArray($this->arrArgs['Operation'], $_i), '', $this->arrArgs['cache_duration']);
         if (isset($_aResponse['Items']['Item']) && is_array($_aResponse['Items']['Item'])) {
             $_aResponseTrunk['Items']['Item'] = $this->_addItems($_aResponseTrunk['Items']['Item'], $_aResponse['Items']['Item']);
         }
     }
     return $_aResponseTrunk;
 }
 /**
  * Schedules an action of getting product information in the background.
  * 
  * @since       3
  * @action      schedule        aal_action_api_get_product_info
  */
 public static function getProductInfo($sAssociateID, $sASIN, $sLocale, $iCacheDuration)
 {
     $_oOption = AmazonAutoLinks_Option::getInstance();
     if (!$_oOption->isAPIConnected()) {
         return false;
     }
     $_bScheduled = self::_scheduleTask('aal_action_api_get_product_info', array($sAssociateID, $sASIN, $sLocale, $iCacheDuration));
     if (!$_bScheduled) {
         return $_bScheduled;
     }
     // Loads the site in the background. The method takes care of doing it only once in the entire page load.
     AmazonAutoLinks_Shadow::see();
     return true;
 }
 /**
  * Triggers event actions.
  */
 public function __construct()
 {
     new AmazonAutoLinks_Event_HTTPCacheRenewal();
     new AmazonAutoLinks_Event_Action_SimplePie_CacheRenewal('aal_action_simplepie_renew_cache');
     new AmazonAutoLinks_Event_Action_UnitPrefetch('aal_action_unit_prefetch');
     new AmazonAutoLinks_Event_Action_ProductAdvertisingAPICacheRenewal('aal_action_api_transient_renewal');
     new AmazonAutoLinks_Event_Action_API_SearchProduct('aal_action_api_get_product_info');
     new AmazonAutoLinks_Event_Action_CustomerReview('aal_action_api_get_customer_review');
     new AmazonAutoLinks_Event_Action_TemplateOptionConverter('aal_action_event_convert_template_options', 2);
     // This must be called after the above action hooks are added.
     $_oOption = AmazonAutoLinks_Option::getInstance();
     $_bIsIntenceCachingMode = 'intense' === $_oOption->get('cache', 'chaching_mode');
     // Force executing actions.
     new AmazonAutoLinks_Shadow($_bIsIntenceCachingMode ? array('aal_action_unit_prefetch', 'aal_action_simplepie_renew_cache', 'aal_action_api_transient_renewal', 'aal_action_api_get_product_info', 'aal_action_api_get_customer_review', 'aal_action_http_cache_renewal') : array('aal_action_unit_prefetch', 'aal_action_api_get_product_info', 'aal_action_api_get_customer_review', 'aal_action_http_cache_renewal'));
     if (!$_bIsIntenceCachingMode) {
         if (AmazonAutoLinks_Shadow::isBackground()) {
             exit;
         }
     }
     $this->_handleQueryURL();
 }
 public function __construct()
 {
     // For SimplePie cache renewal events
     add_action('aal_action_simplepie_renew_cache', array($this, '_replyToRenewSimplePieCaches'));
     // For API transient (cache) renewal events
     add_action('aal_action_api_transient_renewal', array($this, '_replyToRenewAPITransients'));
     // This must be called after the above action hooks are added.
     if ('intense' == $GLOBALS['oAmazonAutoLinks_Option']->arrOptions['aal_settings']['cache']['chaching_mode']) {
         new AmazonAutoLinks_Shadow(array('aal_action_simplepie_renew_cache', 'aal_action_api_transient_renewal'));
     } else {
         if (AmazonAutoLinks_Shadow::isBackground()) {
             exit;
         }
     }
     // User ads redirects
     if (isset($_GET['amazon_auto_links_link']) && $_GET['amazon_auto_links_link']) {
         $_oRedirect = new AmazonAutoLinks_Redirects();
         $_oRedirect->go($_GET['amazon_auto_links_link']);
         // will exit there.
     }
     // Draw cached image.
     if (isset($_GET['amazon_auto_links_image']) && $_GET['amazon_auto_links_image'] && is_user_logged_in()) {
         $_oImageLoader = new AmazonAutoLinks_ImageHandler(AmazonAutoLinks_Commons::TransientPrefix);
         $_oImageLoader->draw($_GET['amazon_auto_links_image']);
         exit;
     }
     // For the activation hook
     add_action('aal_action_setup_transients', array($this, '_replyToSetUpTransients'));
     // Load styles of templates
     if (isset($_GET['amazon_auto_links_style'])) {
         $GLOBALS['oAmazonAutoLinks_Templates']->loadStyle($_GET['amazon_auto_links_style']);
     }
     // URL Cloak
     $_sQueryKey = $GLOBALS['oAmazonAutoLinks_Option']->arrOptions['aal_settings']['query']['cloak'];
     if (isset($_GET[$_sQueryKey])) {
         $this->_redirect($_GET[$_sQueryKey]);
     }
 }
 /**
  * 
  * @callback        action      shutdown
  */
 public function _replyToScheduleUpdatingCaches()
 {
     if (empty($GLOBALS['aAmazonAutoLinks_APIRequestURIs'])) {
         return;
     }
     $_iScheduled = 0;
     foreach ($GLOBALS['aAmazonAutoLinks_APIRequestURIs'] as $aExpiredCacheRequest) {
         // Schedules the action to run in the background with WP Cron.
         $_iScheduled += $this->_scheduleCacheRenewal($aExpiredCacheRequest);
     }
     if ($_iScheduled) {
         AmazonAutoLinks_Shadow::see();
     }
 }
 /**
  * Accesses the site in the background at the end of the script execution.
  * 
  * This is used to trigger cron events in the background and sets a static flag so that it ensures it is done only once per page load.
  * 
  * @since            1.0.0
  */
 public static function see($aGet = array(), $fIgnoreLock = false)
 {
     // WP Cron
     if (isset($_GET['doing_wp_cron'])) {
         return;
     }
     // WP Heart-beat API
     if (isset($GLOBALS['pagenow']) && $GLOBALS['pagenow'] == 'admin-ajax.php') {
         return;
     }
     // Ensures the task is done only once in a page load.
     static $_bIsCalled;
     if ($_bIsCalled) {
         return;
     }
     $_bIsCalled = true;
     // Store the static properties.
     self::$_fIgnoreLock = $fIgnoreLock ? $fIgnoreLock : self::$_fIgnoreLock;
     self::$_aGet = (array) $aGet + self::$_aGet;
     $_sSelfClassName = get_class();
     if (did_action('shutdown')) {
         self::_replyToAccessSite();
         return;
         // important as what the action has performed does not mean the action never will be fired again.
     }
     add_action('shutdown', "{$_sSelfClassName}::_replyToAccessSite", 999);
     // do not pass self::_replyToAccessSite.
 }