Subversion Repositories cheapmusic

Rev

Rev 124 | Rev 127 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
81 - 1
<?php
2
include_once ('php/constants.php');
3
 
4
error_reporting(E_ALL);
5
 
6
// Get itunes listings
7
function get_amazon($query, $searchCondition) {
8
    $vendors = Vendors::getInstance();
9
    $config = $vendors->getVendor(Vendors::AMAZON);
10
 
11
    $needMatches = empty($_SESSION["discogs"]);
12
    $arrMusic = [];
13
    $arrDigital = [];
82 - 14
    $arrBooks = [];
81 - 15
 
16
    // Music
17
    $arrMusic = get_amazonCategory($config, $query, "Music", $needMatches);
18
 
19
    // Digital Music
20
    if ($_SESSION["filterMediaType"]["Digital"]) {
99 - 21
        $arrDigital = get_amazonCategory($config, $query, "DigitalMusic");
81 - 22
    }
23
 
24
    if ($_SESSION["filterMediaType"]["Book"]) {
25
        // Books
26
        $arrBooks = get_amazonCategory($config, $query, "Books");
27
    }
28
 
29
    return (array_merge($arrMusic, $arrDigital, $arrBooks));
30
}
31
 
32
// Get Amazon listings
33
function get_amazonCategory($config, $query, $searchIndex, $needMatches = false) {
94 - 34
    $numResults = $config['numResults'];
81 - 35
 
36
    if ($needMatches) {
37
        $_SESSION["discogs"] = "";
38
    }
39
 
99 - 40
    $response = getSearchCache("amazon", $query, $searchIndex);
41
    if ($response === false) {
42
        $serviceName = "ProductAdvertisingAPI";
43
        $region = "us-east-1";
44
        $accessKey = $config["access_key_id"];
45
        $secretKey = $config["secret_key"];
46
        $associate_tag = $config['associate_tag'];
47
$payload="{"
48
        ." \"Keywords\": \"$query\","
49
        ." \"Resources\": ["
50
        ."  \"Images.Primary.Medium\","
51
        ."  \"Images.Primary.Large\","
52
        ."  \"ItemInfo.ByLineInfo\","
53
        ."  \"ItemInfo.ContentInfo\","
54
        ."  \"ItemInfo.Classifications\","
55
        ."  \"ItemInfo.ExternalIds\","
56
        ."  \"ItemInfo.ManufactureInfo\","
57
        ."  \"ItemInfo.ProductInfo\","
58
        ."  \"ItemInfo.TechnicalInfo\","
59
        ."  \"ItemInfo.Title\","
60
        ."  \"Offers.Listings.Condition\","
61
        ."  \"Offers.Listings.Condition.SubCondition\","
62
        ."  \"Offers.Listings.DeliveryInfo.IsAmazonFulfilled\","
63
        ."  \"Offers.Listings.DeliveryInfo.IsFreeShippingEligible\","
64
        ."  \"Offers.Listings.DeliveryInfo.IsPrimeEligible\","
65
        ."  \"Offers.Listings.DeliveryInfo.ShippingCharges\","
66
        ."  \"Offers.Listings.MerchantInfo\","
67
        ."  \"Offers.Listings.Price\""
68
        ." ],"
69
        ." \"SearchIndex\": \"$searchIndex\","
70
        ." \"Availability\": \"Available\","
71
        ." \"Condition\": \"Any\","
72
        ." \"OfferCount\": 3,"
73
        ." \"SortBy\": \"Price:LowToHigh\","
74
        ." \"PartnerTag\": \"$associate_tag\","
75
        ." \"PartnerType\": \"Associates\","
76
        ." \"Marketplace\": \"www.amazon.com\""
77
        ."}";
78
        $host = "webservices.amazon.com";
79
        $uriPath = "/paapi5/searchitems";
81 - 80
 
99 - 81
        $awsv4 = new AwsV4($accessKey, $secretKey);
82
        $awsv4->setRegionName($region);
83
        $awsv4->setServiceName($serviceName);
84
        $awsv4->setPath($uriPath);
85
        $awsv4->setPayload($payload);
86
        $awsv4->setRequestMethod("POST");
87
        $awsv4->addHeader('content-encoding', 'amz-1.0');
88
        $awsv4->addHeader('content-type', 'application/json; charset=utf-8');
89
        $awsv4->addHeader('host', $host);
90
        $awsv4->addHeader('x-amz-target', 'com.amazon.paapi5.v1.ProductAdvertisingAPIv1.SearchItems');
91
        $headers = $awsv4->getHeaders();
92
        $headerArr = [];
93
        foreach ($headers as $key => $value) {
94
            $headerArr[] = $key . ': ' . $value;
95
        }
81 - 96
 
99 - 97
        $ch = curl_init();
98
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArr);
99
        curl_setopt($ch, CURLOPT_URL, 'https://' . $host . $uriPath);
100
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
101
        curl_setopt($ch, CURLOPT_TIMEOUT, 15);
102
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
103
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
104
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
105
        curl_setopt($ch, CURLOPT_REFERER, 'https://' . $host . $uriPath);
106
        curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
107
        curl_setopt($ch, CURLOPT_POST, 1);
108
        $response = curl_exec($ch);
109
        curl_close($ch);
81 - 110
 
99 - 111
        saveSearchCache("amazon", $query, $searchIndex, $response);
81 - 112
    }
