Rev 120 | Rev 122 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php
include_once ('php/constants.php');
error_reporting(E_ALL);
// Get itunes listings
function 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 Music
if ($_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 listings
function 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;
$wlAddArr = [];
$wlSearchArr = [];
// If the response was loaded, parse it and store in array
foreach ($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, $wlAddArr, $wlSearchArr);
}
$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"] .= '<script nonce="xxxNONCExxx">';
$_SESSION["discogs"] .= 'function addDiscogsEventsWait() {';
$_SESSION["discogs"] .= 'document.addEventListener("DOMContentLoaded", function() {';
$_SESSION["discogs"] .= ' addDiscogsEvents();';
$_SESSION["discogs"] .= '});';
$_SESSION["discogs"] .= '}';
$_SESSION["discogs"] .= 'function addDiscogsEvents() {';
foreach($wlAddArr as $k=>$v) {
$_SESSION["discogs"] .= 'el = document.getElementById("' . $k . '");';
$_SESSION["discogs"] .= 'if (el) document.getElementById("' . $k . '").addEventListener("click", function() {';
$_SESSION["discogs"] .= $v;
$_SESSION["discogs"] .= ' });';
}
foreach($wlSearchArr as $k=>$v) {
$_SESSION["discogs"] .= 'el = document.getElementById("' . $k . '");';
$_SESSION["discogs"] .= 'if (el) document.getElementById("' . $k . '").addEventListener("click", function() {';
$_SESSION["discogs"] .= $v;
$_SESSION["discogs"] .= ' });';
}
$_SESSION["discogs"] .= '}';
$_SESSION["discogs"] .= 'addDiscogsEventsWait();';
$_SESSION["discogs"] .= '</script>';
$_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, &$wlAddArr, &$wlSearchArr) {
$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\">";
$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 h-100\">";
$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 btn-sm\" data-toggle=\"modal\" data-target=\"#masterModal" . $cnt . "\" title=\"Album Information\" data-toggle2=\"tooltip\"><i class=\"material-icons material-text\">info_outline</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 id=\"wl" . $cnt . "Btn\" type=\"button\" class=\"btn btn-primary btn-sm\" title=\"Add to Wishlist\" data-toggle=\"tooltip\"><i class=\"material-icons\">bookmark</i></button>";
$wlAddArr["wl" . $cnt . "Btn"] = 'addWishlist("' . $_SESSION['sessData']['userID'] . '", this,' . $cnt . ',"' . $wl . '");';
}
$searchTitle = 'Searching for:<br><br><strong>' . (string)$item->ItemInfo->Title->DisplayValue . ' by ' . $wlArtists . '</strong>';
if (!empty($barcode)) {
$searchTitle .= " (" . displayBarcode($barcode) . ")";
}
$str .= " <button id=\"discogsSearch" . $cnt . "Btn\" type=\"submit\" name=\"submit\" value=\"discogsSearch\" class=\"btn btn-primary btn-sm\" title=\"Search for Store Offers\" data-toggle=\"tooltip\"><i class=\"material-icons\">search</i></button>";
$str .= "</span>";
$str .= "</div>";
$wlSearchArr["discogsSearch" . $cnt . "Btn"] = 'document.getElementById("discogsTitle").value = "' . addslashes((string)$item->ItemInfo->Title->DisplayValue) . '";' .
'document.getElementById("discogsArtist").value = "' . addslashes($searchArtists) . '";' .
'document.getElementById("discogsBarcode").value = "' . $barcode . '";' .
'progressBar("' . $searchTitle . '");';
$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=\"material-icons btn-dismiss\">cancel_presentation</i></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 HEADER
if ($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");
}
}