GetIdentifier();
// Add it to the list of existing showcases
$this->_showcases[$showcaseIdentifier] = $showcase;
$this->Save();
return $showcaseIdentifier;
}
/**
* Creates a new showcase with default values and saves to the database.
* Outputs HTML to be appended to options panel
*/
function AjaxAddShowcase() {
$showcaseIdentifier = $this->AddNewShowcase();
die($this->_showcases[$showcaseIdentifier]->ShowcaseOptionsFormHtml());
}
/**
* Creates a new showcase item with default values and saves to the database.
* Outputs HTML to be appended to options panel
*
* @param string $showcaseIdentifier
*/
function AjaxAddShowcaseItem($showcaseIdentifier = null) {
if (!$showcaseIdentifier) { return 0; }
$itemIdentifier = $this->_showcases[$showcaseIdentifier]->AddItem();
$this->Save();
die($this->_showcases[$showcaseIdentifier]->ItemOptionsFormHtml($itemIdentifier));
}
/**
* Generates a preview of an Amazon Item and displays. Used for ajax calls
*
* @param mixed $asin
*/
function AjaxGenerateItemPreview($asin) {
// Do some minor cleanup on the asin
$asin = AMZSCShowcase::CleanAsin($asin);
$amazonData = $GLOBALS['AMZSCAmazon']->GetItems(array($asin));
if (isset($amazonData[$asin]['images']['thumbnail']['url'])) {
die('
');
} else {
die('Thumbnail preview not available. Sorry!');
}
}
/**
* Removes a showcase completely.
*
* @param string $identifier
*/
function AjaxRemoveShowcase($identifier = null) {
if (!$identifier) { return 0; }
// Remove the showcase
unset($this->_showcases[$identifier]);
$this->Save();
}
/**
* Removes a showcase item completely.
*
* @param string $showcaseIdentifier
* @param string $itemIdentifier
*/
function AjaxRemoveShowcaseItem($showcaseIdentifier = null, $itemIdentifier= null) {
if (!$showcaseIdentifier || !$itemIdentifier) { return 0; }
// Remove the showcase item
$this->_showcases[$showcaseIdentifier]->RemoveItem($itemIdentifier);
$this->Save();
}
/**
* Displays the options page
*/
function DisplayOptionsPage() {
$this->Initiate();
if (!empty($_POST['amzshcs_form_action'])) {
if ($_POST['amzshcs_form_action'] == 'update') {
if (isset($_POST['amzshcs']['showcases'])) {
foreach ($_POST['amzshcs']['showcases'] as $identifier => $showcase) {
$this->_showcases[$identifier]->SetOptions($showcase);
$this->_showcases[$identifier]->UpdateShowcaseAmazonData();
}
$this->Save();
}
} else if ($_POST['amzshcs_form_action'] == 'apiconfig') {
$this->_AWSAccessKeyId = $_POST['amzshcs']['accesskeyid'];
$this->_AWSSecretAccessKey = $_POST['amzshcs']['secretaccesskey'];
$this->Save();
}
}
$postUrl = $this->GetPostUrl();
?>
Amazon Showcase Settings
_AWSAccessKeyId) && !empty($this->_AWSSecretAccessKey)) { ?>
Showcases
_showcases[$showcaseIdentifier])) {
echo $this->_showcases[$showcaseIdentifier]->ShowcaseHTML();
}
}
/**
* Displays a showcase as a widget
*
*/
function DisplayWidget($args, $showcaseIdentifier) {
extract($args);
echo $before_widget;
if (!empty($this->_showcases[$showcaseIdentifier])) {
echo $before_title . $this->_showcases[$showcaseIdentifier]->GetName() . $after_title;
echo $this->_showcases[$showcaseIdentifier]->ShowcaseHTML();
}
echo $after_widget;
}
/**
* Enables Amazon Showcase and registers all appropriate WordPress hooks
*/
function Enable() {
if (!isset($GLOBALS['AmazonShowcase'])) {
$GLOBALS['AmazonShowcase'] = new AmazonShowcase();
$GLOBALS['AmazonShowcase']->Initiate();
// Hook for adding settings menus
add_action('admin_menu', array(&$GLOBALS['AmazonShowcase'], 'RegisterOptionsPage'));
// Filter for post content
add_filter('the_content', array(&$GLOBALS['AmazonShowcase'], 'ParseContent'));
// Register Widgets
$GLOBALS['AmazonShowcase']->RegisterShowcaseWidgets();
}
}
/*
Check the item's cache:
- If the cache is recent, use it
- If the cache is out dated, query Amazon and update cache with results
Forcing update
- Query amazon and update cache with fresh data
On preview - force cache update
On showcase save - update entire showcase
If missing data, attempt to query Amazon for fresh data
*/
/**
* Utility function for determining the URL for posting forms to
*
* @return string
*/
function GetPostUrl() {
$page = basename(__FILE__);
if (!empty($_GET['page'])) {
$page = preg_replace('[^a-zA-Z0-9\.\_\-]', '', $_GET['page']);
}
return $_SERVER['PHP_SELF'] . "?page=" . $page;
}
/**
* Initiates the plugin and loads options
*/
function Initiate() {
if (!$this->_initiated) {
// Load Amazon Showcase data from the database
$options = get_option('amzshcs');
if ($options && is_array($options)) {
$this->_AWSAccessKeyId = $options['accesskeyid'];
$this->_AWSSecretAccessKey = $options['secretaccesskey'];
foreach ($options['showcases'] as $showcaseIdentifier => $showcase) {
$this->_showcases[$showcaseIdentifier] = new AMZSCShowcase($showcaseIdentifier);
}
}
$GLOBALS['AMZSCAmazon'] = new AMZSCAmazon($this->_AWSAccessKeyId, $this->_AWSSecretAccessKey);
$this->_initiated = true;
}
}
/**
* Parses post content looking for showcase tags. Replaces found showcase tags
* with showcase HTML
*
* @param string $content
* @return string
*/
function ParseContent($content = null) {
$this->Initiate();
if (!empty($this->_showcases)) {
preg_match_all('/\[amazonshowcase_(.*?)\]/i', $content, $matches, PREG_PATTERN_ORDER);
foreach ($matches[1] as $showcaseIdentifier) {
if (isset($this->_showcases[$showcaseIdentifier])) {
$content = str_replace('[amazonshowcase_'.$showcaseIdentifier.']', $this->_showcases[$showcaseIdentifier]->ShowcaseHTML(), $content);
}
}
}
return $content;
}
/**
* Adds the options page in the admin menu
*/
function RegisterOptionsPage() {
if (function_exists('add_options_page')) {
add_options_page(__('Amazon Showcase', 'amazonshowcase'), __('Amazon Showcase', 'amazonshowcase'), 'administrator', basename(__FILE__), array(&$this, 'DisplayOptionsPage'));
}
}
/**
* Creates a widget for each showcase
*
*/
function RegisterShowcaseWidgets() {
if (function_exists('register_sidebar_widget')) {
foreach ($this->_showcases as $showcase) {
register_sidebar_widget($showcase->GetName(), array(&$GLOBALS['AmazonShowcase'], 'DisplayWidget'), $showcase->GetIdentifier());
}
}
}
/**
* Save Amazon Showcase data to the database
*
* @return bool
*/
function Save() {
$options = array();
$options['accesskeyid'] = $this->_AWSAccessKeyId;
$options['secretaccesskey'] = $this->_AWSSecretAccessKey;
foreach ($this->_showcases as $showcase) {
$options['showcases'][$showcase->GetIdentifier()] = $showcase->GetOptionsArray();
};
return update_option("amzshcs", $options);
}
}
class AMZSCAmazon {
var $_AssociateId = 'amazonshowcase-20'; // Used if no associate ID is provided
function AMZSCAmazon($accessKeyId = null, $secretAccessKey = null) {
$this->_AWSAccessKeyId = $accessKeyId;
$this->_AWSSecretAccessKey = $secretAccessKey;
}
/**
* Sends http request to Amazon web service and parses response into tidy array
*
* @param array $asins
* @param string $associateId
* @param string $locale
* @return array Items
*/
function GetItems($asins = array(), $associateId = null, $locale = 'us') {
if (empty($this->_AWSAccessKeyId) || empty($this->_AWSSecretAccessKey)) {
return false;
}
$items = array();
// We batch the items into groups of 10 because that is the maxiumum numbers of ASINs
// that can be queried at once.
$asinBatches = array_chunk($asins, 10);
foreach ($asinBatches as $asinBatch) {
$xml = $this->ItemSearch($asinBatch, $associateId, $locale);
if (!$xml || strpos($xml, 'SignatureDoesNotMatch') === true) {
return false;
}
$itemData = $this->ParseXml($xml);
foreach ($itemData as $asin => $data) { // Would use array_merge here, but numeric asins are reindexed
$items[$asin] = $data;
}
}
return $items;
}
/**
* Sends http request to Amazon web service
*
* @param array $asins
* @param string $associateId
* @param string $locale
* @return xml Amazon API Response
*/
function ItemSearch($asins = array(), $associateId = null, $locale = 'us') {
if (empty($this->_AWSAccessKeyId) || empty($this->_AWSSecretAccessKey)) {
return false;
}
if (is_array($asins) && !empty($asins)) {
//Set the values for some of the parameters.
$associateId = empty($associateId) ? $this->_AssociateId : $associateId;
switch ($locale) {
case 'uk': $base = 'ecs.amazonaws.co.uk'; break;
case 'de': $base = 'ecs.amazonaws.de'; break;
case 'jp': $base = 'ecs.amazonaws.co.jp'; break;
case 'fr': $base = 'ecs.amazonaws.fr'; break;
case 'ca': $base = 'ecs.amazonaws.ca'; break;
default: $base = 'ecs.amazonaws.com'; break;
}
$uri = '/onca/xml';
$queryString =
"AWSAccessKeyId=" . $this->_AWSAccessKeyId
. "&AssociateTag=" . $associateId
. "&ItemId=" . urlencode(implode(',', $asins))
. "&Operation=ItemLookup"
. "&ResponseGroup=Small,Images"
. "&Service=AWSECommerceService"
. "&Timestamp=". gmdate("Y-m-d\TH:i:s\Z")
. "&Version=2008-08-19";
$queryString = str_replace(',', '%2C', $queryString);
$queryString = str_replace(':', '%3A', $queryString);
// Build signature string
$string_to_sign = "GET\n" . $base . "\n" . $uri . "\n" . $queryString;
$signature = urlencode(base64_encode(hash_hmac("sha256", $string_to_sign, $this->_AWSSecretAccessKey, true)));
$request = 'http://' . $base . $uri . '?' . $queryString . '&Signature=' . $signature;
//Catch the response in the $response object
$response = getUrl($request);
return $response;
}
return false;
}
/**
* Parses Amazon API response XML into tidy array
*
* @param string $xml
* @return array Items
*/
function ParseXml($xml) {
$items = array();
preg_match_all("/