113
 
99 - 114
    $parsed_json = json_decode($response);
115
//echo "<br><pre>";print_r($parsed_json);echo "</pre>";
116
    $arr = [];
81 - 117
 
99 - 118
    if (isset($parsed_json->Errors)) {
119
        foreach ($parsed_json->Errors as $error) {
120
            if ($error->Code != "NoResults") {
121
                my_error_log("Amazon Search - " . $error->Message . " (" . $error->Code . ")");
122
            }
123
        }
124
        return [];
106 - 125
    } else if (!isset($parsed_json->SearchResult)) {
126
        my_error_log("Amazon Search - No Search Result.");
127
        return [];
99 - 128
    }
81 - 129
 
99 - 130
    if ($needMatches) {
131
        $cnt = 0;
132
        $_SESSION["discogs"] = startMatches();
133
    }
81 - 134
 
99 - 135
    $listings = 0;
120 - 136
    $wlAddArr = [];
137
    $wlSearchArr = [];
99 - 138
    // If the response was loaded, parse it and store in array
139
    foreach ($parsed_json->SearchResult->Items as $current) {
140
        if (isset($current->ItemInfo->ExternalIds->UPCs)) {
141
            $barcode = (string)$current->ItemInfo->ExternalIds->UPCs->DisplayValues[0];
142
        }
143
        else if (isset($current->ItemInfo->ExternalIds->EANs)) {
144
            $barcode = (string)$current->ItemInfo->ExternalIds->EANs->DisplayValues[0];
145
        }
146
        else if (isset($current->ItemInfo->ExternalIds->ISBNs)) {
147
            $barcode = (string)$current->ItemInfo->ExternalIds->ISBNs->DisplayValues[0];
148
        }
149
        else if (isset($current->ItemInfo->ExternalIds->EISBNs)) {
150
            $barcode = (string)$current->ItemInfo->ExternalIds->EISBNs->DisplayValues[0];
151
        }
152
        else {
153
            $barcode = "";
154
        }
155
        $barcodeType = clsLibGTIN::GTINCheck($barcode, false, 1);
81 - 156
 
102 - 157
        $pic = !empty($current->Images->Primary->Medium->URL) ? (string)$current->Images->Primary->Medium->URL : "images/no-image-available.jpg";
100 - 158
        $pic = str_replace('http://', 'https://', $pic);
99 - 159
        if (empty($pic)) {
160
            continue;
161
        }
81 - 162
 
99 - 163
        if (strpos($current->ItemInfo->Classifications->Binding->DisplayValue, "Audio CD") !== false) {
164
            $mediaType = "CD";
165
        }
166
        else if (strpos($current->ItemInfo->Classifications->Binding->DisplayValue, "MP3 Music") !== false) {
167
            $mediaType = "Digital";
168
        }
169
        else if (strpos($current->ItemInfo->Classifications->Binding->DisplayValue, "Vinyl") !== false) {
170
            $mediaType = "Record";
171
        }
172
        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) {
173
            $mediaType = "Book";
174
        }
175
        else {
176
            continue;
177
        }
81 - 178
 
179
        if ($needMatches) {
99 - 180
            // bugbug: check maxMasterCnt?
120 - 181
            $_SESSION["discogs"] .= addMatch($current, ++$cnt, $mediaType, $wlAddArr, $wlSearchArr);
81 - 182
        }
183
 
99 - 184
        $title = (string)$current->ItemInfo->Title->DisplayValue;
185
        $artists = getArtists($current);
186
        $contributers = getContributers($current);
187
        if (!empty($artists)) {
188
            $title .= " by " . join(", ", $artists);
189
        }
190
        else if (!empty($contributers)) {
191
            $title .= " by " . join(", ", $contributers);
192
        }
81 - 193
 
99 - 194
        $url = str_replace('http://', 'https://', (string)$current->DetailPageURL);
81 - 195
 
99 - 196
        if (empty($url)) {
197
            continue;
198
        }
81 - 199
 
99 - 200
        $bestOffer = false;
81 - 201
 
99 - 202
        $url = str_replace('http://', 'https://', (string)$current->DetailPageURL);
203
        $url .= "&condition=";
81 - 204
 
