アマゾン用グッズメモ アフィリエイト

グッズメモ アフィリエイト・WordPressプラグインのソースコード記事の目次WordPress

AmazonAffiliate.php

アマゾンアフィリエイト用の商品を表示するHTMLを、作成します。


namespace goodsmemo\amazon;

use goodsmemo\amazon\KeywordSearchOperation;
use goodsmemo\amazon\AmazonOptionUtils;
use goodsmemo\amazon\ItemHTMLUtils;
use goodsmemo\network\URLUtils;
use goodsmemo\option\AffiliateOptionUtils;
use goodsmemo\option\amazon\URLParagraphUtils;
use goodsmemo\option\amazon\RESTParagraphUtils;
use goodsmemo\exception\IllegalArgumentException;

require_once GOODS_MEMO_DIR . "amazon/KeywordSearchOperation.php";
require_once GOODS_MEMO_DIR . "amazon/AmazonOptionUtils.php";
require_once GOODS_MEMO_DIR . "amazon/ItemHTMLUtils.php";
require_once GOODS_MEMO_DIR . "network/URLUtils.php";
require_once GOODS_MEMO_DIR . "option/AffiliateOptionUtils.php";
require_once GOODS_MEMO_DIR . "option/amazon/URLParagraphUtils.php";
require_once GOODS_MEMO_DIR . "option/amazon/RESTParagraphUtils.php";
require_once GOODS_MEMO_DIR . "exception/IllegalArgumentException.php";

/**
 * Description of Amazon
 *
 * @author Goods Memo
 */
class AmazonAffiliate {

	public static function makeHTML($operationOfShortcode, $searchIndexOfShortcode, $keyword, $number) {

		$optionMap = AffiliateOptionUtils::getAffiliateOption(); //ここで一回だけデータベースを読み込む。

		$urlInfo = URLUtils::makeURLInfo($optionMap, URLParagraphUtils::HOSTNAME_ID);
		$commonParameter = AmazonOptionUtils::makeCommonRESTParameter($optionMap);
		$restParameter = AmazonOptionUtils::makeRESTParameter($optionMap, $operationOfShortcode, $searchIndexOfShortcode,
				$keyword);
		$itemHTMLOption = ItemHTMLUtils::makeItemHTMLOption($optionMap, $number);
		$productTypeOption = AmazonOptionUtils::makeProductTypeOption($optionMap);
		$searchWidgetOption = AmazonOptionUtils::makeSearchWidgetOption($optionMap);

		$affiliateHTML;

		$operation = $restParameter->getOperation();
		switch ($operation) {
			case RESTParagraphUtils::ITEM_SEARCH_OPERATION:

				//現時点では、「Operation="ItemSearch", SearchIndex="all"の組み合わせ」で、キーワード検索する処理だけ行なう。
				$affiliateHTML = KeywordSearchOperation::makeHTMLOfSearchOperation($urlInfo, $commonParameter, $restParameter,
						$itemHTMLOption, $productTypeOption, $searchWidgetOption);
				break;

			default:

				throw new IllegalArgumentException("無効なオペレーション:" . $operation);
		}

		return $affiliateHTML;
	}

}

AmazonItemsHTMLInfoMaker.php


namespace goodsmemo\amazon;

use goodsmemo\item\ItemsHTMLInfoMaker;
use goodsmemo\network\URLInfo;
use goodsmemo\amazon\CommonRESTParameter;
use goodsmemo\amazon\RESTParameter;
use goodsmemo\amazon\ProductTypeOption;
use goodsmemo\amazon\AmazonRequest;
use goodsmemo\amazon\AmazonResponse;
use goodsmemo\item\html\ItemHTMLOption;
use goodsmemo\option\amazon\AmazonSettingSection;

require_once GOODS_MEMO_DIR . "item/ItemsHTMLInfoMaker.php";
require_once GOODS_MEMO_DIR . "network/URLInfo.php";
require_once GOODS_MEMO_DIR . "amazon/CommonRESTParameter.php";
require_once GOODS_MEMO_DIR . "amazon/RESTParameter.php";
require_once GOODS_MEMO_DIR . "amazon/ProductTypeOption.php";
require_once GOODS_MEMO_DIR . "amazon/AmazonRequest.php";
require_once GOODS_MEMO_DIR . "amazon/AmazonResponse.php";
require_once GOODS_MEMO_DIR . "item/html/ItemHTMLOption.php";
require_once GOODS_MEMO_DIR . "option/amazon/AmazonSettingSection.php";

/**
 * Description of AmazonItemsHTMLInfoMaker
 *
 * @author Goods Memo
 */
class AmazonItemsHTMLInfoMaker implements ItemsHTMLInfoMaker {

	private $commonParameter;
	private $restParameter;
	private $productTypeOption;

	public function __construct(CommonRESTParameter $commonParameter, RESTParameter $restParameter,
		ProductTypeOption $productTypeOption) {

		$this->commonParameter = $commonParameter;
		$this->restParameter = $restParameter;
		$this->productTypeOption = $productTypeOption;
	}

	public function requestItemSearch(URLInfo $urlInfo, int $itemCount) {

		$response = AmazonRequest::requestSearchIndex($urlInfo, $this->commonParameter, $this->restParameter,
				$itemCount);
		return $response;
	}

	public function makeItemArray($response, ItemHTMLOption $itemHTMLOption) {

		$numberToDisplay = $itemHTMLOption->getNumberToDisplay();
		$itemArray = AmazonResponse::makeItemArray($response, $numberToDisplay, $this->productTypeOption);
		return $itemArray;
	}

	public function makeUniqueText(ItemHTMLOption $itemHTMLOption) {

		$operation = $this->restParameter->getOperation();
		$searchIndex = $this->restParameter->getSearchIndex();
		$responseGroup = $this->restParameter->getSearchItemsResources();
		$keyword = $this->restParameter->getKeyword();
		$numberToDisplay = $itemHTMLOption->getNumberToDisplay();
		$cacheExpirationInSeconds = $itemHTMLOption->getCacheExpirationInSeconds();

		$uniqueText = AmazonSettingSection::ID_PREFIX . $operation . $searchIndex . $responseGroup . $keyword . $numberToDisplay . $cacheExpirationInSeconds;
		return $uniqueText;
	}

}

AmazonOptionUtils.php


namespace goodsmemo\amazon;

use goodsmemo\amazon\CommonRESTParameter;
use goodsmemo\amazon\RESTParameter;
use goodsmemo\amazon\ProductTypeOption;
use goodsmemo\option\amazon\CommonRESTParagraphUtils;
use goodsmemo\option\amazon\RESTParagraphUtils;
use goodsmemo\option\amazon\ProductTypeParagraph;
use goodsmemo\option\amazon\ProductTypeParagraphUtils;
use goodsmemo\option\amazon\SearchWidgetParagraph;
use goodsmemo\option\amazon\SearchWidgetParagraphUtils;

