public function fetchFeed($vURLs, $numItems = 0, $fCacheRenew = false) { $arrURLs = is_array($vURLs) ? $vURLs : (array) $vURLs; $strURLID = md5(serialize($arrURLs)); if (!isset($this->arrFeedItems[$strURLID]) && $fCacheRenew == false) { $this->arrFeedItems[$strURLID] = (array) AmazonAutoLinks_WPUtilities::getTransient($this->strTransientPrefix . $strURLID); unset($this->arrFeedItems[$strURLID][0]); // casting array causes the 0 key, } // If it's out of stock, fill the array by fetching the feed. if (empty($this->arrFeedItems[$strURLID])) { // When an array of urls is passed to the Simple Pie's set_feed_url() method, the memory usage increases largely. // So fetch the feeds one by one per url and store the output into an array. foreach ($arrURLs as $strURL) { $oFeed = $this->getFeedObj($strURL, null, $fCacheRenew ? 0 : 3600); // foreach ( $oFeed->get_items( 0, $numItems * 3 ) as $item ) does not change the memory usage foreach ($oFeed->get_items() as $oItem) { $this->arrFeedItems[$strURLID][$oItem->get_title()] = array('strContent' => $oItem->get_content(), 'strDescription' => $oItem->get_description(), 'strTitle' => $oItem->get_title(), 'strDate' => $oItem->get_title(), 'strAuthor' => $oItem->get_date('j F Y, g:i a'), 'strLink' => $oItem->get_permalink()); } // For PHP below 5.3 to release the memory. $oFeed->__destruct(); // Do what PHP should be doing on it's own. unset($oFeed); } // This life span should be little longer than the feed cache life span, which is 1700. AmazonAutoLinks_WPUtilities::setTransient($this->strTransientPrefix . $strURLID, $this->arrFeedItems[$strURLID], 1800); // 30 minutes } $arrOut = $this->arrFeedItems[$strURLID]; if ($numItems) { array_splice($arrOut, ${$numItems}); } return $arrOut; }
public function validation_aal_add_category_unit_set_category_unit_options($aInput, $aOldInput) { // validation + _ + page slug + tab slug $_fVerified = true; $_aErrors = array(); // Check the limitation. if ($this->oOption->isUnitLimitReached()) { $this->setFieldErrors(array('error')); // must set an field error array which does not yield empty so that it won't be redirected. $this->setSettingNotice(sprintf(__('Please upgrade to <A href="%1$s">Pro</a> to add more units! Make sure to empty the <a href="%2$s">trash box</a> to delete the units completely!', 'amazon-auto-links'), 'http://en.michaeluno.jp/amazon-auto-links-pro/', admin_url('edit.php?post_status=trash&post_type=' . AmazonAutoLinks_Commons::PostTypeSlug))); return $aOldInput; } if (empty($aInput['aal_add_category_unit']['category']['category_associate_id'])) { $_aErrors['category']['category_associate_id'] = __('The associate ID cannot be empty.', 'amazon-auto-links'); $_fVerified = false; } // An invalid value is found. if (!$_fVerified) { // Set the error array for the input fields. $this->setFieldErrors($_aErrors); $this->setSettingNotice(__('There was an error in your input.', 'amazon-auto-links')); return $aOldInput; } // Drop the sections. $arrNewFields = array(); foreach ($aInput['aal_add_category_unit'] as $strSection => $arrFields) { $arrNewFields = $arrNewFields + $arrFields; } $arrSanitizedFields = array(); // Remove the category_ prefix in the keys. foreach ($arrNewFields as $strKey => $vValue) { $arrSanitizedFields[preg_replace('/^category_/', '', $strKey)] = $vValue; } $arrSanitizedFields['categories'] = array(); $arrSanitizedFields['categories_exclude'] = array(); $arrSanitizedFields = $this->oOption->sanitizeUnitOpitons($arrSanitizedFields); // If nothing is checked for the feed type, enable the bestseller item. if (!array_filter($arrSanitizedFields['feed_type'])) { $arrSanitizedFields['feed_type']['bestsellers'] = true; } $arrTempUnitOptions = (array) AmazonAutoLinks_WPUtilities::getTransient('AAL_CreateUnit_' . $arrSanitizedFields['transient_id']); AmazonAutoLinks_WPUtilities::setTransient('AAL_CreateUnit_' . $arrSanitizedFields['transient_id'], AmazonAutoLinks_Utilities::uniteArrays($arrSanitizedFields, $arrTempUnitOptions), 60 * 10 * 6 * 24); // AmazonAutoLinks_Debug::logArray( $arrSanitizedFields ); return $aInput; }
/** * The global page load * */ public function load_AmazonAutoLinks_AdminPage() { // Check the support rate and ads visibility if (!(isset($_GET['tab'], $_GET['bounce_url']) && $_GET['tab'] == 'support') && !$this->oOption->arrOptions['aal_settings']['support']['agreed'] && $this->oOption->isSupportMissing()) { $strBounceURL = htmlspecialchars_decode(AmazonAutoLinks_WPUtilities::getCurrentAdminURL()); $strBounceURL = str_replace('tab=support', '', $strBounceURL); // prevent infinite redirects ; $strBounceURL = remove_query_arg('aal-option-upgrade', $strBounceURL); AmazonAutoLinks_WPUtilities::setTransient('AAL_BounceURL', $strBounceURL, 60 * 10); exit(wp_redirect(admin_url('edit.php?post_type=' . AmazonAutoLinks_Commons::PostTypeSlug . '&page=aal_settings&tab=support&bounce_url=AAL_BounceURL'))); } // Check the v1 options exist and redirect to the v1 options importer. if (!(isset($_GET['tab'], $_GET['bounce_url']) && ($_GET['tab'] == 'import_v1_options' || $_GET['tab'] == 'support')) && !$this->oOption->arrOptions['aal_settings']['import_v1_options']['dismiss'] && false !== get_option('amazonautolinks')) { $strBounceURL = htmlspecialchars_decode(AmazonAutoLinks_WPUtilities::getCurrentAdminURL()); $strBounceURL = str_replace('tab=import_v1_options', '', $strBounceURL); // prevent infinite redirects AmazonAutoLinks_WPUtilities::setTransient('AAL_BounceURL_Importer', $strBounceURL, 60 * 10); $this->setAdminNotice(sprintf(__('Please upgrade the options of previous versions of the plugin by clicking <a href="%1$s">here</a>.', 'amazon-auto-links') . ' ' . __('Before you do it, please <strong>back up</strong> the database.', 'amazon-auto-links') . ' ' . __('Dismiss this message by clicking <a href="%2$s">here</a>.', 'amazon-auto-links'), admin_url('edit.php?post_type=' . AmazonAutoLinks_Commons::PostTypeSlug . '&page=aal_settings&tab=import_v1_options&bounce_url=AAL_BounceURL_Importer'), admin_url('edit.php?post_type=' . AmazonAutoLinks_Commons::PostTypeSlug . '&page=aal_settings&tab=import_v1_options&action=dismiss&bounce_url=AAL_BounceURL_Importer')), 'error'); return; } // Check v1 option importer messages if (isset($_GET['aal-option-upgrade'])) { switch ($_GET['aal-option-upgrade']) { case 'not-found': $this->setAdminNotice(__('Could not find the options to import.', 'amazon-auto-links'), 'error'); break; case 'succeed': $this->setAdminNotice(sprintf(__('Options have been imported. ( %1$s unit(s) )', 'amazon-auto-links'), $_GET['count']), 'updated'); break; case 'partial': $this->setAdminNotice(sprintf(__('Options been partially imported. ( %1$s unit(s) )', 'amazon-auto-links'), $_GET['count']), 'error'); break; case 'failed': $this->setAdminNotice(__('No unit was imported.', 'amazon-auto-links'), 'error'); break; } } // 3+ Add a setting notice to upgrade the options to v3 $_sBounceURL = htmlspecialchars_decode(AmazonAutoLinks_WPUtilities::getCurrentAdminURL()); $_sBounceURL = str_replace('tab=create_v3_options', '', $_sBounceURL); // prevent infinite redirects AmazonAutoLinks_WPUtilities::setTransient('AAL_BounceURL_Importer', $_sBounceURL, 60 * 10); $this->setAdminNotice('<strong>' . AmazonAutoLinks_Commons::Name . '</strong>: ' . sprintf(__('Please upgrade the options by clicking <strong><a href="%1$s">here</a></strong>.', 'amazon-auto-links') . ' ' . __('Before you do it, please <strong>back up</strong> the database.', 'amazon-auto-links'), admin_url('edit.php?post_type=' . AmazonAutoLinks_Commons::PostTypeSlug . '&page=aal_settings&tab=create_v3_options&bounce_url=AAL_BounceURL_Importer')), 'error'); }
protected function fetchItems($arrURLs, $numItems = 1) { $strURLID = md5(serialize(is_string($arrURLs) ? array($arrURLs) : $arrURLs)); if (!isset($this->arrFeedItems[$strURLID])) { $this->arrFeedItems[$strURLID] = (array) AmazonAutoLinks_WPUtilities::getTransient($this->strTransientPrefix . $strURLID); $this->arrFeedItems[$strURLID] = array_filter($this->arrFeedItems[$strURLID]); // casting array causes the 0 key } // If it's out of stock, fill the array by fetching the feed. shuffle($this->arrFeedItems[$strURLID]); $this->arrFeedItems[$strURLID] = array_unique($this->arrFeedItems[$strURLID]); if (count($this->arrFeedItems[$strURLID]) < $numItems) { $oReplace = new AmazonAutoLinks_HTMLElementReplacer(get_bloginfo('charset')); // When an array of urls is passed to the Simple Pie's set_feed_url() method, the memory usage increases largely. // So fetch the feeds one by one per url and store the output into an array. foreach ($arrURLs as $strURL) { $oFeed = $this->getFeedObj($strURL, $numItems * 10); // multiplied by three to store items more than enough for next calls. foreach ($oFeed->get_items() as $item) { // foreach ( $oFeed->get_items( 0, $numItems * 3 ) as $item ) does not change the memory usage $this->arrFeedItems[$strURLID][] = $oReplace->Perform($item->get_content()); } // For PHP below 5.3 to release the memory. $oFeed->__destruct(); // Do what PHP should be doing on it's own. unset($oFeed); } unset($oReplace); // This life span should be little longer than the feed cache life span, which is 1700. AmazonAutoLinks_WPUtilities::setTransient($this->strTransientPrefix . $strURLID, $this->arrFeedItems[$strURLID], 1800); // 30 minutes } $this->arrFeedItems[$strURLID] = array_unique($this->arrFeedItems[$strURLID]); shuffle($this->arrFeedItems[$strURLID]); $strOut = ''; for ($i = 1; $i <= $numItems; $i++) { $strOut .= array_pop($this->arrFeedItems[$strURLID]); } return $strOut; }
public function start_AmazonAutoLinks_PostType_AutoInsert() { $this->setPostTypeArgs(array('labels' => array('name' => __('Auto Insert', 'amazon-auto-links'), 'singular_name' => __('Auto Insert', 'amazon-auto-links'), 'menu_name' => __('Manage Auto Insert', 'amazon-auto-links'), 'add_new' => __('Add New Auto Insert', 'amazon-auto-links'), 'add_new_item' => __('Add New Auto Insert', 'amazon-auto-links'), 'edit' => __('Edit', 'amazon-auto-links'), 'edit_item' => __('Edit Auto Insert', 'amazon-auto-links'), 'new_item' => __('New Auto Insert', 'amazon-auto-links'), 'view' => __('View', 'amazon-auto-links'), 'view_item' => __('View Auto Insert', 'amazon-auto-links'), 'search_items' => __('Search Auto Insert Definitions', 'amazon-auto-links'), 'not_found' => __('No definitions found for Auto Insert', 'amazon-auto-links'), 'not_found_in_trash' => __('No definitions Found for Auto Insert in Trash', 'amazon-auto-links'), 'parent' => __('Parent Auto Insert', 'amazon-auto-links')), 'public' => false, 'menu_position' => 120, 'supports' => array('title'), 'taxonomies' => array(''), 'menu_icon' => AmazonAutoLinks_Commons::getPluginURL('asset/image/menu_icon_16x16.png'), 'has_archive' => false, 'hierarchical' => false, 'show_admin_column' => true, 'exclude_from_search' => true, 'publicly_queryable' => false, 'show_ui' => false, 'show_in_nav_menus' => false, 'show_in_menu' => false)); // Check custom actions if (is_admin() && $GLOBALS['pagenow'] == 'edit.php' && isset($_GET['post_type']) && $_GET['post_type'] == AmazonAutoLinks_Commons::PostTypeSlugAutoInsert) { // add_filter( 'post_row_actions', array( $this, 'modifyRowActions' ), 10, 2 ); add_filter('bulk_actions-edit-' . $this->oProps->strPostType, array($this, 'modifyBulkActionsDropDownList')); // $this->setAutoSave( false ); $this->setAuthorTableFilter(false); $this->strCustomNonce = uniqid(); AmazonAutoLinks_WPUtilities::setTransient('AAL_Nonce_' . $this->strCustomNonce, $this->strCustomNonce, 60 * 10); $this->handleCustomActions(); } // if not in admin or the post type slug is not set, the oLink object won't be set. if (isset($this->oLink)) { $this->oLink->strSettingPageLinkTitle = __('Auto-Insert', 'amazon-auto-links'); } // If a unit is deleted, check auto-insert items if there are empty items. If so, delete them as well. if (is_admin()) { add_action('before_delete_post', array($this, '_replyToCheckEmptyAutoInsert')); } }
/** * A wrapper method for the set_transient() function. * */ public function setTransient($strTransientKey, $vData, $intTime = null) { $sLockTransient = AmazonAutoLinks_Commons::TransientPrefix . '_' . md5("Lock_{$strTransientKey}"); // Check if the transient is locked if (AmazonAutoLinks_WPUtilities::getTransient($sLockTransient) !== false) { return; // it means the cache is being modified right now in a different process. } // Set a lock flag transient that indicates the transient is being renewed. AmazonAutoLinks_WPUtilities::setTransient($sLockTransient, time(), AmazonAutoLinks_Utilities::getAllowedMaxExecutionTime(30, 30)); // AmazonAutoLinks_Debug::logArray( 'set transient: ' . $strTransientKey ); // Save the cache AmazonAutoLinks_WPUtilities::setTransient($strTransientKey, array('mod' => $intTime ? $intTime : time(), 'data' => $this->oEncrypt->encode($vData))); // no expiration by itself // AmazonAutoLinks_Debug::logArray( 'the transient is saved: ' . $strTransientKey ); // AmazonAutoLinks_WPUtilities::deleteTransient( $sLockTransient ); }
/** * Fetches HTML body with the specified URL with caching functionality. * */ public function getHTML($strURL, $fUseFileGetContents = false) { // Check the transient first. $strTransient = $this->strHTMLCachePrefix . md5($strURL); $strHTMLBodyEncoded = AmazonAutoLinks_WPUtilities::getTransient($strTransient); if (false !== $strHTMLBodyEncoded) { return $this->oEncrypt->decode($strHTMLBodyEncoded); } // Fetch HTML. if ($fUseFileGetContents) { $strHTMLBody = file_get_contents($strURL); } else { $arrResponse = wp_remote_get($strURL, array('timeout' => 20, 'httpversion' => '1.1')); $strHTMLBody = wp_remote_retrieve_body($arrResponse); } // If failed or empty, return. if (empty($strHTMLBody)) { return $strHTMLBody; } // Encode the HTML string; otherwise, sometimes it gets broken. AmazonAutoLinks_WPUtilities::setTransient($strTransient, $this->oEncrypt->encode($strHTMLBody), 60 * 60 * 48); return $strHTMLBody; }
public function validation_aal_add_search_unit_initial_search_settings($aInput, $aOldInput) { // validation_{page slug}_{tab slug} $fVerified = true; $arrErrors = array(); $arrSearchOptions = $aInput['aal_add_search_unit']['search']; // Check the limitation. if ($this->oOption->isUnitLimitReached()) { $this->setFieldErrors(array('error')); // must set an field error array which does not yield empty so that it won't be redirected. $this->setSettingNotice(sprintf(__('Please upgrade to <A href="%1$s">Pro</a> to add more units! Make sure to empty the <a href="%2$s">trash box</a> to delete the units completely!', 'amazon-auto-links'), 'http://en.michaeluno.jp/amazon-auto-links-pro/', admin_url('edit.php?post_status=trash&post_type=' . AmazonAutoLinks_Commons::PostTypeSlug))); return $aOldInput; } // If the Access Key fields are present, it means the user has not set them yet in the Settings page. // In this case, just check if they are valid and if so, save them in the settings' option array. Otherwise, return an error. if (isset($arrSearchOptions['search_access_key'], $arrSearchOptions['search_access_key_secret'])) { $strPublicKey = $arrSearchOptions['search_access_key']; if (strlen($strPublicKey) != 20) { $arrErrors['search']['search_access_key'] = __('The Access Key ID must consist of 20 characters.', 'amazon-auto-links') . ': ' . $strPublicKey . ' '; $fVerified = false; } $strPrivateKey = $arrSearchOptions['search_access_key_secret']; if (strlen($strPrivateKey) != 40) { $arrErrors['search']['search_access_key_secret'] = __('The Secret Access Key must consist of 40 characters.', 'amazon-auto-links') . ': ' . $strPrivateKey . ' '; $fVerified = false; } // An invalid value is found. if (!$fVerified) { // Set the error array for the input fields. $this->setFieldErrors($arrErrors); $this->setSettingNotice(__('There was an error in your input.', 'amazon-auto-links')); return $aOldInput; } // Test authentication - browse the Books node in amazon.com. $oAmazonAPI = new AmazonAutoLinks_ProductAdvertisingAPI('com', $strPublicKey, $strPrivateKey); if (!$oAmazonAPI->test()) { $arrErrors['search']['search_access_key'] = __('Sent Value', 'amazon-auto-links') . ': ' . $strPublicKey; $arrErrors['search']['search_access_key_secret'] = __('Sent Value', 'amazon-auto-links') . ': ' . $strPrivateKey; $this->setFieldErrors($arrErrors); $this->setSettingNotice(__('Failed authentication.', 'amazon-auto-links')); $aOldInput; } // It is authenticated, so set the keys in the Settings option array. // Since the validation_ callbacks internally merge with the framework's property option array, // modify the property array, NOT the option object that plugin creates. $this->oProps->arrOptions['aal_settings']['authentication_keys']['access_key'] = $strPublicKey; $this->oProps->arrOptions['aal_settings']['authentication_keys']['access_key_secret'] = $strPrivateKey; } if (empty($arrSearchOptions['search_associate_id'])) { $arrErrors['search']['search_associate_id'] = __('The associate ID cannot be empty.', 'amazon-auto-links'); $fVerified = false; } // An invalid value is found. if (!$fVerified) { // Set the error array for the input fields. $this->setFieldErrors($arrErrors); $this->setSettingNotice(__('There was an error in your input.', 'amazon-auto-links')); return $aOldInput; } // Drop the sections. $_aNewFields = array(); foreach ($aInput['aal_add_search_unit'] as $strSection => $arrFields) { $_aNewFields = $_aNewFields + $arrFields; } // Remove the search_ prefix in the keys. $_aSanitizedFields = array(); foreach ($_aNewFields as $strKey => $vValue) { $_aSanitizedFields[preg_replace('/^search_/', '', $strKey)] = $vValue; } // Set the unit type based on the chosen one. // Redirect to the appropriate page by the search type. switch ($_aSanitizedFields['Operation']) { case 'ItemSearch': $_aSanitizedFields['unit_type'] = 'search'; $sTabSlug = 'search_products'; break; case 'ItemLookup': $_aSanitizedFields['unit_type'] = 'item_lookup'; $sTabSlug = 'item_lookup'; break; case 'SimilarityLookup': $_aSanitizedFields['unit_type'] = 'similarity_lookup'; $sTabSlug = 'similarity_lookup'; break; } // Save the transient $arrTempUnitOptions = (array) AmazonAutoLinks_WPUtilities::getTransient('AAL_CreateUnit_' . $_aSanitizedFields['transient_id']); $aSavingUnitOptions = AmazonAutoLinks_Utilities::uniteArrays($_aSanitizedFields, $arrTempUnitOptions); AmazonAutoLinks_WPUtilities::setTransient('AAL_CreateUnit_' . $_aSanitizedFields['transient_id'], $aSavingUnitOptions, 60 * 10 * 6 * 24); // Go to the next page. die(wp_redirect(add_query_arg(array('tab' => $sTabSlug, 'transient_id' => $_aSanitizedFields['transient_id']) + $_GET, $_aSanitizedFields['bounce_url']))); }
/** * A callback for the accessSiteAtShutDown() method. * * @since 1.0.0 */ public static function _replyToAccessSite() { // Retrieve the plugin scheduled tasks array. $_sTransientName = md5(get_class()); $_aTasks = AmazonAutoLinks_WPUtilities::getTransient($_sTransientName); $_aTasks = $_aTasks ? $_aTasks : array(); $_nNow = microtime(true); // Check the excessive background call protection interval if (!self::$_fIgnoreLock) { $_nCalled = isset($_aTasks['called']) ? $_aTasks['called'] : 0; if ($_nCalled + self::$_iLockBackgroundCallInterval > $_nNow) { return; // if it's called within 10 seconds from the last time of calling this method, do nothing to avoid excessive calls. } } // Renew the called time. $_aFlagKeys = array('called' => $_nNow); AmazonAutoLinks_WPUtilities::setTransient($_sTransientName, $_aFlagKeys + $_aTasks, self::getAllowedMaxExecutionTime()); // set a locked key so it prevents duplicated function calls due to too many calls caused by simultaneous accesses. // Compose a GET query array $_aGet = self::$_aGet; if (defined('WP_DEBUG')) { $_aGet['debug'] = WP_DEBUG; } unset($_aGet[0]); // Load the site in the background. wp_remote_get(site_url('?' . http_build_query($_aGet)), array('timeout' => 0.01, 'sslverify' => false, 'cookies' => $_aFlagKeys + array($_sTransientName => true))); }