99 - 205
        if (!empty($current->Offers->Listings)) {
206
            foreach ($current->Offers->Listings as $offer) {
207
                $country = 'US';
208
                if (isset($offer->MerchantInfo->DefaultShippingCountry)) {
209
                    $country = $offer->MerchantInfo->DefaultShippingCountry;
210
                }
211
                $merchantName = "Amazon";
212
                if (strpos($offer->MerchantInfo->Name, "Amazon") === false) {
213
                    $merchantName .= " Marketplace";
214
                }
81 - 215
 
99 - 216
                $condition = (string)$offer->Condition->Value;
217
                $url .= $condition;
218
                $detailCondition = $condition;
219
                if ($condition == "Collectible") {
220
                    $condition = 'Used';
221
                    $detailCondition = "Collectible";
222
                }
223
                if ($condition == "Refurbished") {
224
                    $condition = 'Used';
225
                    $detailCondition = "Refurbished";
226
                }
227
                $currency = (string)$offer->Price->Currency;
228
                $price = number_format(floatval($offer->Price->Amount) , 2, '.', '');
81 - 229
 
99 - 230
                if ($price <= "0.00") {
231
                    continue;
232
                }
81 - 233
 
99 - 234
                $timeLeft = 0;
235
                $listingType = 'Fixed';
236
                $location = 'US';
237
                $zip = '';
238
                $feedbackScore = - 1;
239
                $feedbackPercent = - 1;
240
                $sellerName = "";
241
                $handlingTime = 0;
242
                if ($offer->DeliveryInfo->IsPrimeEligible === true) {
243
                    $sellerName = "Prime";
81 - 244
                }
99 - 245
                if ($mediaType == "Digital") {
246
                    $shippingCost = 0.00;
247
                    $shippingEstimated = false;
248
                    $shippingCurrency = 'USD';
249
                }
250
                else {
251
                    $shippingCost = 3.99; // bugbug
252
                    $shippingEstimated = true; // bugbug
253
                    $shippingCurrency = 'USD';
254
                }
255
                $freeShippingCap = !empty($offer->DeliveryInfo->IsFreeShippingEligible) ? 25 : 0;
81 - 256
 
99 - 257
                if (++$listings > $numResults) {
258
                    continue;
259
                }
81 - 260
 
99 - 261
                $arr[] = array(
262
                    "Merchant" => $merchantName,
263
                    "Condition" => $condition,
264
                    "Title" => $title,
265
                    "Barcode" => $barcode,
266
                    "BarcodeType" => $barcodeType,
267
                    "Image" => $pic,
268
                    "URL" => $url,
269
                    "MediaType" => $mediaType,
270
                    "DetailCondition" => $detailCondition,
271
                    "Country" => $country,
272
                    "BestOffer" => $bestOffer,
273
                    "TimeLeft" => $timeLeft,
274
                    "Price" => $price,
275
                    "Currency" => $currency,
276
                    "ListingType" => $listingType,
277
                    "Location" => $location,
278
                    "Zip" => $zip,
279
                    "FeedbackScore" => $feedbackScore,
280
                    "FeedbackPercent" => $feedbackPercent,
281
                    "SellerName" => $sellerName,
282
                    "HandlingTime" => $handlingTime,
283
                    "ShippingCost" => $shippingCost,
284
                    "ShippingEstimated" => $shippingEstimated,
285
                    "ShippingCurrency" => $shippingCurrency,
286
                    "FreeShippingCap" => $freeShippingCap,
287
                    "Show" => true
288
                );
81 - 289
            }
290
        }
99 - 291
    }
81 - 292
 
99 - 293
    if ($needMatches) {
294
        if ($cnt = 0) {
295
            $_SESSION["discogs"] = "";
81 - 296
        }
99 - 297
        else {
121 - 298
            $_SESSION["discogs"] .= '<script nonce="xxxNONCExxx">';
120 - 299
            $_SESSION["discogs"] .= 'function addDiscogsEventsWait() {';
300
            $_SESSION["discogs"] .= 'document.addEventListener("DOMContentLoaded", function() {';
301
            $_SESSION["discogs"] .= '	addDiscogsEvents();';
302
            $_SESSION["discogs"] .= '});';
303
            $_SESSION["discogs"] .= '}';
304
 
305
            $_SESSION["discogs"] .= 'function addDiscogsEvents() {';
306
            foreach($wlAddArr as $k=>$v) {
307
                $_SESSION["discogs"] .= 'el = document.getElementById("' . $k . '");';
308
                $_SESSION["discogs"] .= 'if (el) document.getElementById("' . $k . '").addEventListener("click", function() {';
309
                $_SESSION["discogs"] .= $v;
310
                $_SESSION["discogs"] .= '	});';
311
            }
312
 
313
            foreach($wlSearchArr as $k=>$v) {
314
                $_SESSION["discogs"] .= 'el = document.getElementById("' . $k . '");';
315
                $_SESSION["discogs"] .= 'if (el) document.getElementById("' . $k . '").addEventListener("click", function() {';
316
                $_SESSION["discogs"] .= $v;
317
                $_SESSION["discogs"] .= '	});';
318
            }
319
            $_SESSION["discogs"] .= '}';
320
            $_SESSION["discogs"] .= 'addDiscogsEventsWait();';
321
            $_SESSION["discogs"] .= '</script>';
322
 
99 - 323
            $_SESSION["discogs"] .= endMatches();
324
        }
81 - 325
    }