require_once GOODS_MEMO_DIR . "amazon/CommonRESTParameter.php";
require_once GOODS_MEMO_DIR . "amazon/RESTParameter.php";
require_once GOODS_MEMO_DIR . "amazon/ProductTypeOption.php";
require_once GOODS_MEMO_DIR . "option/amazon/CommonRESTParagraphUtils.php";
require_once GOODS_MEMO_DIR . "option/amazon/RESTParagraphUtils.php";
require_once GOODS_MEMO_DIR . "option/amazon/ProductTypeParagraph.php";
require_once GOODS_MEMO_DIR . "option/amazon/ProductTypeParagraphUtils.php";
require_once GOODS_MEMO_DIR . "option/amazon/SearchWidgetParagraph.php";
require_once GOODS_MEMO_DIR . "option/amazon/SearchWidgetParagraphUtils.php";

/**
 * Description of AmazonOption
 *
 * @author Goods Memo
 */
class AmazonOptionUtils {

	public static function makeCommonRESTParameter($optionMap): CommonRESTParameter {

		$parameter = new CommonRESTParameter();

		$accessKey = $optionMap[CommonRESTParagraphUtils::PAA_ACCESS_KEY_ID]; //var_dump($accessKey);
		$parameter->setAccessKey($accessKey);

		$associateTag = $optionMap[CommonRESTParagraphUtils::PAA_ASSOCIATE_TAG_ID]; //var_dump($associateTag);
		$parameter->setAssociateTag($associateTag);

		$secretKey = $optionMap[CommonRESTParagraphUtils::PAA_SECRET_KEY_ID]; //var_dump($secretKey);
		$parameter->setSecretKey($secretKey);

		$region = $optionMap[CommonRESTParagraphUtils::PAA_REGION_ID]; //var_dump($region);
		$parameter->setRegion($region);

		return $parameter;
	}

	public static function makeRESTParameter($optionMap, $operationOfShortcode, $searchIndexOfShortcode, $keyword): RESTParameter {

		$restParameter = new RESTParameter();

		//TODO get_option()から、値を取得する。

		if ($operationOfShortcode) {
			$restParameter->setOperation($operationOfShortcode);
		} else {
			$restParameter->setOperation(RESTParagraphUtils::ITEM_SEARCH_OPERATION);
		}

		if ($searchIndexOfShortcode) {
			$restParameter->setSearchIndex($searchIndexOfShortcode);
		} else {
			$restParameter->setSearchIndex(RESTParagraphUtils::ALL_SEARCH_INDEX);
		}

		$searchItemsResources = json_decode($optionMap[RESTParagraphUtils::SEARCH_ITEMS_RESOURCES_ID], true); //true:連想配列に変換する
		//var_dump($searchItemsResources);
		$restParameter->setSearchItemsResources($searchItemsResources);

		$restParameter->setKeyword($keyword);

		return $restParameter;
	}

	public static function makeProductTypeOption($optionMap): ProductTypeOption {

		$productTypeOption = new ProductTypeOption();

		//参考:チェックボックスがチェックされていなかった場合、
		//チェックされていない状態を表す値(value=unchecked など)が送信されることはなく、
		//値はサーバーに全く送信されません。$optionMapの要素が存在しない。
		if (isset($optionMap[ProductTypeParagraphUtils::ADULT_PRODUCT_ID])) {

			$adultProductCheckedValue = $optionMap[ProductTypeParagraphUtils::ADULT_PRODUCT_ID]; //var_dump($adultProductCheckedValue);
			$adultProductEnabled = ($adultProductCheckedValue === ProductTypeParagraph::ADULT_PRODUCT_CHECKED_VALUE); //var_dump($adultProductEnabled);
			$productTypeOption->setAdultProductEnabled($adultProductEnabled);
		}

		return $productTypeOption;
	}

	public static function makeSearchWidgetOption($optionMap): SearchWidgetOption {

		$searchWidgetOption = new SearchWidgetOption();

		//参考:チェックボックスがチェックされていなかった場合、
		//チェックされていない状態を表す値(value=unchecked など)が送信されることはなく、
		//値はサーバーに全く送信されません。$optionMapの要素が存在しない。
		if (isset($optionMap[SearchWidgetParagraphUtils::SEARCH_WIDGET_ID])) {

			$searchWidgetCheckedValue = $optionMap[SearchWidgetParagraphUtils::SEARCH_WIDGET_ID]; //var_dump($searchWidgetCheckedValue);
			$searchWidgetEnabled = ($searchWidgetCheckedValue === SearchWidgetParagraph::SEARCH_WIDGET_CHECKED_VALUE); //var_dump($searchWidgetEnabled);
			$searchWidgetOption->setSearchWidgetAlwaysEnabled($searchWidgetEnabled);
		}

		return $searchWidgetOption;
	}

}

AmazonRequest.php


namespace goodsmemo\amazon;

use goodsmemo\amazon\CommonRESTParameter;
use goodsmemo\amazon\RESTParameter;
use goodsmemo\network\URLInfo;
use goodsmemo\exception\HttpRequestException;
//PA-API v5  SDK
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\api\DefaultApi;
use Amazon\ProductAdvertisingAPI\v1\ApiException;
use Amazon\ProductAdvertisingAPI\v1\Configuration;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\SearchItemsRequest;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\PartnerType;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\ProductAdvertisingAPIClientException;

require_once GOODS_MEMO_DIR . "amazon/CommonRESTParameter.php";
require_once GOODS_MEMO_DIR . "amazon/RESTParameter.php";
require_once GOODS_MEMO_DIR . "network/URLInfo.php";
require_once GOODS_MEMO_DIR . "exception/HttpRequestException.php";
//PA-API v5  SDK
require_once(__DIR__ . '/sdk/vendor/autoload.php'); // change path as needed

/**
 * Description of AmazonRequest
 *
 * @author Goods Memo
 */
class AmazonRequest {

