Rev 106 | Rev 116 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?phpinclude_once ('php/constants.php');error_reporting(E_ALL);// Get itunes listingsfunction get_amazon($query, $searchCondition) {$vendors = Vendors::getInstance();$config = $vendors->getVendor(Vendors::AMAZON);$needMatches = empty($_SESSION["discogs"]);$arrMusic = [];$arrDigital = [];$arrBooks = [];// Music$arrMusic = get_amazonCategory($config, $query, "Music", $needMatches);// Digital Musicif ($_SESSION["filterMediaType"]["Digital"]) {$arrDigital = get_amazonCategory($config, $query, "DigitalMusic");}if ($_SESSION["filterMediaType"]["Book"]) {// Books$arrBooks = get_amazonCategory($config, $query, "Books");}return (array_merge($arrMusic, $arrDigital, $arrBooks));}// Get Amazon listingsfunction get_amazonCategory($config, $query, $searchIndex, $needMatches = false) {$numResults = $config['numResults'];if ($needMatches) {$_SESSION["discogs"] = "";}$response = getSearchCache("amazon", $query, $searchIndex);if ($response === false) {$serviceName = "ProductAdvertisingAPI";$region = "us-east-1";$accessKey = $config["access_key_id"];$secretKey = $config["secret_key"];$associate_tag = $config['associate_tag'];$payload="{"." \"Keywords\": \"$query\","." \"Resources\": ["." \"Images.Primary.Medium\","." \"Images.Primary.Large\","." \"ItemInfo.ByLineInfo\","." \"ItemInfo.ContentInfo\","." \"ItemInfo.Classifications\","." \"ItemInfo.ExternalIds\","." \"ItemInfo.ManufactureInfo\","." \"ItemInfo.ProductInfo\","." \"ItemInfo.TechnicalInfo\","." \"ItemInfo.Title\","." \"Offers.Listings.Condition\","." \"Offers.Listings.Condition.SubCondition\","." \"Offers.Listings.DeliveryInfo.IsAmazonFulfilled\","." \"Offers.Listings.DeliveryInfo.IsFreeShippingEligible\","." \"Offers.Listings.DeliveryInfo.IsPrimeEligible\","." \"Offers.Listings.DeliveryInfo.ShippingCharges\","." \"Offers.Listings.MerchantInfo\","." \"Offers.Listings.Price\""." ],"." \"SearchIndex\": \"$searchIndex\","." \"Availability\": \"Available\","." \"Condition\": \"Any\","." \"OfferCount\": 3,"." \"SortBy\": \"Price:LowToHigh\","." \"PartnerTag\": \"$associate_tag\","." \"PartnerType\": \"Associates\","." \"Marketplace\": \"www.amazon.com\""."}";$host = "webservices.amazon.com";$uriPath = "/paapi5/searchitems";$awsv4 = new AwsV4($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.SearchItems');$headers = $awsv4->getHeaders();$headerArr = [];foreach ($headers as $key => $value) {$headerArr[] = $key . ': ' . $value;}$ch = curl_init();curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArr);curl_setopt($ch, CURLOPT_URL, 'https://' . $host . $uriPath);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch, CURLOPT_TIMEOUT, 15);curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_REFERER, 'https://' . $host . $uriPath);curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);curl_setopt($ch, CURLOPT_POST, 1);$response = curl_exec($ch);curl_close($ch);saveSearchCache("amazon", $query, $searchIndex, $response);}$parsed_json = json_decode($response);//echo "<br><pre>";print_r($parsed_json);echo "</pre>";$arr = [];if (isset($parsed_json->Errors)) {foreach ($parsed_json->Errors as $error) {if ($error->Code != "NoResults") {my_error_log("Amazon Search - " . $error->Message . " (" . $error->Code . ")");}}return [];} else if (!isset($parsed_json->SearchResult)) {my_error_log("Amazon Search - No Search Result.");return [];}if ($needMatches) {$cnt = 0;$_SESSION["discogs"] = startMatches();}$listings = 0;// If the response was loaded, parse it and store in arrayforeach ($parsed_json->SearchResult->Items as $current) {if (isset($current->ItemInfo->ExternalIds->UPCs)) {$barcode = (string)$current->ItemInfo->ExternalIds->UPCs->DisplayValues[0];}else if (isset($current->ItemInfo->ExternalIds->EANs)) {$barcode = (string)$current->ItemInfo->ExternalIds->EANs->DisplayValues[0];}else if (isset($current->ItemInfo->ExternalIds->ISBNs)) {$barcode = (string)$current->ItemInfo->ExternalIds->ISBNs->DisplayValues[0];}else if (isset($current->ItemInfo->ExternalIds->EISBNs)) {$barcode = (string)$current->ItemInfo->ExternalIds->EISBNs->DisplayValues[0];}else {$barcode = "";}$barcodeType = clsLibGTIN::GTINCheck($barcode, false, 1);$pic = !empty($current->Images->Primary->Medium->URL) ? (string)$current->Images->Primary->Medium->URL : "images/no-image-available.jpg";$pic = str_replace('http://', 'https://', $pic);if (empty($pic)) {continue;}if (strpos($current->ItemInfo->Classifications->Binding->DisplayValue, "Audio CD") !== false) {$mediaType = "CD";}else if (strpos($current->ItemInfo->Classifications->Binding->DisplayValue, "MP3 Music") !== false) {$mediaType = "Digital";}else if (strpos($current->ItemInfo->Classifications->Binding->DisplayValue, "Vinyl") !== false) {$mediaType = "Record";}else if (strpos($current->ItemInfo->Classifications->Binding->DisplayValue, "Paperback") !== false || strpos($current->ItemInfo->Classifications->Binding->DisplayValue, "Sheet") !== false || strpos($current->ItemInfo->Classifications->Binding->DisplayValue, "Hardcover") !== false) {$mediaType = "Book";}else {continue;}if ($needMatches) {// bugbug: check maxMasterCnt?$_SESSION["discogs"] .= addMatch($current, ++$cnt, $mediaType);}$title = (string)$current->ItemInfo->Title->DisplayValue;$artists = getArtists($current);$contributers = getContributers($current);if (!empty($artists)) {$title .= " by " . join(", ", $artists);}else if (!empty($contributers)) {$title .= " by " . join(", ", $contributers);}$url = str_replace('http://', 'https://', (string)$current->DetailPageURL);if (empty($url)) {continue;}$bestOffer = false;$url = str_replace('http://', 'https://', (string)$current->DetailPageURL);$url .= "&condition=";if (!empty($current->Offers->Listings)) {foreach ($current->Offers->Listings as $offer) {$country = 'US';if (isset($offer->MerchantInfo->DefaultShippingCountry)) {$country = $offer->MerchantInfo->DefaultShippingCountry;}$merchantName = "Amazon";if (strpos($offer->MerchantInfo->Name, "Amazon") === false) {$merchantName .= " Marketplace";}$condition = (string)$offer->Condition->Value;$url .= $condition;$detailCondition = $condition;if ($condition == "Collectible") {$condition = 'Used';$detailCondition = "Collectible";}if ($condition == "Refurbished") {$condition = 'Used';$detailCondition = "Refurbished";}$currency = (string)$offer->Price->Currency;$price = number_format(floatval($offer->Price->Amount) , 2, '.', '');if ($price <= "0.00") {continue;}$timeLeft = 0;$listingType = 'Fixed';$location = 'US';$zip = '';$feedbackScore = - 1;$feedbackPercent = - 1;$sellerName = "";$handlingTime = 0;if ($offer->DeliveryInfo->IsPrimeEligible === true) {$sellerName = "Prime";}if ($mediaType == "Digital") {$shippingCost = 0.00;$shippingEstimated = false;$shippingCurrency = 'USD';}else {$shippingCost = 3.99; // bugbug$shippingEstimated = true; // bugbug$shippingCurrency = 'USD';}$freeShippingCap = !empty($offer->DeliveryInfo->IsFreeShippingEligible) ? 25 : 0;if (++$listings > $numResults) {continue;}$arr[] = array("Merchant" => $merchantName,"Condition" => $condition,"Title" => $title,"Barcode" => $barcode,"BarcodeType" => $barcodeType,"Image" => $pic,"URL" => $url,"MediaType" => $mediaType,"DetailCondition" => $detailCondition,"Country" => $country,"BestOffer" => $bestOffer,"TimeLeft" => $timeLeft,"Price" => $price,"Currency" => $currency,"ListingType" => $listingType,"Location" => $location,"Zip" => $zip,"FeedbackScore" => $feedbackScore,"FeedbackPercent" => $feedbackPercent,"SellerName" => $sellerName,"HandlingTime" => $handlingTime,"ShippingCost" => $shippingCost,"ShippingEstimated" => $shippingEstimated,"ShippingCurrency" => $shippingCurrency,"FreeShippingCap" => $freeShippingCap,"Show" => true);}}}if ($needMatches) {if ($cnt = 0) {$_SESSION["discogs"] = "";}else {$_SESSION["discogs"] .= endMatches();}}// If the response does not indicate 'Success,' log the error(s)/******************else {my_error_log($url);if (!empty($parsed_json->OperationRequest->Errors)) {foreach($parsed_json->OperationRequest->Errors->Error as $error){my_error_log($error->Message . " (" . $error->Code . ")");}} else if (!empty($parsed_json->Errors)) {foreach($parsed_json->OperationRequest->Errors->Error as $error){my_error_log($error->Message . " (" . $error->Code . ")");}} else if (!empty($parsed_json->Error)) {my_error_log($parsed_json->Error->Message . " (" . $parsed_json->Error->Code . ")");} else {my_error_log(print_r($result, 1));}}******************/return $arr;}function startMatches() {$str = "<div class=\"container-fluid bg-secondary\">";$str .= "<h4 class=\"text-center py-2\">Matching Albums</h4>";$str .= "<form method=\"post\" action=\"/index.php\">";$str .= "<input type=\"hidden\" name=\"sessionTab\" value=\"" . MySessionHandler::getSessionTab() . "\">";$str .= "<input id=\"discogsTitle\" type=\"hidden\" name=\"discogsTitle\" value=\"\">";$str .= "<input id=\"discogsArtist\" type=\"hidden\" name=\"discogsArtist\" value=\"\">";$str .= "<input id=\"discogsBarcode\" type=\"hidden\" name=\"discogsBarcode\" value=\"\">";$str .= "<div id=\"discogsDeck\" class=\"card-deck\">";return $str;}function endMatches() {$str = "</div>";$str .= "</form>";$str .= "</div>";return $str;}function addMatch($item, $cnt, $mediaType) {$artists = getArtists($item);$contributers = getContributers($item);$label = "";if (!empty($item->ItemInfo->ByLineInfo->Manufacturer)) {$label = $item->ItemInfo->ByLineInfo->Manufacturer->DisplayValue;}$languages = [];if (!empty($item->ItemInfo->ContentInfo->Languages)) {foreach ($item->ItemInfo->ContentInfo->Languages->DisplayValues as $language) {if ((string)$language->Type != "Unknown") {$languages[] = $language->DisplayValue . " (" . $language->Type . ")";}}}$genres = [];if (!empty($item->ItemInfo->Genre)) {foreach($item->ItemInfo->Genre as $genre) {$genres[] = join(" ", array_map('ucfirst', explode('-', $genre)));}}$runningTime = "";if (!empty($item->ItemInfo->RunningTime)) {if ($mediaType != 'Digital') {$runningTime = (string)$item->ItemInfo->RunningTime . " minutes";} else {$runningTime = gmdate("H:i:s", (int)$item->ItemInfo->RunningTime);}}$modal = "";$str = "<div class=\"card mx-auto discogs-card\">";$str .= "<div class=\"card-header bg-info d-flex h-100\">";$str .= "<p class=\"card-title font-weight-bold small flex-grow-1\">" . (string)$item->ItemInfo->Title->DisplayValue . " by ";$searchArtists = "";$wlArtists = "";if (!empty($artists)) {if (count($artists) < 5) {$wlArtists = join(", ", $artists);if (!empty($artists) && $artists[0] != 'Various') {$searchArtists = join(" ", $artists);}} else {$wlArtists = "Various Artists";}}else if (!empty($contributers)) {if (count($contributers) < 5) {$wlArtists = join(", ", $contributers);if (!empty($contributers) && $contributers[0] != 'Various') {$searchArtists = join(" ", $contributers);}} else {$wlArtists = "Various Artists";}}$str .= $wlArtists;$str .= "</p>";$str .= "</div>";$thumbnail = !empty($item->Images->Primary->Medium->URL) ? (string)$item->Images->Primary->Medium->URL : "images/no-image-available.jpg";$str .= "<div class=\"card-body bg-light mx-auto p-0 m-0\">";$str .= "<img class=\"btn responsive-image p-0 m-0 lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . $thumbnail . "\" data-toggle=\"modal\" data-target=\"#masterModal" . $cnt . "\" title=\"Album Information\" data-toggle2=\"tooltip\" alt=\"Cover Thumbnail\">";$str .= "</div>";$str .= "<div class=\"card-footer bg-dark p-0 m-0\">";$str .= "<div class=\"container clearfix p-0 m-0\">";$str .= "<span class=\"float-left\">";$str .= "<button type=\"button\" class=\"btn btn-primary m-1 btn-sm\" data-toggle=\"modal\" data-target=\"#masterModal" . $cnt . "\" title=\"Album Information\" data-toggle2=\"tooltip\"><i class=\"fas fa-info\"></i></button>";$str .= "</span>";$str .= "<span class=\"float-right\">";$barcode = "";$tmpBarcode = "";if (isset($item->ItemInfo->ExternalIds->UPCs)) {$tmpBarcode = (string)$item->ItemInfo->ExternalIds->UPCs->DisplayValues[0];}else if (isset($item->ItemInfo->ExternalIds->EANs)) {$tmpBarcode = (string)$item->ItemInfo->ExternalIds->EANs->DisplayValues[0];}else if (isset($item->ItemInfo->ExternalIds->ISBNs)) {$tmpBarcode = (string)$item->ItemInfo->ExternalIds->ISBNs->DisplayValues[0];}else if (isset($item->ItemInfo->ExternalIds->EISBNs)) {$tmpBarcode = (string)$item->ItemInfo->ExternalIds->EISBNs->DisplayValues[0];}$barcodeType = clsLibGTIN::GTINCheck($tmpBarcode, false, 1);if (!empty($barcodeType)) {$barcode = $tmpBarcode;}if (isLoggedIn() && !checkWishlist('asin', $item->ASIN)) {$wlArr = array('asin' => (string)$item->ASIN,'title' => (string)$item->ItemInfo->Title->DisplayValue,'artist' => $wlArtists,'barcode' => $barcode,'thumbnail' => $thumbnail,'url' => (string)$item->DetailPageURL);$wl = base64_encode(json_encode($wlArr));$str .= " <button type=\"button\" class=\"btn btn-primary m-1 btn-sm\" onclick=\"addWishlist('" . $_SESSION['sessData']['userID'] . "',this," . $cnt . ",'" . $wl . "');\" title=\"Add to Wishlist\" data-toggle=\"tooltip\"><i class=\"fas fa-bookmark\"></i></button>";}$searchTitle = 'Searching for:<br><br><strong>' . (string)$item->ItemInfo->Title->DisplayValue . ' by ' . $wlArtists . '</strong>';if (!empty($barcode)) {$searchTitle .= " (" . displayBarcode($barcode) . ")";}$str .= " <button type=\"submit\" name=\"submit\" value=\"discogsSearch\" class=\"btn btn-primary m-1 btn-sm\" onclick=\"document.getElementById('discogsTitle').value = '" . addslashes((string)$item->ItemInfo->Title->DisplayValue) . "';document.getElementById('discogsArtist').value = '" . addslashes($searchArtists) . "';document.getElementById('discogsBarcode').value = '" . $barcode . "';progressBar('" . sanitizeInput2($searchTitle) . "');\" title=\"Search for Store Offers\" data-toggle=\"tooltip\"><i class=\"fas fa-search\"></i></button>";$str .= "</span>";$str .= "</div>";$str .= "<span id=\"wishlistAdd" . $cnt . "\"></span>";$str .= "</div>";$modal .= "<div id=\"masterModal" . $cnt . "\" class=\"modal\">";$modal .= "<div class=\"modal-dialog\">";$modal .= "<div class=\"modal-content\">";$modal .= "<div class=\"modal-header bg-primary\">";$modal .= "<h4 class=\"modal-title mx-auto\">" . (string)$item->ItemInfo->Title->DisplayValue . " by " . $wlArtists . "</h4>";$modal .= "<button type=\"button\" class=\"close\" data-dismiss=\"modal\"><i class=\"fas fa-window-close btn-dismiss\"></i></button>";$modal .= "</div>";$modal .= "<div class=\"modal-body bg-white mx-auto\">";if (!empty($item->Images->Primary->Large->URL)) {$modal .= "<img class=\"responsive-image mx-auto mb-4 lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . (string)$item->Images->Primary->Large->URL . "\" alt=\"Cover Image\">";}$modal .= "<table class=\"table-borderless table-condensed small mx-auto\">";$modal .= "<tr><td class=\"px-1\">Title:</td><td class=\"px-1\">" . (string)$item->ItemInfo->Title->DisplayValue . "</td></tr>";$modal .= "<tr><td class=\"px-1\">Artist:</td><td class=\"px-1\">" . join(", ", $artists) . "</td></tr>";if (!empty($contributers)) {$modal .= "<tr><td class=\"px-1\">Creator:</td><td class=\"px-1\">" . join(", ", $contributers) . "</td></tr>";}if (!empty($actors)) {$modal .= "<tr><td class=\"px-1\">Actor:</td><td class=\"px-1\">" . join(", ", $actors) . "</td></tr>";}if (!empty($directors)) {$modal .= "<tr><td class=\"px-1\">Director:</td><td class=\"px-1\">" . join(", ", $directors) . "</td></tr>";}if (!empty($authors)) {$modal .= "<tr><td class=\"px-1\">Author:</td><td class=\"px-1\">" . join(", ", $authors) . "</td></tr>";}if (!empty($item->ItemInfo->Classifications->Binding)) {$modal .= "<tr><td class=\"px-1\">Type:</td><td class=\"px-1\">" . (string)$item->ItemInfo->Classifications->Binding->DisplayValue . "</td></tr>";}if (!empty($item->ItemInfo->MediaType)) { //$modal .= "<tr><td class=\"px-1\">Media Type:</td><td class=\"px-1\">" . (string)$item->ItemInfo->MediaType . "</td></tr>";}if (!empty($barcode)) {$modal .= "<tr><td class=\"px-1\">Barcode:</td><td class=\"px-1\">" . displayBarcode($barcode) . "</td></tr>";}if (!empty($label)) {$modal .= "<tr><td class=\"px-1\">Label:</td><td class=\"px-1\">" . $label . "</td></tr>";}if (!empty($languages)) {$modal .= "<tr><td class=\"px-1\">Languages:</td><td class=\"px-1\">" . join(", ", $languages) . "</td></tr>";}if (!empty($item->ItemInfo->ContentInfo->PublicationDate)) {$modal .= "<tr><td class=\"px-1\">Publication Date:</td><td class=\"px-1\">" . (string)$item->ItemInfo->ContentInfo->PublicationDate->DisplayValue . "</td></tr>";}if (!empty($item->ItemInfo->ContentInfo->ReleaseDate)) {$modal .= "<tr><td class=\"px-1\">Release Date:</td><td class=\"px-1\">" . (string)$item->ItemInfo->ContentInfo->ReleaseDate->DisplayValue . "</td></tr>";}if (!empty($genres)) {$modal .= "<tr><td class=\"px-1\">Genre:</td><td class=\"px-1\">" . join(", ", $genres) . "</td></tr>";}if (!empty($item->ItemInfo->ContentInfo->UnitCount->DisplayValue)) {$modal .= "<tr><td class=\"px-1\">Number of Discs:</td><td class=\"px-1\">" . (string)$item->ItemInfo->ContentInfo->UnitCount->DisplayValue . "</td></tr>";}if (!empty($item->ItemInfo->ContentInfo->PagesCount->DisplayValue)) {$modal .= "<tr><td class=\"px-1\">Number of Pages:</td><td class=\"px-1\">" . (string)$item->ItemInfo->ContentInfo->PagesCount->DisplayValue . "</td></tr>";}if (!empty($item->ItemInfo->RunningTime)) {$modal .= "<tr><td class=\"px-1\">Running Time:</td><td class=\"px-1\">" . $runningTime . "</td></tr>";}if (!empty($item->ItemInfo->Edition)) {$modal .= "<tr><td class=\"px-1\">Edition:</td><td class=\"px-1\">" . (string)$item->ItemInfo->Edition . "</td></tr>";}if (!empty($item->Tracks)) {$modal .= "<tr><td colspan=\"2\" class=\"px-1\">Tracks:</td></tr>";$modal .= "<tr><td colspan=\"2\">";$modal .= "<ul class=\"pl-3 pt-0 small list-unstyled\">";foreach ($item->Tracks->Disc as $disc) {if ((int)$item->ItemInfo->ContentInfo->UnitCount->DisplayValue > 1 && !empty($disc->attributes())) {$modal .= "<li class=\"font-weight-bold\">Disc " . $disc->attributes() . ":</li>";}foreach($disc->Track as $track) {$modal .= "<li>" . (!empty($track->attributes()) ? $track->attributes() . ") " : "") . $track . "</li>";}}$modal .= "</ul>";$modal .= "</td></tr>";}$modal .= "</table>";$modal .= "</div>";$modal .= "<div class=\"modal-footer bg-white justify-content-between\">";$modal .= "<span class=\"float-right\"><button type=\"button\" class=\"btn btn-danger\" data-dismiss=\"modal\">Close</button></span>";$modal .= "</div>";$modal .= "</div>";$modal .= "</div>";$modal .= "</div>";$str .= $modal;$str .= "</div>";return $str;}function getArtists($item) {$artists = [];if (!empty($item->ItemInfo->Artist)){$artists[] = $item->ItemInfo->Artist;} else if (!empty($item->ItemInfo->ByLineInfo->Contributors)) {foreach ($item->ItemInfo->ByLineInfo->Contributors as $artist) {if ((string)$artist->Role == "Artist") {$artists[] = $artist->Name;}}}return $artists;}function getContributers($item) {$contributers = [];if (!empty($item->ItemInfo->ByLineInfo->Contributors)) {foreach ($item->ItemInfo->ByLineInfo->Contributors as $creator) {if ((string)$creator->Role == "Primary Contributor") {$contributers[] = $creator->Name;}else {$contributers[] = $creator->Name . " (" . $creator->Role . ")";}}}return $contributers;}class AwsV4 {private $accessKey = null;private $secretKey = null;private $path = null;private $regionName = null;private $serviceName = null;private $httpMethodName = null;private $queryParametes = array();private $awsHeaders = array();private $payload = "";private $HMACAlgorithm = "AWS4-HMAC-SHA256";private $aws4Request = "aws4_request";private $strSignedHeader = null;private $xAmzDate = null;private $currentDate = null;public function __construct($accessKey, $secretKey) {$this->accessKey = $accessKey;$this->secretKey = $secretKey;$this->xAmzDate = $this->getTimeStamp();$this->currentDate = $this->getDate();}function setPath($path) {$this->path = $path;}function setServiceName($serviceName) {$this->serviceName = $serviceName;}function setRegionName($regionName) {$this->regionName = $regionName;}function setPayload($payload) {$this->payload = $payload;}function setRequestMethod($method) {$this->httpMethodName = $method;}function addHeader($headerName, $headerValue) {$this->awsHeaders[$headerName] = $headerValue;}private function prepareCanonicalRequest() {$canonicalURL = "";$canonicalURL .= $this->httpMethodName . "\n";$canonicalURL .= $this->path . "\n" . "\n";$signedHeaders = '';foreach ($this->awsHeaders as $key => $value) {$signedHeaders .= $key . ";";$canonicalURL .= $key . ":" . $value . "\n";}$canonicalURL .= "\n";$this->strSignedHeader = substr($signedHeaders, 0, -1);$canonicalURL .= $this->strSignedHeader . "\n";$canonicalURL .= $this->generateHex($this->payload);return $canonicalURL;}private function prepareStringToSign($canonicalURL) {$stringToSign = '';$stringToSign .= $this->HMACAlgorithm . "\n";$stringToSign .= $this->xAmzDate . "\n";$stringToSign .= $this->currentDate . "/" . $this->regionName . "/" . $this->serviceName . "/" . $this->aws4Request . "\n";$stringToSign .= $this->generateHex($canonicalURL);return $stringToSign;}private function calculateSignature($stringToSign) {$signatureKey = $this->getSignatureKey($this->secretKey, $this->currentDate, $this->regionName, $this->serviceName);$signature = hash_hmac("sha256", $stringToSign, $signatureKey, true);$strHexSignature = strtolower(bin2hex($signature));return $strHexSignature;}public function getHeaders() {$this->awsHeaders['x-amz-date'] = $this->xAmzDate;ksort($this->awsHeaders);// Step 1: CREATE A CANONICAL REQUEST$canonicalURL = $this->prepareCanonicalRequest();// Step 2: CREATE THE STRING TO SIGN$stringToSign = $this->prepareStringToSign($canonicalURL);// Step 3: CALCULATE THE SIGNATURE$signature = $this->calculateSignature($stringToSign);// Step 4: CALCULATE AUTHORIZATION HEADERif ($signature) {$this->awsHeaders['Authorization'] = $this->buildAuthorizationString($signature);return $this->awsHeaders;}}private function buildAuthorizationString($strSignature) {return $this->HMACAlgorithm . " " . "Credential=" . $this->accessKey . "/" . $this->getDate() . "/" . $this->regionName . "/" . $this->serviceName . "/" . $this->aws4Request . "," . "SignedHeaders=" . $this->strSignedHeader . "," . "Signature=" . $strSignature;}private function generateHex($data) {return strtolower(bin2hex(hash("sha256", $data, true)));}private function getSignatureKey($key, $date, $regionName, $serviceName) {$kSecret = "AWS4" . $key;$kDate = hash_hmac("sha256", $date, $kSecret, true);$kRegion = hash_hmac("sha256", $regionName, $kDate, true);$kService = hash_hmac("sha256", $serviceName, $kRegion, true);$kSigning = hash_hmac("sha256", $this->aws4Request, $kService, true);return $kSigning;}private function getTimeStamp() {return gmdate("Ymd\THis\Z");}private function getDate() {return gmdate("Ymd");}}