99 - 326
 
81 - 327
    // If the response does not indicate 'Success,' log the error(s)
99 - 328
    /******************
81 - 329
    else {
96 - 330
        my_error_log($url);
99 - 331
        if (!empty($parsed_json->OperationRequest->Errors)) {
332
            foreach($parsed_json->OperationRequest->Errors->Error as $error){
96 - 333
                my_error_log($error->Message . " (" . $error->Code . ")");
81 - 334
            }
99 - 335
        } else if (!empty($parsed_json->Errors)) {
336
            foreach($parsed_json->OperationRequest->Errors->Error as $error){
96 - 337
                my_error_log($error->Message . " (" . $error->Code . ")");
81 - 338
            }
99 - 339
        } else if (!empty($parsed_json->Error)) {
340
            my_error_log($parsed_json->Error->Message . " (" . $parsed_json->Error->Code . ")");
81 - 341
        } else {
96 - 342
            my_error_log(print_r($result, 1));
81 - 343
        }
344
    }
99 - 345
    ******************/
81 - 346
 
347
    return $arr;
348
}
349
 
350
function startMatches() {
124 - 351
    $str = "<div class=\"container-fluid bg-light\">";
352
    $str .= htmlHeader(2, "Matching Albums", "text-center py-2");
81 - 353
    $str .= "<form method=\"post\" action=\"/index.php\">";
116 - 354
    $str .= "<input type=\"hidden\" name=\"sessionTab\" value=\"" . MySessionHandler::getSessionTab() . "\" />";
122 - 355
    $str .= "<input type=\"hidden\" name=\"nonce\" value=\"" . $_SESSION["nonce"] . "\" />";
116 - 356
    $str .= "<input id=\"discogsTitle\" type=\"hidden\" name=\"discogsTitle\" value=\"\" />";
357
    $str .= "<input id=\"discogsArtist\" type=\"hidden\" name=\"discogsArtist\" value=\"\" />";
358
    $str .= "<input id=\"discogsBarcode\" type=\"hidden\" name=\"discogsBarcode\" value=\"\" />";
81 - 359
    $str .= "<div id=\"discogsDeck\" class=\"card-deck\">";
360
 
361
    return $str;
362
}
363
 
364
function endMatches() {
365
    $str = "</div>";
366
    $str .= "</form>";
367
    $str .= "</div>";
368
 
369
    return $str;
370
}
371
 