	public static function requestSearchIndex(URLInfo $urlInfo, CommonRESTParameter $commonParameter,
		RESTParameter $restParameter, int $itemCount) {

		if ($itemCount <= 0) {
			return NULL; //表示する件数が0件なので、商品情報なしとする。
		}

		// Request initialization
		/*
		 * Specify the category in which search request is to be made
		 * For more details, refer: https://webservices.amazon.com/paapi5/documentation/use-cases/organization-of-items-on-amazon/search-index.html
		 */
		$partnerTag = $commonParameter->getAssociateTag(); // Please add your partner tag (store/tracking id) here
		$searchIndex = $restParameter->getSearchIndex();
		$keyword = $restParameter->getKeyword(); // Specify keywords
		/*
		 * Choose resources you want from SearchItemsResource enum
		 * For more details, refer: https://webservices.amazon.com/paapi5/documentation/search-items.html#resources-parameter
		 */
		$resources = $restParameter->getSearchItemsResources();

		// Forming the request
		$searchItemsRequest = new SearchItemsRequest();
		$searchItemsRequest->setPartnerTag($partnerTag);
		$searchItemsRequest->setPartnerType(PartnerType::ASSOCIATES);
		$searchItemsRequest->setSearchIndex($searchIndex);
		$searchItemsRequest->setKeywords($keyword);
		$searchItemsRequest->setItemCount($itemCount);
		$searchItemsRequest->setResources($resources);

		// Validating request
		$invalidPropertyList = $searchItemsRequest->listInvalidProperties();
		$length = count($invalidPropertyList);
		if ($length > 0) {
			$errorMessage = "Error forming the request" . PHP_EOL;
			foreach ($invalidPropertyList as $invalidProperty) {
				$errorMessage .= $invalidProperty . PHP_EOL;
			}
			throw new HttpRequestException($errorMessage);
		}

		$config = new Configuration();
		/*
		 * Add your credentials
		 * Please add your access key here
		 */
		$config->setAccessKey($commonParameter->getAccessKey());
		// Please add your secret key here
		$config->setSecretKey($commonParameter->getSecretKey());
		/*
		 * PAAPI host and region to which you want to send request
		 * For more details refer: https://webservices.amazon.com/paapi5/documentation/common-request-parameters.html#host-and-region
		 */
		$config->setHost($urlInfo->getHostname());
		$config->setRegion($commonParameter->getRegion());

		$apiInstance = new DefaultApi(
			/*
			 * If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`.
			 * This is optional, `GuzzleHttp\Client` will be used as default.
			 */
			new \GuzzleHttp\Client(), $config);

		$searchItemsResponse = AmazonRequest::getSearchItems($apiInstance, $searchItemsRequest);
		return $searchItemsResponse;
	}

	private static function getSearchItems(DefaultApi $apiInstance, SearchItemsRequest $searchItemsRequest, $retryCount = 3) {

		$lastHttpRequestException;
		for ($i = 0; $i < $retryCount; $i++) {//リトライ回数:3回
			if ($i >= 1) {
				sleep(1); //再試行の待ち時間(1秒)
			}

			try {
				$searchItemsResponse = AmazonRequest::getSearchItemsResponse($apiInstance, $searchItemsRequest);
				return $searchItemsResponse;
			} catch (HttpRequestException $ex) {
				$lastHttpRequestException = $ex;
			}
		}

		throw $lastHttpRequestException;
	}

	private static function getSearchItemsResponse(DefaultApi $apiInstance, SearchItemsRequest $searchItemsRequest) {

		// Sending the request
		try {
			$searchItemsResponse = $apiInstance->searchItems($searchItemsRequest);

			//echo 'API called successfully', PHP_EOL;
			//echo 'Complete Response: ', $searchItemsResponse, PHP_EOL;
			if ($searchItemsResponse->getErrors() != NULL
				and $searchItemsResponse->getErrors()[0] != NULL) {
				//Error message: No results found for your request.この時 $searchItemsResponse->getSearchResult() == NULL。//var_dump($searchItemsResponse);
				//検索結果0件の場合、ここに来る。正常処理なので、throw new HttpRequestException()しなくて良い。
				$errorCodeText = $searchItemsResponse->getErrors()[0]->getCode(); //string型。例:"NoResults"という文字列が取得された。
				$errorMessage = 'Printing Errors:' . PHP_EOL . 'Printing first error object from list of errors' . PHP_EOL;
				$errorMessage .= 'Error message: ' . $searchItemsResponse->getErrors()[0]->getMessage() . PHP_EOL;
				$errorMessage .= 'Error CodeText: ' . $errorCodeText . PHP_EOL;
				//var_dump($errorMessage);
			}

			return $searchItemsResponse;
		} catch (ApiException $exception) {

			$errorMessage = "Error calling PA-API 5.0!" . PHP_EOL;
			$errorMessage .= "Error Message: " . $exception->getMessage() . PHP_EOL;
			$errorMessage .= "Error host: " . $apiInstance->getConfig()->getHost() . PHP_EOL;

			if ($exception->getResponseObject() instanceof ProductAdvertisingAPIClientException) {
				$errors = $exception->getResponseObject()->getErrors();
				foreach ($errors as $error) {
					$errorMessage .= "Error Type: " . $error->getCode() . PHP_EOL;
					$errorMessage .= "Error Message: " . $error->getMessage() . PHP_EOL;
				}
			} else {
				$errorMessage .= "Error response body: " . $exception->getResponseBody() . PHP_EOL;
			}

			$errorCode = $exception->getCode();
			throw new HttpRequestException($errorMessage, $errorCode);
		}
		//Shortcode.phpで受け取るようにした。
//		catch (Exception $exception) {
//			$errorMessage = "Error Message: " . $exception->getMessage() . PHP_EOL;
//		}
	}

}

AmazonResponse.php


namespace goodsmemo\amazon;

use goodsmemo\amazon\ImageResponse;
use goodsmemo\amazon\PriceResponse;
use goodsmemo\amazon\ProductionResponse;
use goodsmemo\amazon\ProductTypeOption;
//use goodsmemo\item\Item;//PA-API v5  SDKに同名のクラスがある。
use goodsmemo\item\ReviewItem;
use goodsmemo\item\html\HTMLUtils;
use goodsmemo\date\DateTextMaking;

//PA-API v5  SDK
//use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\Item;

require_once GOODS_MEMO_DIR . "amazon/ImageResponse.php";
require_once GOODS_MEMO_DIR . "amazon/PriceResponse.php";
require_once GOODS_MEMO_DIR . "amazon/ProductionResponse.php";
require_once GOODS_MEMO_DIR . "amazon/ProductTypeOption.php";
require_once GOODS_MEMO_DIR . "item/Item.php";
require_once GOODS_MEMO_DIR . "item/ReviewItem.php";
require_once GOODS_MEMO_DIR . "item/html/HTMLUtils.php";
require_once GOODS_MEMO_DIR . "date/DateTextMaking.php";
//PA-API v5  SDK
require_once(__DIR__ . '/sdk/vendor/autoload.php'); // change path as needed

/**
 * Description of AmazonResponse
 *
 * @author Goods Memo
 */
class AmazonResponse {

	public static function makeItemArray($searchItemsResponse, $numberToDisplay, ProductTypeOption $productTypeOption) {

		$itemArray = array();

		if ($searchItemsResponse == NULL
			or $searchItemsResponse->getSearchResult() == NULL
			or $searchItemsResponse->getSearchResult()->getItems() == NULL) {

			return $itemArray; //商品情報なし
		}

		$searchItems = $searchItemsResponse->getSearchResult()->getItems(); //Item[] //PA-API v5  SDKのItemクラス
		$priceTime = DateTextMaking::getUnixTimeMillSecond();

		$searchItemCount = count($searchItems); //var_dump($searchItems);
		$count = min($searchItemCount, $numberToDisplay);
		for ($i = 0; $i < $count; $i++) {

			$searchItem = $searchItems[$i];
			if ($searchItem == NULL) {//念のため。配列の要素がNULLの場合
				continue;
			}

			if (AmazonResponse::getItemEnabled($searchItem, $productTypeOption)) {

				$item = AmazonResponse::makeItem($searchItem, $priceTime);
				array_push($itemArray, $item);
			}
		}

		return $itemArray;
	}

