helper = $helper; } function callAmazonApi( $method, $searchString = '' ) { if( !in_array( $method, [self::AMZN_API_METHOD_GETITEMS,self::AMZN_API_METHOD_SEARCHITEMS] ) ) { // not an allowed method return false; } if( $method == self::AMZN_API_METHOD_GETITEMS ) { $responseResultKey = 'ItemsResult'; } else if( $method == self::AMZN_API_METHOD_SEARCHITEMS ) { $responseResultKey = 'SearchResult'; } else { return false; } if( substr( trim( $searchString ), -1 ) != ',' ) { $searchString .= ','; } $serviceName="ProductAdvertisingAPI"; $region = "us-east-1"; $accessKey = get_option( $this->helper->getOptionName( PipAmzpaHelper::OPTION_AUTH_KEY_ACCESS ) ); $secretKey = get_option( $this->helper->getOptionName( PipAmzpaHelper::OPTION_AUTH_KEY_SECRET ) ); $payload = "{" . $searchString ." \"Resources\": [" ." \"CustomerReviews.StarRating\"," ." \"Images.Primary.Small\"," ." \"Images.Primary.Medium\"," ." \"Images.Primary.Large\"," ." \"ItemInfo.TechnicalInfo\"," ." \"ItemInfo.Title\"," ." \"ItemInfo.Features\"," ." \"Offers.Listings.Price\"," ." \"Offers.Listings.Promotions\"," ." \"Offers.Listings.DeliveryInfo.IsPrimeEligible\"" ." ]," ." \"ItemCount\": ".get_option( $this->helper->getOptionName( PipAmzpaHelper::OPTION_AUTO_NUM_ITEMS ) )."," ." \"PartnerTag\": \"".get_option( $this->helper->getOptionName( PipAmzpaHelper::OPTION_AUTH_ID_ACCOUNT ) )."\"," ." \"PartnerType\": \"Associates\"," ." \"Marketplace\": \"".get_option( $this->helper->getOptionName( PipAmzpaHelper::OPTION_AUTH_MARKETPLACE ) )."\"" ."}"; $host="webservices.amazon.com"; $uriPath="/paapi5/" . strtolower( $method ); require_once 'pip-amzpa-AwsV4.php'; $awsv4 = new PipAmzpaAwsV4($accessKey, $secretKey); $awsv4->setRegionName($region); $awsv4->setServiceName($serviceName); $awsv4->setPath($uriPath); $awsv4->setPayload($payload); $awsv4->setRequestMethod("POST"); $awsv4->addHeader('content-encoding', 'amz-1.0'); $awsv4->addHeader('content-type', 'application/json; charset=utf-8'); $awsv4->addHeader('host', $host); $awsv4->addHeader('x-amz-target', 'com.amazon.paapi5.v1.ProductAdvertisingAPIv1.' . $method); // TODO: implement transient caching https://developer.wordpress.org/plugins/http-api/#wordpress-transients $argsAmazonApi = [ 'headers' => $awsv4->getHeaders(), 'body' => $payload ]; $responseAmazonApi = wp_remote_post( 'https://'.$host.$uriPath, $argsAmazonApi ); $responseCodeAmazonApi = wp_remote_retrieve_response_code( $responseAmazonApi ); if( $responseCodeAmazonApi == 200 ) { $responseBodyAmazonApi = wp_remote_retrieve_body( $responseAmazonApi ); $amzJson = json_decode( $responseBodyAmazonApi ); if( is_object($amzJson) && property_exists( $amzJson, $responseResultKey ) ) { if( is_object($amzJson->$responseResultKey) && property_exists( $amzJson->$responseResultKey, 'Items' ) ) { $items = $amzJson->$responseResultKey->Items; if( is_array($items) && count( $items ) > 0 ) { return $items; } } } } return false; } function getAdsAuto($content) { if( is_single() ){ if( get_option( $this->helper->getOptionName( PipAmzpaHelper::OPTION_AUTO_ENABLED ) ) == 'on' ) { if( $this->helper->getContentHasAmazonLinks( $content ) ) { // TODO: use Yoast Keywords Focus as search logic (if plugin is installed) // TODO: use whatever Rankmath has as a good identifier for search logic (if plugin is installed) // TODO: use post excerpt as search keywords // TODO: use post categories as search keywords // TODO: allow user to choose prefered first method of auto search logic (keywords, tags, meta title) $tags = wp_get_post_tags(get_the_ID()); if( count( $tags ) > 0 ) { $tagTerms = ""; foreach( $tags AS $i => $tag ) { $tagTerms .= " " . $tag->name; } } else { $tagTerms = get_the_title( get_the_ID() ); } if( strlen( trim( $tagTerms ) ) > 0 ) { // TODO: how many API calls does Amazon allow for? (will this plugin "abuse" the Amazon policies?) // TODO: add config for image // TODO: add config for heading // TODO: add config for price // TODO: add config to show prime checkmark // TODO: add config to display reviews // TODO: add config to fetch only by top reviews // TODO: add item count per row to config // TODO: add horizontal scroller (pro) // TODO: build in caching // TODO: add a custom block with it's own options (pro) // TODO: add configuration per blog post to change what to search for (pro) // TODO: fetch ratings and reviews from here: https://www.amazon.com/gp/customer-reviews/widgets/average-customer-review/popover/ref=dpx_acr_pop_?contextId=dpx&asin=B000P0ZSHK // source: https://stackoverflow.com/questions/8279478/amazon-product-advertising-api-get-average-customer-rating?rq=4 $searchString = '"Keywords": "' . $tagTerms . '"'; $items = $this->callAmazonApi( self::AMZN_API_METHOD_SEARCHITEMS, $searchString ); if( $items ) { $content .= '