120 - 372
function addMatch($item, $cnt, $mediaType, &$wlAddArr, &$wlSearchArr) {
81 - 373
    $artists = getArtists($item);
374
 
99 - 375
    $contributers = getContributers($item);
81 - 376
 
99 - 377
    $label = "";
378
    if (!empty($item->ItemInfo->ByLineInfo->Manufacturer)) {
100 - 379
        $label = $item->ItemInfo->ByLineInfo->Manufacturer->DisplayValue;
81 - 380
    }
381
 
382
    $languages = [];
99 - 383
    if (!empty($item->ItemInfo->ContentInfo->Languages)) {
384
        foreach ($item->ItemInfo->ContentInfo->Languages->DisplayValues as $language) {
81 - 385
            if ((string)$language->Type != "Unknown") {
99 - 386
                $languages[] = $language->DisplayValue . " (" . $language->Type . ")";
81 - 387
            }
388
        }
389
    }
390
 
101 - 391
    $genres = [];
392
    if (!empty($item->ItemInfo->Genre)) {
393
        foreach($item->ItemInfo->Genre as $genre) {
394
            $genres[] = join(" ", array_map('ucfirst', explode('-', $genre)));
395
        }
396
    }
397
 
398
    $runningTime = "";
399
    if (!empty($item->ItemInfo->RunningTime)) {
400
        if ($mediaType != 'Digital') {
401
            $runningTime = (string)$item->ItemInfo->RunningTime . " minutes";
402
        } else {
403
            $runningTime = gmdate("H:i:s", (int)$item->ItemInfo->RunningTime);
404
        }
405
    }
406
 
81 - 407
    $modal = "";
408
    $str = "<div class=\"card mx-auto discogs-card\">";
124 - 409
    $str .= "<div class=\"card-header bg-secondary d-flex\">";
125 - 410
    $str .= "<p class=\"card-title font-weight-bold small flex-grow-1\">" . htmlentities((string)$item->ItemInfo->Title->DisplayValue);
81 - 411
    $searchArtists = "";
105 - 412
    $wlArtists = "";
99 - 413
    if (!empty($artists)) {
414
        if (count($artists) < 5) {
415
            $wlArtists = join(", ", $artists);
416
            if (!empty($artists) && $artists[0] != 'Various') {
417
                $searchArtists = join(" ", $artists);
418
            }
419
        } else {
420
            $wlArtists = "Various Artists";
81 - 421
        }
422
    }
99 - 423
    else if (!empty($contributers)) {
424
        if (count($contributers) < 5) {
425
            $wlArtists = join(", ", $contributers);
426
            if (!empty($contributers) && $contributers[0] != 'Various') {
427
                $searchArtists = join(" ", $contributers);
428
            }
429
        } else {
430
            $wlArtists = "Various Artists";
431
        }
81 - 432
    }
124 - 433
    if (!empty($wlArtists)) {
125 - 434
        $str .= " by " . htmlentities($wlArtists);
124 - 435
    }
81 - 436
    $str .= "</p>";
437
    $str .= "</div>";
438
 
99 - 439
    $thumbnail = !empty($item->Images->Primary->Medium->URL) ? (string)$item->Images->Primary->Medium->URL : "images/no-image-available.jpg";
81 - 440
 
124 - 441
    $str .= "<div class=\"card-body d-flex justify-content-center align-items-center p-1 m-0\">";
442
    $str .= "<img class=\"btn 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\" />";
81 - 443
    $str .= "</div>";
124 - 444
    $str .= "<div class=\"card-footer bg-secondary p-0 m-0\">";
81 - 445
    $str .= "<div class=\"container clearfix p-0 m-0\">";
124 - 446
    $str .= "<span class=\"float-left btn-group-sm\">";
447
    $str .= "<button type=\"button\" class=\"btn btn-info btn-sm\" data-toggle=\"modal\" data-target=\"#masterModal" . $cnt . "\" title=\"Album Information\" data-toggle2=\"tooltip\"><i class=\"material-icons\">info_outline</i></button>";
81 - 448
 
449
    $str .= "</span>";
450
 
124 - 451
    $str .= "<span class=\"float-right btn-group-sm\">";
81 - 452
 
453
    $barcode = "";
454
    $tmpBarcode = "";
99 - 455
    if (isset($item->ItemInfo->ExternalIds->UPCs)) {
456
        $tmpBarcode = (string)$item->ItemInfo->ExternalIds->UPCs->DisplayValues[0];
81 - 457
    }
99 - 458
    else if (isset($item->ItemInfo->ExternalIds->EANs)) {
459
        $tmpBarcode = (string)$item->ItemInfo->ExternalIds->EANs->DisplayValues[0];
460
    }
461
    else if (isset($item->ItemInfo->ExternalIds->ISBNs)) {
462
        $tmpBarcode = (string)$item->ItemInfo->ExternalIds->ISBNs->DisplayValues[0];
463
    }
464
    else if (isset($item->ItemInfo->ExternalIds->EISBNs)) {
465
        $tmpBarcode = (string)$item->ItemInfo->ExternalIds->EISBNs->DisplayValues[0];
466
    }
81 - 467
    $barcodeType = clsLibGTIN::GTINCheck($tmpBarcode, false, 1);
468
    if (!empty($barcodeType)) {
469
        $barcode = $tmpBarcode;
470
    }
471
 
472
    if (isLoggedIn() && !checkWishlist('asin', $item->ASIN)) {
473
        $wlArr = array(
474
            'asin' => (string)$item->ASIN,
99 - 475
            'title' => (string)$item->ItemInfo->Title->DisplayValue,
81 - 476
            'artist' => $wlArtists,
477
            'barcode' => $barcode,
478
            'thumbnail' => $thumbnail,
479
            'url' => (string)$item->DetailPageURL
480
        );
481
        $wl = base64_encode(json_encode($wlArr));
124 - 482
        $str .= "<button id=\"wl" . $cnt . "Btn\" type=\"button\" class=\"btn btn-info btn-sm\" title=\"Add to Wishlist\" data-toggle=\"tooltip\"><i class=\"material-icons\">bookmark</i></button>";
120 - 483
        $wlAddArr["wl" . $cnt . "Btn"] = 'addWishlist("' . $_SESSION['sessData']['userID'] . '", this,' . $cnt . ',"' . $wl . '");';
81 - 484
    }
485
 
125 - 486
    $searchTitle = 'Searching for:<br><br><strong>' . htmlentities((string)$item->ItemInfo->Title->DisplayValue) . ' by ' . htmlentities($wlArtists) . '</strong>';
81 - 487
    if (!empty($barcode)) {
488
        $searchTitle .= " (" . displayBarcode($barcode) . ")";
489
    }
490
 
124 - 491
    $str .= " ";
492
    $str .= "<button id=\"discogsSearch" . $cnt . "Btn\" type=\"submit\" name=\"submit\" value=\"discogsSearch\" class=\"btn btn-success btn-sm\" title=\"Search for Store Offers\" data-toggle=\"tooltip\"><i class=\"material-icons\">search</i></button>";
81 - 493
    $str .= "</span>";
494
    $str .= "</div>";
120 - 495
 
496
    $wlSearchArr["discogsSearch" . $cnt . "Btn"] = 'document.getElementById("discogsTitle").value = "' . addslashes((string)$item->ItemInfo->Title->DisplayValue) . '";' .
497
                                                   'document.getElementById("discogsArtist").value = "' . addslashes($searchArtists) . '";' .
498
                                                   'document.getElementById("discogsBarcode").value = "' . $barcode . '";' .
499
                                                   'progressBar("' . $searchTitle . '");';
500
 
81 - 501
    $str .= "<span id=\"wishlistAdd" . $cnt . "\"></span>";
502
    $str .= "</div>";
503
 
504
    $modal .= "<div id=\"masterModal" . $cnt . "\" class=\"modal\">";
505
    $modal .= "<div class=\"modal-dialog\">";
506
    $modal .= "<div class=\"modal-content\">";
124 - 507
    $modal .= "<div class=\"modal-header bg-secondary\">";
125 - 508
    $modal .= "<h4 class=\"modal-title mx-auto\">" . htmlentities((string)$item->ItemInfo->Title->DisplayValue) . " by " . htmlentities($wlArtists) . "</h4>";
120 - 509
    $modal .= "<button type=\"button\" class=\"close\" data-dismiss=\"modal\"><i class=\"material-icons btn-dismiss\">cancel_presentation</i></i></button>";
81 - 510
    $modal .= "</div>";
511
 
124 - 512
    $modal .= "<div class=\"modal-body mx-auto\">";
81 - 513
 
99 - 514
    if (!empty($item->Images->Primary->Large->URL)) {
116 - 515
        $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\" />";
81 - 516
    }
517
 
518
    $modal .= "<table class=\"table-borderless table-condensed small mx-auto\">";
125 - 519
    $modal .= "<tr><td class=\"px-1\">Title:</td><td class=\"px-1\">" . htmlentities((string)$item->ItemInfo->Title->DisplayValue) . "</td></tr>";
81 - 520
 
125 - 521
    $modal .= "<tr><td class=\"px-1\">Artist:</td><td class=\"px-1\">" . htmlentities(join(", ", $artists)) . "</td></tr>";
99 - 522
    if (!empty($contributers)) {
125 - 523
        $modal .= "<tr><td class=\"px-1\">Creator:</td><td class=\"px-1\">" . htmlentities(join(", ", $contributers)) . "</td></tr>";
81 - 524
    }
525
 
526
    if (!empty($actors)) {
125 - 527
        $modal .= "<tr><td class=\"px-1\">Actor:</td><td class=\"px-1\">" . htmlentities(join(", ", $actors)) . "</td></tr>";
81 - 528
    }
529
 
530
    if (!empty($directors)) {
125 - 531
        $modal .= "<tr><td class=\"px-1\">Director:</td><td class=\"px-1\">" . htmlentities(join(", ", $directors)) . "</td></tr>";
81 - 532
    }
533
 
534
    if (!empty($authors)) {
125 - 535
        $modal .= "<tr><td class=\"px-1\">Author:</td><td class=\"px-1\">" . htmlentities(join(", ", $authors)) . "</td></tr>";
81 - 536
    }
537
 
99 - 538
    if (!empty($item->ItemInfo->Classifications->Binding)) {
125 - 539
        $modal .= "<tr><td class=\"px-1\">Type:</td><td class=\"px-1\">" . htmlentities((string)$item->ItemInfo->Classifications->Binding->DisplayValue) . "</td></tr>";
81 - 540
    }
541
 
101 - 542
    if (!empty($item->ItemInfo->MediaType)) { //
125 - 543
        $modal .= "<tr><td class=\"px-1\">Media Type:</td><td class=\"px-1\">" . htmlentities((string)$item->ItemInfo->MediaType) . "</td></tr>";
81 - 544
    }
545
 
546
    if (!empty($barcode)) {
547
        $modal .= "<tr><td class=\"px-1\">Barcode:</td><td class=\"px-1\">" . displayBarcode($barcode) . "</td></tr>";
548
    }
549
 
99 - 550
    if (!empty($label)) {
125 - 551
        $modal .= "<tr><td class=\"px-1\">Label:</td><td class=\"px-1\">" . htmlentities($label) . "</td></tr>";
81 - 552
    }
553
 
554
    if (!empty($languages)) {
125 - 555
        $modal .= "<tr><td class=\"px-1\">Languages:</td><td class=\"px-1\">" . htmlentities(join(", ", $languages)) . "</td></tr>";
81 - 556
    }
557
 
99 - 558
    if (!empty($item->ItemInfo->ContentInfo->PublicationDate)) {
125 - 559
        $modal .= "<tr><td class=\"px-1\">Publication Date:</td><td class=\"px-1\">" . htmlentities((string)$item->ItemInfo->ContentInfo->PublicationDate->DisplayValue) . "</td></tr>";
81 - 560
    }
561
 
99 - 562
    if (!empty($item->ItemInfo->ContentInfo->ReleaseDate)) {
125 - 563
        $modal .= "<tr><td class=\"px-1\">Release Date:</td><td class=\"px-1\">" . htmlentities((string)$item->ItemInfo->ContentInfo->ReleaseDate->DisplayValue) . "</td></tr>";
81 - 564
    }
565
 
101 - 566
    if (!empty($genres)) {
125 - 567
        $modal .= "<tr><td class=\"px-1\">Genre:</td><td class=\"px-1\">" . htmlentities(join(", ", $genres)) . "</td></tr>";
101 - 568
    }
569
 
99 - 570
    if (!empty($item->ItemInfo->ContentInfo->UnitCount->DisplayValue)) {
125 - 571
        $modal .= "<tr><td class=\"px-1\">Number of Discs:</td><td class=\"px-1\">" . htmlentities((string)$item->ItemInfo->ContentInfo->UnitCount->DisplayValue) . "</td></tr>";
81 - 572
    }
573
 
99 - 574
    if (!empty($item->ItemInfo->ContentInfo->PagesCount->DisplayValue)) {
125 - 575
        $modal .= "<tr><td class=\"px-1\">Number of Pages:</td><td class=\"px-1\">" . htmlentities((string)$item->ItemInfo->ContentInfo->PagesCount->DisplayValue) . "</td></tr>";
81 - 576
    }
577
 
101 - 578
    if (!empty($item->ItemInfo->RunningTime)) {
125 - 579
        $modal .= "<tr><td class=\"px-1\">Running Time:</td><td class=\"px-1\">" . htmlentities($runningTime) . "</td></tr>";
101 - 580
    }
581
 
582
    if (!empty($item->ItemInfo->Edition)) {
125 - 583
        $modal .= "<tr><td class=\"px-1\">Edition:</td><td class=\"px-1\">" . htmlentities((string)$item->ItemInfo->Edition) . "</td></tr>";
101 - 584
    }
585
 
586
    if (!empty($item->Tracks)) {
587
        $modal .= "<tr><td colspan=\"2\" class=\"px-1\">Tracks:</td></tr>";
588
        $modal .= "<tr><td colspan=\"2\">";
589
        $modal .= "<ul class=\"pl-3 pt-0 small list-unstyled\">";
590
        foreach ($item->Tracks->Disc as $disc) {
591
            if ((int)$item->ItemInfo->ContentInfo->UnitCount->DisplayValue > 1 && !empty($disc->attributes())) {
592
                $modal .= "<li class=\"font-weight-bold\">Disc " . $disc->attributes() . ":</li>";
593
            }
594
 
595
            foreach($disc->Track as $track) {
125 - 596
                $modal .= "<li>" . (!empty($track->attributes()) ? $track->attributes() . ") " : "") . htmlentities($track) . "</li>";
101 - 597
            }
598
        }
599
        $modal .= "</ul>";
600
        $modal .= "</td></tr>";
601
    }
602
 
81 - 603
    $modal .= "</table>";
604
    $modal .= "</div>";
124 - 605
    $modal .= "<div class=\"modal-footer bg-secondary justify-content-between\">";
81 - 606
    $modal .= "<span class=\"float-right\"><button type=\"button\" class=\"btn btn-danger\" data-dismiss=\"modal\">Close</button></span>";
607
    $modal .= "</div>";
608
    $modal .= "</div>";
609
    $modal .= "</div>";
610
    $modal .= "</div>";
611
    $str .= $modal;
612
    $str .= "</div>";
613
 
614
    return $str;
615
}
616
 