	private static function getItemEnabled(\Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\Item $searchItem,
		ProductTypeOption $productTypeOption): bool {

		$adultProductEnable = $productTypeOption->getAdultProductEnabled(); //var_dump($adultProductEnable);
		if ($adultProductEnable) {
			return true;
		}

		//以下、アダルト商品が無効と指定されている場合について
		//
		if ($searchItem->getItemInfo() == NULL
			or $searchItem->getItemInfo()->getProductInfo() == NULL
			or $searchItem->getItemInfo()->getProductInfo()->getIsAdultProduct() == NULL
			or $searchItem->getItemInfo()->getProductInfo()->getIsAdultProduct()->getDisplayValue() === NULL //bool型とNULL型を比較
		) {

			return true; //アダルト商品の情報がない場合、有効とする。
		}

		$isAdultProductValue = $searchItem->getItemInfo()->getProductInfo()->getIsAdultProduct()->getDisplayValue(); //SingleBooleanValuedAttributeクラスのbool値
		//var_dump($isAdultProductValue);//var_dump($searchItem);
		if ($isAdultProductValue) {
			return false; //$searchItemがアダルト商品なら、無効とする。
		} else {
			return true; //$searchItemが普通の商品なら、有効とする。
		}
	}

	private static function makeItem(\Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\Item $searchItem,
		float $priceTime): \goodsmemo\item\Item {

		$item = new \goodsmemo\item\Item();

		if ($searchItem->getDetailPageURL() != NULL) {
			$item->setPageURL(esc_url($searchItem->getDetailPageURL()));
		}

		AmazonResponse::setItemInfoTo($item, $searchItem);
		AmazonResponse::setOffersTo($item, $searchItem);

		$imageItem = ImageResponse::makeImageItem($searchItem);
		$item->setImageItem($imageItem);

		$priceItem = PriceResponse::makePriceItem($searchItem, $priceTime);
		$item->setPriceItem($priceItem);

		$productionItem = ProductionResponse::makeProductionItem($searchItem);
		$item->setProductionItem($productionItem);  //var_dump($searchItem);

		$reviewItem = AmazonResponse::makeReviewItem($searchItem);
		$item->setReviewItem($reviewItem);

		return $item;
	}

	private static function setItemInfoTo(\goodsmemo\item\Item &$item,
		\Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\Item $searchItem) {

		if ($searchItem->getItemInfo() == NULL) {
			return;
		}

		$itemInfo = $searchItem->getItemInfo();

		if ($itemInfo->getTitle() != NULL
			and $itemInfo->getTitle()->getDisplayValue() != NULL) {

			$titleValue = $itemInfo->getTitle()->getDisplayValue();
			$item->setTitle(HTMLUtils::makePlainText($titleValue));
		}
	}

	private static function setOffersTo(\goodsmemo\item\Item &$item,
		\Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\Item $searchItem) {

		if ($searchItem->getOffers() == NULL) {
			return;
		}

		$offers = $searchItem->getOffers(); //var_dump($offers);

		if ($offers->getListings() != NULL
			and $offers->getListings()[0] != NULL
			and $offers->getListings()[0]->getDeliveryInfo() != NULL) {

			$isPrimeEligible = $offers->getListings()[0]->getDeliveryInfo()->getIsPrimeEligible(); //bool型	//var_dump($isPrimeEligible);
			if ($isPrimeEligible) {
				$item->setPreferentialMember(HTMLUtils::makePlainText("&#10003;prime")); //"✓prime"
			}
		}

		if ($offers->getListings() != NULL
			and $offers->getListings()[0] != NULL
			and $offers->getListings()[0]->getMerchantInfo() != NULL
			and $offers->getListings()[0]->getMerchantInfo()->getName() != NULL) {

			$merchantName = $offers->getListings()[0]->getMerchantInfo()->getName();
			$item->setShop(HTMLUtils::makePlainText($merchantName));
		}
	}

	private static function makeReviewItem(\Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\Item $searchItem): ReviewItem {

		$reviewItem = new ReviewItem();

		if ($searchItem->getItemInfo() != NULL
			and $searchItem->getItemInfo()->getFeatures() != NULL
			and $searchItem->getItemInfo()->getFeatures()->getDisplayValues() != NULL) {

			$featuresValues = $searchItem->getItemInfo()->getFeatures()->getDisplayValues(); //string[]

			$featureArray = array();
			foreach ($featuresValues as $value) {

				if ($value == NULL) {
					continue;
				}//var_dump($value);
				$feature = HTMLUtils::makePlainText($value);
				array_push($featureArray, $feature);
			}

			$reviewItem->setReviewLineArray($featureArray);
		}

		//TODO Check back later for updates
//		if (isset($node->EditorialReviews->EditorialReview->Content)) {//Noticd: Trying to get property of non-objectエラーが起きた。
//			$editorialReview = HTMLUtils::makePlainText($node->EditorialReviews->EditorialReview->Content);
//			$reviewItem->setPlainTextReview($editorialReview);
//		}

		return $reviewItem;
	}

}

CommonRESTParameter.php


namespace goodsmemo\amazon;

/**
 * Description of CommonRESTParameter
 *
 * @author Goods Memo
 */
class CommonRESTParameter {

	private $accessKey;
	private $associateTag;
	private $secretKey;
	private $region;

	public function getAccessKey() {
		return $this->accessKey;
	}

	public function getAssociateTag() {
		return $this->associateTag;
	}

	public function getSecretKey() {
		return $this->secretKey;
	}

	public function getRegion() {
		return $this->region;
	}

	public function setAccessKey($accessKey) {
		$this->accessKey = $accessKey;
	}

	public function setAssociateTag($associateTag) {
		$this->associateTag = $associateTag;
	}

	public function setSecretKey($secretKey) {
		$this->secretKey = $secretKey;
	}

	public function setRegion($region) {
		$this->region = $region;
	}

}

ImageResponse.php


namespace goodsmemo\amazon;

use goodsmemo\item\ImageItem;

require_once GOODS_MEMO_DIR . "item/ImageItem.php";
//PA-API v5  SDK
require_once(__DIR__ . '/sdk/vendor/autoload.php'); // change path as needed

/**
 * Description of ImageResponse
 *
 * @author Goods Memo
 */
class ImageResponse {

	public static function makeImageItem(\Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\Item $searchItem): ImageItem {

		$imageItem = new ImageItem();

		if ($searchItem->getImages() == NULL
			or $searchItem->getImages()->getPrimary() == NULL) {
			return $imageItem;
		}

		$primaryImages = $searchItem->getImages()->getPrimary();

		//大きさの優先順位は、ミディアム、ラージ、スモール

		if ($primaryImages->getMedium() != NULL) {
			$imageSize = $primaryImages->getMedium();
			ImageResponse::setImageInfoTo($imageItem, $imageSize);

			if ($imageItem->getImageURL()) {
				return $imageItem;
			}
		}

		if ($primaryImages->getLarge() != NULL) {
			$imageSize = $primaryImages->getLarge();
			ImageResponse::setImageInfoTo($imageItem, $imageSize);

			if ($imageItem->getImageURL()) {
				return $imageItem;
			}
		}

		if ($primaryImages->getSmall() != NULL) {
			$imageSize = $primaryImages->getSmall();
			ImageResponse::setImageInfoTo($imageItem, $imageSize);

			if ($imageItem->getImageURL()) {
				return $imageItem;
			}
		}

		return $imageItem;
	}

	private static function setImageInfoTo(ImageItem &$imageItem,
		\Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\ImageSize $imageSize) {

		if ($imageSize->getURL() != NULL) { //ImageSizeクラス string型
			$imageItem->setImageURL(esc_url($imageSize->getURL()));
			$imageItem->setImageWidth($imageSize->getWidth()); //ImageSizeクラス int32型
			$imageItem->setImageHeight($imageSize->getHeight()); //ImageSizeクラス int32型
		}
	}

}

ItemHTMLUtils.php


namespace goodsmemo\amazon;

use goodsmemo\item\html\ItemHTMLOption;
use goodsmemo\item\html\PriceItemHTMLOption;
use goodsmemo\item\html\ReviewItemHTMLUtils;
use goodsmemo\option\amazon\AmazonSettingSection;
use goodsmemo\option\amazon\ItemHTMLParagraphUtils;
use goodsmemo\option\amazon\PriceParagraphUtils;
use goodsmemo\option\amazon\ReviewParagraphUtils;

require_once GOODS_MEMO_DIR . "item/html/ItemHTMLOption.php";
require_once GOODS_MEMO_DIR . "item/html/PriceItemHTMLOption.php";
require_once GOODS_MEMO_DIR . "item/html/ReviewItemHTMLUtils.php";
require_once GOODS_MEMO_DIR . "option/amazon/AmazonSettingSection.php";
require_once GOODS_MEMO_DIR . "option/amazon/ItemHTMLParagraphUtils.php";
require_once GOODS_MEMO_DIR . "option/amazon/PriceParagraphUtils.php";
require_once GOODS_MEMO_DIR . "option/amazon/ReviewParagraphUtils.php";

/**
 * Description of ItemHTMLUtils
 *
 * @author Goods Memo
 */
class ItemHTMLUtils {

    public static function makeItemHTMLOption($optionMap, int $number): ItemHTMLOption {

	$option = new ItemHTMLOption();

	//TODO get_option()から、値を取得する。

	$option->setIdPrefix(AmazonSettingSection::ID_PREFIX);

	if (is_numeric($number)) {//ゼロも有効とした。
	    $option->setNumberToDisplay($number);
	} else {
	    $option->setNumberToDisplay(ItemHTMLParagraphUtils::DEFAULT_NUMBER_TO_DISPLAY);
	}

	$titleLength = $optionMap[ItemHTMLParagraphUtils::TITLE_LENGTH_ID];
	$option->setTitleLength($titleLength);

	$priceItemHTMLOption = ItemHTMLUtils::makePriceItemHTMLOption($optionMap);
	$option->setPriceItemHTMLOption($priceItemHTMLOption);

	$reviewItemHTMLOption = ReviewItemHTMLUtils::makeReviewItemHTMLOption(
			$optionMap, //
			ReviewParagraphUtils::EDITORIAL_REVIEW_LENGTH_ID, //
			ReviewParagraphUtils::ARRAY_OF_STRING_TO_DELETE_ID, //
			ReviewParagraphUtils::ARRAY_OF_STRING_TO_BREAK_ID
	);
	$option->setReviewItemHTMLOption($reviewItemHTMLOption);

	$cacheExpirationInSeconds = $optionMap[ItemHTMLParagraphUtils::CACHE_EXPIRATION_IN_SECONDS_ID];
	$option->setCacheExpirationInSeconds($cacheExpirationInSeconds);

	return $option;
    }

    private static function makePriceItemHTMLOption($optionMap): PriceItemHTMLOption {

	$priceItemHTMLOption = new PriceItemHTMLOption();

	//TODO get_option()から、値を取得する。
	//PriceItemHTMLUtils::makePriceItemHTMLOptionを作成して、共通化する。

	$priceItemHTMLOption->setPriceTimeLinkVisible(PriceParagraphUtils::DEFAULT_PRICE_TIME_LINK_VISIBLE);
	$priceItemHTMLOption->setPriceFooterText(PriceParagraphUtils::DEFAULT_PRICE_TIME_FOOTER_TEXT);

	return $priceItemHTMLOption;
    }

}

KeywordSearchOperation.php


namespace goodsmemo\amazon;

use goodsmemo\network\URLInfo;
use goodsmemo\amazon\CommonRESTParameter;
use goodsmemo\amazon\RESTParameter;
use goodsmemo\amazon\ProductTypeOption;
use goodsmemo\amazon\SearchWidgetOption;
use goodsmemo\amazon\AmazonItemsHTMLInfoMaker;
use goodsmemo\amazon\widget\SearchWidget;
use goodsmemo\item\ItemSearchOperation;
use goodsmemo\item\html\ItemHTMLOption;
use goodsmemo\item\html\ItemArrayHTMLMaking;
use goodsmemo\option\amazon\RESTParagraphUtils;
use goodsmemo\exception\HttpRequestException;
use goodsmemo\exception\IllegalArgumentException;

require_once GOODS_MEMO_DIR . "network/URLInfo.php";
require_once GOODS_MEMO_DIR . "amazon/CommonRESTParameter.php";
require_once GOODS_MEMO_DIR . "amazon/RESTParameter.php";
require_once GOODS_MEMO_DIR . "amazon/ProductTypeOption.php";
require_once GOODS_MEMO_DIR . "amazon/SearchWidgetOption.php";
require_once GOODS_MEMO_DIR . "amazon/AmazonItemsHTMLInfoMaker.php";
require_once GOODS_MEMO_DIR . "amazon/widget/SearchWidget.php";
require_once GOODS_MEMO_DIR . "item/ItemSearchOperation.php";
require_once GOODS_MEMO_DIR . "item/html/ItemHTMLOption.php";
require_once GOODS_MEMO_DIR . "item/html/ItemArrayHTMLMaking.php";
require_once GOODS_MEMO_DIR . "option/amazon/RESTParagraphUtils.php";
require_once GOODS_MEMO_DIR . "exception/HttpRequestException.php";
require_once GOODS_MEMO_DIR . "exception/IllegalArgumentException.php";

/**
 * Description of AmazonKeywordSearchOperation
 *
 * @author Goods Memo
 */
class KeywordSearchOperation {