617
function getArtists($item) {
618
    $artists = [];
619
 
101 - 620
    if (!empty($item->ItemInfo->Artist)){
621
        $artists[] = $item->ItemInfo->Artist;
622
    } else if (!empty($item->ItemInfo->ByLineInfo->Contributors)) {
99 - 623
        foreach ($item->ItemInfo->ByLineInfo->Contributors as $artist) {
624
            if ((string)$artist->Role == "Artist") {
625
                $artists[] = $artist->Name;
626
            }
81 - 627
        }
628
    }
629
 
630
    return $artists;
631
}
632
 
99 - 633
function getContributers($item) {
634
    $contributers = [];
635
 
636
    if (!empty($item->ItemInfo->ByLineInfo->Contributors)) {
637
        foreach ($item->ItemInfo->ByLineInfo->Contributors as $creator) {
638
            if ((string)$creator->Role == "Primary Contributor") {
639
                $contributers[] = $creator->Name;
81 - 640
            }
99 - 641
            else {
642
                $contributers[] = $creator->Name . " (" . $creator->Role . ")";
643
            }
81 - 644
        }
645
    }
646
 
99 - 647
    return $contributers;
81 - 648
}
99 - 649
 
650
class AwsV4 {
651
 
652
    private $accessKey = null;
653
    private $secretKey = null;
654
    private $path = null;
655
    private $regionName = null;
656
    private $serviceName = null;
657
    private $httpMethodName = null;
658
    private $queryParametes = array();
659
    private $awsHeaders = array();
660
    private $payload = "";
661
 
662
    private $HMACAlgorithm = "AWS4-HMAC-SHA256";
663
    private $aws4Request = "aws4_request";
664
    private $strSignedHeader = null;
665
    private $xAmzDate = null;
666
    private $currentDate = null;
667
 
668
    public function __construct($accessKey, $secretKey) {
669
        $this->accessKey = $accessKey;
670
        $this->secretKey = $secretKey;
671
        $this->xAmzDate = $this->getTimeStamp();
672
        $this->currentDate = $this->getDate();
673
    }
674
 
675
    function setPath($path) {
676
        $this->path = $path;
677
    }
678
 
679
    function setServiceName($serviceName) {
680
        $this->serviceName = $serviceName;
681
    }
682
 
683
    function setRegionName($regionName) {
684
        $this->regionName = $regionName;
685
    }
686
 
687
    function setPayload($payload) {
688
        $this->payload = $payload;
689
    }
690
 
691
    function setRequestMethod($method) {
692
        $this->httpMethodName = $method;
693
    }
694
 
695
    function addHeader($headerName, $headerValue) {
696
        $this->awsHeaders[$headerName] = $headerValue;
697
    }
698
 
699
    private function prepareCanonicalRequest() {
700
        $canonicalURL = "";
701
        $canonicalURL .= $this->httpMethodName . "\n";
702
        $canonicalURL .= $this->path . "\n" . "\n";
703
        $signedHeaders = '';
704
        foreach ($this->awsHeaders as $key => $value) {
705
            $signedHeaders .= $key . ";";
706
            $canonicalURL .= $key . ":" . $value . "\n";
707
        }
708
        $canonicalURL .= "\n";
709
        $this->strSignedHeader = substr($signedHeaders, 0, -1);
710
        $canonicalURL .= $this->strSignedHeader . "\n";
711
        $canonicalURL .= $this->generateHex($this->payload);
712
        return $canonicalURL;
713
    }
714
 
715
    private function prepareStringToSign($canonicalURL) {
716
        $stringToSign = '';
717
        $stringToSign .= $this->HMACAlgorithm . "\n";
718
        $stringToSign .= $this->xAmzDate . "\n";
719
        $stringToSign .= $this->currentDate . "/" . $this->regionName . "/" . $this->serviceName . "/" . $this->aws4Request . "\n";
720
        $stringToSign .= $this->generateHex($canonicalURL);
721
        return $stringToSign;
722
    }
723
 
724
    private function calculateSignature($stringToSign) {
725
        $signatureKey = $this->getSignatureKey($this->secretKey, $this->currentDate, $this->regionName, $this->serviceName);
726
        $signature = hash_hmac("sha256", $stringToSign, $signatureKey, true);
727
        $strHexSignature = strtolower(bin2hex($signature));
728
        return $strHexSignature;
729
    }
730
 
731
    public function getHeaders() {
732
        $this->awsHeaders['x-amz-date'] = $this->xAmzDate;
733
        ksort($this->awsHeaders);
734
 
735
        // Step 1: CREATE A CANONICAL REQUEST
736
        $canonicalURL = $this->prepareCanonicalRequest();
737
 
738
        // Step 2: CREATE THE STRING TO SIGN
739
        $stringToSign = $this->prepareStringToSign($canonicalURL);
740
 
741
        // Step 3: CALCULATE THE SIGNATURE
742
        $signature = $this->calculateSignature($stringToSign);
743
 
744
        // Step 4: CALCULATE AUTHORIZATION HEADER
745
        if ($signature) {
746
            $this->awsHeaders['Authorization'] = $this->buildAuthorizationString($signature);
747
            return $this->awsHeaders;
748
        }
749
    }
750
 
751
    private function buildAuthorizationString($strSignature) {
752
        return $this->HMACAlgorithm . " " . "Credential=" . $this->accessKey . "/" . $this->getDate() . "/" . $this->regionName . "/" . $this->serviceName . "/" . $this->aws4Request . "," . "SignedHeaders=" . $this->strSignedHeader . "," . "Signature=" . $strSignature;
753
    }
754
 
755
    private function generateHex($data) {
756
        return strtolower(bin2hex(hash("sha256", $data, true)));
757
    }
758
 
759
    private function getSignatureKey($key, $date, $regionName, $serviceName) {
760
        $kSecret = "AWS4" . $key;
761
        $kDate = hash_hmac("sha256", $date, $kSecret, true);
762
        $kRegion = hash_hmac("sha256", $regionName, $kDate, true);
763
        $kService = hash_hmac("sha256", $serviceName, $kRegion, true);
764
        $kSigning = hash_hmac("sha256", $this->aws4Request, $kService, true);
765
 
766
        return $kSigning;
767
    }
768
 
769
    private function getTimeStamp() {
770
        return gmdate("Ymd\THis\Z");
771
    }
772
 
773
    private function getDate() {
774
        return gmdate("Ymd");
775
    }
776
}