	public static function makeHTMLOfSearchOperation(
	URLInfo $urlInfo, CommonRESTParameter $commonParameter, RESTParameter $restParameter, ItemHTMLOption $itemHTMLOption,
		ProductTypeOption $productTypeOption, SearchWidgetOption $searchWidgetOption) {

		$affiliateHTML;

		$searchIndex = $restParameter->getSearchIndex();
		switch ($searchIndex) {
			case RESTParagraphUtils::ALL_SEARCH_INDEX:

				$affiliateHTML = KeywordSearchOperation::makeHTMLOfSearchIndex(
						$urlInfo, $commonParameter, $restParameter, $itemHTMLOption, $productTypeOption, $searchWidgetOption);
				break;

			default:

				throw new IllegalArgumentException("無効なサーチインデックス:" . $searchIndex);
		}

		return $affiliateHTML;
	}

	private static function makeHTMLOfSearchIndex(URLInfo $urlInfo, CommonRESTParameter $commonParameter,
		RESTParameter $restParameter, ItemHTMLOption $itemHTMLOption, ProductTypeOption $productTypeOption,
		SearchWidgetOption $searchWidgetOption) {

		$searchWidgetAlwaysEnabled = $searchWidgetOption->getSearchWidgetAlwaysEnabled();
		if ($searchWidgetAlwaysEnabled) {

			$widgetHtml = SearchWidget::makeHtmlOfSearchWidget($commonParameter, $restParameter); //var_dump($widgetHtml);
			return $widgetHtml;
		}

		$itemsHTMLInfoMaker = new AmazonItemsHTMLInfoMaker($commonParameter, $restParameter, $productTypeOption);

		$searchWidgetCache = SearchWidget::getSearchWidgetCache($itemHTMLOption, $itemsHTMLInfoMaker);
		if ($searchWidgetCache !== false) {
			return $searchWidgetCache;
		}

		try {
			$itemsHtml = ItemSearchOperation::makeItemsHTML($urlInfo, $itemHTMLOption, $itemsHTMLInfoMaker);
			return $itemsHtml;
		} catch (HttpRequestException $ex) {

			$responseCode = $ex->getCode();

			/*
			 * APIリクエストが多すぎる場合
			 * 429:Too Many Requests
			 * The request was denied due to request throttling. Please verify the number of requests made per second to the Amazon Product Advertising API.
			 *
			 * Product Advertising API 売上実績なしの場合
			 * 503:RequestThrottled
			 *  A 503 error means that you are submitting requests too quickly and your requests are being throttled.
			 * If this is the case, you need to reduce the number of requests you are sending per second.
			 */
			$searchWidgetEnabled;
			switch ($responseCode) {
				case 429:
				case 503:
					$searchWidgetEnabled = TRUE;
					break;
				default:
					$searchWidgetEnabled = FALSE;
			}

			if ($searchWidgetEnabled) {

				$widgetHtml = SearchWidget::makeHtmlOfSearchWidget($commonParameter, $restParameter);
				SearchWidget::setSearchWidgetCache($widgetHtml, $itemHTMLOption, $itemsHTMLInfoMaker);
				return $widgetHtml;
			} else {
				throw $ex;
			}
		}
	}

}

PriceResponse.php


namespace goodsmemo\amazon;

use goodsmemo\item\PriceItem;
use goodsmemo\item\html\PriceUtils;
use goodsmemo\item\html\HTMLUtils;
use goodsmemo\exception\IllegalArgumentException;

require_once GOODS_MEMO_DIR . "item/PriceItem.php";
require_once GOODS_MEMO_DIR . "item/html/PriceUtils.php";
require_once GOODS_MEMO_DIR . "item/html/HTMLUtils.php";
require_once GOODS_MEMO_DIR . "exception/IllegalArgumentException.php";
//PA-API v5  SDK
require_once(__DIR__ . '/sdk/vendor/autoload.php'); // change path as needed

/**
 * Description of PriceResponse
 *
 * @author Goods Memo
 */
class PriceResponse {

	public static function makePriceItem(\Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\Item $searchItem,
		float $priceTime): PriceItem {

		$priceItem = new PriceItem();
		$offers = $searchItem->getOffers();

		//参考:PA-API v4
		//定価 価格:「ItemAttributes->ListPrice->Amount」「ItemAttributes->ListPrice->FormattedPrice」
		//Amazon.co.jp 価格:「Offers->Offer->OfferListing->Price->Amount」「Offers->Offer->OfferListing->Price->FormattedPrice」
		//マーチャント 新品の価格:「OfferSummary->LowestNewPrice->Amount」「OfferSummary->LowestNewPrice->FormattedPrice」
		//
		//PA-API v5
		//LowestUsedPriceは、無い。Condition ValueにUsedがあった。
		//Offers Listings Condition Value:Valid Values: New, Used, Collectible and Refurbished

		$priceFlag = 0b000;
		if ($offers != NULL
			and $offers->getListings() != NULL
			and $offers->getListings()[0] != NULL
			and $offers->getListings()[0]->getPrice() != NULL
			and $offers->getListings()[0]->getPrice()->getAmount() != NULL
		) {
			$priceFlag = $priceFlag | 0b001; //「Amazon.co.jp 価格」が存在する。
		}
		if ($offers != NULL
			and $offers->getSummaries() != NULL
			and $offers->getSummaries()[0] != NULL
			and $offers->getSummaries()[0]->getLowestPrice() != NULL
			and $offers->getSummaries()[0]->getLowestPrice()->getAmount() != NULL
		) {
			$priceFlag = $priceFlag | 0b010; //「価格(最安値)」が存在する。
		}
		//if (isset($node->OfferSummary->LowestUsedPrice->FormattedPrice)) {
		//	$priceFlag = $priceFlag | 0b100; //「マーチャント 中古の価格」が存在する。
		//}
		//var_dump($priceFlag);

		switch ($priceFlag) {
			case 0b000:
				PriceResponse::setEmptyPriceTo($priceItem);
				break;
			case 0b001:
			case 0b101:
				PriceResponse::setAmazonPriceTo($priceItem, $offers);
				break;
			case 0b010:
			case 0b110:
				PriceResponse::setLowestPriceTo($priceItem, $offers);
				break;
			case 0b011:
			case 0b111:
				PriceResponse::setFitNewPriceTo($priceItem, $offers);
				break;
			case 0b100:
				PriceResponse::setMerchantUsedPriceTo($priceItem, $offers);
				break;
			default :
				throw new IllegalArgumentException("無効な価格フラグ値:" . decbin($priceFlag));
		}

		if ($offers != NULL
			and $offers->getListings() != NULL
			and $offers->getListings()[0] != NULL
			and $offers->getListings()[0]->getDeliveryInfo() != NULL) {

			$isFreeShippingEligible = $offers->getListings()[0]->getDeliveryInfo()->getIsFreeShippingEligible(); //bool型	//var_dump($isFreeShippingEligible);
			if ($isFreeShippingEligible) {
				$priceItem->setPostageText("送料無料");
			}
		}

		$priceItem->setPriceTime($priceTime);

		return $priceItem;
	}

	private static function setEmptyPriceTo(&$priceItem) {

		$priceItem->setLabel("価格");
		$priceItem->setPrice("");
		$priceItem->setPriceAddition("");
	}

	private static function setAmazonPriceTo(&$priceItem, $offers) {

		$priceItem->setLabel("価格"); //スマートフォンの画面幅が狭いため、文字数を短くした。「Amazon.co.jp 価格」

		$amazonPrice = PriceResponse::makeAmazonPriceIfAmoutIsSet($offers);
		$formattedPrice = PriceUtils::makeFormattedPrice($amazonPrice);
		$priceItem->setPrice($formattedPrice);

		$priceItem->setPriceAddition("");
	}

	private static function setLowestPriceTo(&$priceItem, $offers) {

		$priceItem->setLabel("最安価格"); //参考:PA-API v4の場合、新品価格

		$lowestPrice = PriceResponse::makeLowestPriceIfAmoutIsSet($offers);
		$formattedPrice = PriceUtils::makeFormattedPrice($lowestPrice);
		$priceItem->setPrice($formattedPrice);

		$priceItem->setPriceAddition("");
	}

	private static function setMerchantUsedPriceTo(&$priceItem, $offers) {

		throw new Exception("setMerchantUsedPriceTo()が、呼び出された。");

//		$priceItem->setLabel("中古価格");
//
//		$merchantPrice = PriceResponse::makeMerchantUsedPriceIfAmoutIsSet($offers);
//		$formattedPrice = PriceUtils::makeFormattedPrice($merchantPrice);
//		$priceItem->setPrice($formattedPrice);
//
//		$priceItem->setPriceAddition("より");
	}

	private static function setFitNewPriceTo(&$priceItem, $offers) {
		//Fit:ちょうど良い

		$amazonPrice = PriceResponse::makeAmazonPriceIfAmoutIsSet($offers);
		$lowestPrice = PriceResponse::makeLowestPriceIfAmoutIsSet($offers);

		if (is_numeric($amazonPrice) && is_numeric($lowestPrice)) {//var_dump(is_numeric($amazonPrice));//var_dump(is_numeric($merchantPrice));
			$amazonPrice = intval($amazonPrice);
			$lowestPrice = intval($lowestPrice);

			if ($amazonPrice < $lowestPrice) {
				PriceResponse::setAmazonPriceTo($priceItem, $offers);
			} else {
				PriceResponse::setLowestPriceTo($priceItem, $offers);
			}
		} else {
			PriceResponse::setEmptyPriceTo($priceItem);
		}
	}

	private static function makeAmazonPriceIfAmoutIsSet($offers) {

		if ($offers != NULL
			and $offers->getListings() != NULL
			and $offers->getListings()[0] != NULL
			and $offers->getListings()[0]->getPrice() != NULL
			and $offers->getListings()[0]->getPrice()->getAmount() != NULL
		) {
			$priceAmount = $offers->getListings()[0]->getPrice()->getAmount();
			return HTMLUtils::makePlainText((string) $priceAmount);
		} else {
			return "";
		}
	}

	private static function makeLowestPriceIfAmoutIsSet($offers) {

		if ($offers != NULL
			and $offers->getSummaries() != NULL
			and $offers->getSummaries()[0] != NULL
			and $offers->getSummaries()[0]->getLowestPrice() != NULL
			and $offers->getSummaries()[0]->getLowestPrice()->getAmount() != NULL
		) {
			$lowestPriceAmount = $offers->getSummaries()[0]->getLowestPrice()->getAmount();
			return HTMLUtils::makePlainText((string) $lowestPriceAmount);
		} else {
			return "";
		}
	}

	private static function makeMerchantUsedPriceIfAmoutIsSet($offers) {

		throw new Exception("makeMerchantUsedPriceIfAmoutIsSet()が、呼び出された。");

//		if (isset($node->OfferSummary->LowestUsedPrice->Amount)) {
//
//			return HTMLUtils::makePlainText(
//					(string) $node->OfferSummary->LowestUsedPrice->Amount //例:object(SimpleXMLElement) public 0 => string '999' (length=3)
//			);
//		} else {
//
//			return "";
//		}
	}

}

ProductionResponse.php


namespace goodsmemo\amazon;

use goodsmemo\item\ProductionItem;
use goodsmemo\item\html\HTMLUtils;

require_once GOODS_MEMO_DIR . "item/ProductionItem.php";
require_once GOODS_MEMO_DIR . "item/html/HTMLUtils.php";
//PA-API v5  SDK
require_once(__DIR__ . '/sdk/vendor/autoload.php'); // change path as needed

/**
 * Description of ProductionResponse
 *
 * @author Goods Memo
 */
class ProductionResponse {

	//str_replace()用 検索文字列と置換文字列
	const MANUFACTURER_LABEL_SEARCH = array("Manufacturer");
	const MANUFACTURER_LABEL_REPLACE = array("製造元");

	public static function makeProductionItem(\Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\Item $searchItem): ProductionItem {

		$productionItem = new ProductionItem();

		if ($searchItem->getItemInfo() == NULL) {
			return $productionItem;
		}

		$itemInfo = $searchItem->getItemInfo();

		if ($itemInfo->getClassifications() != NULL
			and $itemInfo->getClassifications()->getBinding() != NULL
			and $itemInfo->getClassifications()->getBinding()->getDisplayValue() != NULL) {

			$bindingValue = $itemInfo->getClassifications()->getBinding()->getDisplayValue();
			$productionItem->setBinding(HTMLUtils::makePlainText($bindingValue));
		}

		if ($itemInfo->getByLineInfo() != NULL) {

			$byLineInfo = $itemInfo->getByLineInfo();

			if ($byLineInfo->getContributors() != NULL) {

				$contributors = $byLineInfo->getContributors(); //Contributor[]
				$contributorArray = array();
				foreach ($contributors as $contributor) {

					if ($contributor == NULL) {
						continue;
					}

					$role = HTMLUtils::makePlainText($contributor->getRole());
					$name = HTMLUtils::makePlainText($contributor->getName());
					$contributorValue = $name . "(" . $role . ")";
					array_push($contributorArray, $contributorValue);

					if (strcmp($role, "著") == 0 and empty($productionItem->getManufacturerLabel())) {
						$productionItem->setManufacturerLabel("出版社");
					}
				}

				$productionItem->setContributorArray($contributorArray);
			}

			if ($byLineInfo->getManufacturer() != NULL
				and $byLineInfo->getManufacturer()->getDisplayValue() != NULL) {

				$manufacturer = $byLineInfo->getManufacturer();   //var_dump($manufacturer);
				if ($manufacturer->getLabel() != NULL and empty($productionItem->getManufacturerLabel())) {

					$manufacturerLabel = HTMLUtils::makePlainText($manufacturer->getLabel());
					$manufacturerLabel = str_replace(ProductionResponse::MANUFACTURER_LABEL_SEARCH,
						ProductionResponse::MANUFACTURER_LABEL_REPLACE, $manufacturerLabel);
					$productionItem->setManufacturerLabel($manufacturerLabel);
				}

				$manufacturerValue = HTMLUtils::makePlainText($manufacturer->getDisplayValue());
				$productionItem->setManufacturer($manufacturerValue);
			}
		}

		return $productionItem;
	}

}

ProductTypeOption.php


namespace goodsmemo\amazon;

/**
 * Description of ProductTypeOption
 *
 * @author Goods Memo
 */
class ProductTypeOption {

	//ItemHTMLのOptionではないと判断した。
	private $adultProductEnabled = false;

	public function getAdultProductEnabled() {
		return $this->adultProductEnabled;
	}

	public function setAdultProductEnabled($adultProductEnabled) {
		$this->adultProductEnabled = $adultProductEnabled;
	}

}

RESTParameter.php


namespace goodsmemo\amazon;

use goodsmemo\network\DefaultRESTParameter;

require_once GOODS_MEMO_DIR . "network/DefaultRESTParameter.php";

/**
 * Description of RESTParameter
 *
 * @author Goods Memo
 */
class RESTParameter extends DefaultRESTParameter {

    private $operation;
    private $searchIndex;
    private $searchItemsResources;

    public function getOperation() {
	return $this->operation;
    }

    public function getSearchIndex() {
	return $this->searchIndex;
    }

    public function getSearchItemsResources() {
	return $this->searchItemsResources;
    }

    public function setOperation($operation) {
	$this->operation = $operation;
    }

    public function setSearchIndex($searchIndex) {
	$this->searchIndex = $searchIndex;
    }

    public function setSearchItemsResources($searchItemsResources) {
	$this->searchItemsResources = $searchItemsResources;
    }

}

SearchWidgetOption.php


namespace goodsmemo\amazon;

/**
 * Description of SearchWidgetOption
 *
 * @author Goods Memo
 */
class SearchWidgetOption {

	private $searchWidgetAlwaysEnabled = false;

	public function getSearchWidgetAlwaysEnabled() {
		return $this->searchWidgetAlwaysEnabled;
	}

	public function setSearchWidgetAlwaysEnabled($searchWidgetAlwaysEnabled) {
		$this->searchWidgetAlwaysEnabled = $searchWidgetAlwaysEnabled;
	}

}

widget名前空間

SearchWidget.php


namespace goodsmemo\amazon\widget;

use goodsmemo\amazon\CommonRESTParameter;
use goodsmemo\amazon\RESTParameter;
use goodsmemo\amazon\AmazonItemsHTMLInfoMaker;
use goodsmemo\item\html\ItemHTMLOption;
use goodsmemo\exception\FileNotFoundException;

require_once GOODS_MEMO_DIR . "amazon/CommonRESTParameter.php";
require_once GOODS_MEMO_DIR . "amazon/RESTParameter.php";
require_once GOODS_MEMO_DIR . "amazon/AmazonItemsHTMLInfoMaker.php";
require_once GOODS_MEMO_DIR . "item/html/ItemHTMLOption.php";
require_once GOODS_MEMO_DIR . "exception/FileNotFoundException.php";

/**
 * Description of SearchWidget
 *
 * @author Goods Memo
 */
class SearchWidget {

	const SEARCH_WIDGET_PREFIX = "search_w";

	public static function makeHtmlOfSearchWidget(
	CommonRESTParameter $commonParameter, RESTParameter $restParameter) {

		$filename = __DIR__ . "/SearchWidget.html";
		$widgetHtml = file_get_contents($filename); //$widgetHtml = false;
		if ($widgetHtml === false) {
			$errorMessage = "検索ウィジェットファイルの読み込み失敗:filename=[" . $filename . "]";
			throw new FileNotFoundException($errorMessage);
		}

		$searchArray = array("GOODS_MEMO_ASSOCIATE_TAG", "GOODS_MEMO_SEARCH_KEYWORD");

		$associateTag = $commonParameter->getAssociateTag();
		$keyword = $restParameter->getKeyword();
		$replaceArray = array($associateTag, $keyword);

		$newWidgetHtml = str_replace($searchArray, $replaceArray, $widgetHtml);

		return $newWidgetHtml;
	}

	public static function getSearchWidgetCache(ItemHTMLOption $itemHTMLOption, AmazonItemsHTMLInfoMaker $itemsHTMLInfoMaker) {

		$cacheExpirationInSeconds = $itemHTMLOption->getCacheExpirationInSeconds();
		if ($cacheExpirationInSeconds <= 0) {
			return false;
		}

		$transientID = SearchWidget::makeTransientID($itemHTMLOption, $itemsHTMLInfoMaker);
		$searchWidgetCache = get_transient($transientID);
		//var_dump($searchWidgetCache);

		return $searchWidgetCache;
	}

	public static function setSearchWidgetCache($widgetHtml, ItemHTMLOption $itemHTMLOption, AmazonItemsHTMLInfoMaker $itemsHTMLInfoMaker) {

		$transientID = SearchWidget::makeTransientID($itemHTMLOption, $itemsHTMLInfoMaker);
		$cacheExpirationInSeconds = $itemHTMLOption->getCacheExpirationInSeconds();

		//一時的にデータベースに検索ウィジェットHTMLを保存する。有効期限後、削除される。
		set_transient($transientID, $widgetHtml, $cacheExpirationInSeconds);
		//var_dump($newWidgetHtml);
	}

	private static function makeTransientID(ItemHTMLOption $itemHTMLOption, AmazonItemsHTMLInfoMaker $itemsHTMLInfoMaker) {

		$uniqueText = $itemsHTMLInfoMaker->makeUniqueText($itemHTMLOption);
		$uniqueTextOfWidget = SearchWidget::SEARCH_WIDGET_PREFIX . $uniqueText;

		//$transientID:キャッシュされるデータにつけるユニークな識別子。長さ 45 文字以下であること。
		//md5() :32 文字の 16 進数からなるハッシュを返します。
		$transientID = GOODS_MEMO_PREFIX . md5($uniqueTextOfWidget); //var_dump($transientID);

		return $transientID;
	}

}

SearchWidget.html


<div class="goodsmemo-amazon-search-widget">
    <script type="text/javascript">amzn_assoc_ad_type = "responsive_search_widget"; amzn_assoc_tracking_id = "GOODS_MEMO_ASSOCIATE_TAG"; amzn_assoc_marketplace = "amazon"; amzn_assoc_region = "JP"; amzn_assoc_placement = ""; amzn_assoc_search_type = "search_widget";amzn_assoc_width = "336"; amzn_assoc_height = "280"; amzn_assoc_default_search_category = ""; amzn_assoc_default_search_key = "GOODS_MEMO_SEARCH_KEYWORD";amzn_assoc_theme = "light"; amzn_assoc_bg_color = "FFFFFF";</script><script src="//z-fe.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&Operation=GetScript&ID=OneJS&WS=1&Marketplace=JP"></script>
</div>
<!--
注意:「Autoptimize 設定 - インラインの JS を連結」を有効にすると、アマゾンサーチウィジェットのscriptタグが移動してしまい、表示されない。
-->
コンピューター
この記事をシェアする

グッズ・メモランダム