Subversion Repositories cheapmusic

Rev

Rev 125 | Rev 130 | 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;
127 - 132
 
133
        $xh = new Html;
134
        $xh->init($_SESSION["htmlIndent"]);
135
        startMatches($xh);
99 - 136
    }
81 - 137
 
99 - 138
    $listings = 0;
120 - 139
    $wlAddArr = [];
140
    $wlSearchArr = [];
99 - 141
    // If the response was loaded, parse it and store in array
142
    foreach ($parsed_json->SearchResult->Items as $current) {
143
        if (isset($current->ItemInfo->ExternalIds->UPCs)) {
144
            $barcode = (string)$current->ItemInfo->ExternalIds->UPCs->DisplayValues[0];
145
        }
146
        else if (isset($current->ItemInfo->ExternalIds->EANs)) {
147
            $barcode = (string)$current->ItemInfo->ExternalIds->EANs->DisplayValues[0];
148
        }
149
        else if (isset($current->ItemInfo->ExternalIds->ISBNs)) {
150
            $barcode = (string)$current->ItemInfo->ExternalIds->ISBNs->DisplayValues[0];
151
        }
152
        else if (isset($current->ItemInfo->ExternalIds->EISBNs)) {
153
            $barcode = (string)$current->ItemInfo->ExternalIds->EISBNs->DisplayValues[0];
154
        }
155
        else {
156
            $barcode = "";
157
        }
158
        $barcodeType = clsLibGTIN::GTINCheck($barcode, false, 1);
81 - 159
 
102 - 160
        $pic = !empty($current->Images->Primary->Medium->URL) ? (string)$current->Images->Primary->Medium->URL : "images/no-image-available.jpg";
100 - 161
        $pic = str_replace('http://', 'https://', $pic);
99 - 162
        if (empty($pic)) {
163
            continue;
164
        }
81 - 165
 
99 - 166
        if (strpos($current->ItemInfo->Classifications->Binding->DisplayValue, "Audio CD") !== false) {
167
            $mediaType = "CD";
168
        }
169
        else if (strpos($current->ItemInfo->Classifications->Binding->DisplayValue, "MP3 Music") !== false) {
170
            $mediaType = "Digital";
171
        }
172
        else if (strpos($current->ItemInfo->Classifications->Binding->DisplayValue, "Vinyl") !== false) {
173
            $mediaType = "Record";
174
        }
175
        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) {
176
            $mediaType = "Book";
177
        }
178
        else {
179
            continue;
180
        }
81 - 181
 
182
        if ($needMatches) {
99 - 183
            // bugbug: check maxMasterCnt?
127 - 184
            addMatch($xh, $current, ++$cnt, $mediaType, $wlAddArr, $wlSearchArr);
81 - 185
        }
186
 
99 - 187
        $title = (string)$current->ItemInfo->Title->DisplayValue;
188
        $artists = getArtists($current);
189
        $contributers = getContributers($current);
190
        if (!empty($artists)) {
191
            $title .= " by " . join(", ", $artists);
192
        }
193
        else if (!empty($contributers)) {
194
            $title .= " by " . join(", ", $contributers);
195
        }
81 - 196
 
99 - 197
        $url = str_replace('http://', 'https://', (string)$current->DetailPageURL);
81 - 198
 
99 - 199
        if (empty($url)) {
200
            continue;
201
        }
81 - 202
 
99 - 203
        $bestOffer = false;
81 - 204
 
99 - 205
        $url = str_replace('http://', 'https://', (string)$current->DetailPageURL);
206
        $url .= "&condition=";
81 - 207
 
99 - 208
        if (!empty($current->Offers->Listings)) {
209
            foreach ($current->Offers->Listings as $offer) {
210
                $country = 'US';
211
                if (isset($offer->MerchantInfo->DefaultShippingCountry)) {
212
                    $country = $offer->MerchantInfo->DefaultShippingCountry;
213
                }
214
                $merchantName = "Amazon";
215
                if (strpos($offer->MerchantInfo->Name, "Amazon") === false) {
216
                    $merchantName .= " Marketplace";
217
                }
81 - 218
 
99 - 219
                $condition = (string)$offer->Condition->Value;
220
                $url .= $condition;
221
                $detailCondition = $condition;
222
                if ($condition == "Collectible") {
223
                    $condition = 'Used';
224
                    $detailCondition = "Collectible";
225
                }
226
                if ($condition == "Refurbished") {
227
                    $condition = 'Used';
228
                    $detailCondition = "Refurbished";
229
                }
230
                $currency = (string)$offer->Price->Currency;
231
                $price = number_format(floatval($offer->Price->Amount) , 2, '.', '');
81 - 232
 
99 - 233
                if ($price <= "0.00") {
234
                    continue;
235
                }
81 - 236
 
99 - 237
                $timeLeft = 0;
238
                $listingType = 'Fixed';
239
                $location = 'US';
240
                $zip = '';
241
                $feedbackScore = - 1;
242
                $feedbackPercent = - 1;
243
                $sellerName = "";
244
                $handlingTime = 0;
245
                if ($offer->DeliveryInfo->IsPrimeEligible === true) {
246
                    $sellerName = "Prime";
81 - 247
                }
99 - 248
                if ($mediaType == "Digital") {
249
                    $shippingCost = 0.00;
250
                    $shippingEstimated = false;
251
                    $shippingCurrency = 'USD';
252
                }
253
                else {
254
                    $shippingCost = 3.99; // bugbug
255
                    $shippingEstimated = true; // bugbug
256
                    $shippingCurrency = 'USD';
257
                }
258
                $freeShippingCap = !empty($offer->DeliveryInfo->IsFreeShippingEligible) ? 25 : 0;
81 - 259
 
99 - 260
                if (++$listings > $numResults) {
261
                    continue;
262
                }
81 - 263
 
99 - 264
                $arr[] = array(
265
                    "Merchant" => $merchantName,
266
                    "Condition" => $condition,
267
                    "Title" => $title,
268
                    "Barcode" => $barcode,
269
                    "BarcodeType" => $barcodeType,
270
                    "Image" => $pic,
271
                    "URL" => $url,
272
                    "MediaType" => $mediaType,
273
                    "DetailCondition" => $detailCondition,
274
                    "Country" => $country,
275
                    "BestOffer" => $bestOffer,
276
                    "TimeLeft" => $timeLeft,
277
                    "Price" => $price,
278
                    "Currency" => $currency,
279
                    "ListingType" => $listingType,
280
                    "Location" => $location,
281
                    "Zip" => $zip,
282
                    "FeedbackScore" => $feedbackScore,
283
                    "FeedbackPercent" => $feedbackPercent,
284
                    "SellerName" => $sellerName,
285
                    "HandlingTime" => $handlingTime,
286
                    "ShippingCost" => $shippingCost,
287
                    "ShippingEstimated" => $shippingEstimated,
288
                    "ShippingCurrency" => $shippingCurrency,
289
                    "FreeShippingCap" => $freeShippingCap,
290
                    "Show" => true
291
                );
81 - 292
            }
293
        }
99 - 294
    }
81 - 295
 
99 - 296
    if ($needMatches) {
297
        if ($cnt = 0) {
298
            $_SESSION["discogs"] = "";
81 - 299
        }
99 - 300
        else {
127 - 301
            endMatches($xh, $wlAddArr, $wlSearchArr);
302
 
303
            $_SESSION["discogs"] = $xh->flush();
304
            error_log(print_r($_SESSION["discogs"], 1));
99 - 305
        }
81 - 306
    }
99 - 307
 
81 - 308
    // If the response does not indicate 'Success,' log the error(s)
99 - 309
    /******************
81 - 310
    else {
96 - 311
        my_error_log($url);
99 - 312
        if (!empty($parsed_json->OperationRequest->Errors)) {
313
            foreach($parsed_json->OperationRequest->Errors->Error as $error){
96 - 314
                my_error_log($error->Message . " (" . $error->Code . ")");
81 - 315
            }
99 - 316
        } else if (!empty($parsed_json->Errors)) {
317
            foreach($parsed_json->OperationRequest->Errors->Error as $error){
96 - 318
                my_error_log($error->Message . " (" . $error->Code . ")");
81 - 319
            }
99 - 320
        } else if (!empty($parsed_json->Error)) {
321
            my_error_log($parsed_json->Error->Message . " (" . $parsed_json->Error->Code . ")");
81 - 322
        } else {
96 - 323
            my_error_log(print_r($result, 1));
81 - 324
        }
325
    }
99 - 326
    ******************/
81 - 327
 
328
    return $arr;
329
}
330
 
127 - 331
function startMatches(&$xh) {
332
    $xh->add_attribute("class", "container-fluid bg-light");
333
    $xh->tag('div');
334
    $xh->add_attribute("class", "text-center py-2");
335
    $xh->tag('h2', "Matching Albums");
81 - 336
 
127 - 337
    $xh->tag('form');
338
    $xh->insert_code(inputSessionTab());
339
    $xh->insert_code(inputNonce());
340
    $xh->add_attribute("id", "discogsTitle");
341
    $xh->add_attribute("type", "hidden");
342
    $xh->add_attribute("name", "discogsTitle");
343
    $xh->add_attribute("value", "");
344
    $xh->single_tag('input');
345
    $xh->add_attribute("id", "discogsArtist");
346
    $xh->add_attribute("type", "hidden");
347
    $xh->add_attribute("name", "discogsArtist");
348
    $xh->add_attribute("value", "");
349
    $xh->single_tag('input');
350
    $xh->add_attribute("id", "discogsBarcode");
351
    $xh->add_attribute("type", "hidden");
352
    $xh->add_attribute("name", "discogsBarcode");
353
    $xh->add_attribute("value", "");
354
    $xh->single_tag('input');
355
    $xh->add_attribute("id", "discogsDeck");
356
    $xh->add_attribute("class", "card-deck");
357
    $xh->tag('div');
81 - 358
}
359
 
127 - 360
function endMatches(&$xh, $wlAddArr, $wlSearchArr) {
361
    $xh->add_attribute("nonce", "xxxNONCExxx");
362
    $xh->tag('script');
363
        $str  = trim('function addDiscogsEventsWait() {');
364
        $str .= trim('document.addEventListener("DOMContentLoaded", function() {');
365
        $str .= trim('	addDiscogsEvents();');
366
        $str .= trim('});');
367
        $str .= trim('}');
81 - 368
 
127 - 369
        $str .= trim('function addDiscogsEvents() {');
370
        foreach($wlAddArr as $k=>$v) {
371
            $str .= trim('el = document.getElementById("' . $k . '");');
372
            $str .= trim('if (el) document.getElementById("' . $k . '").addEventListener("click", function() {');
373
            $str .= trim($v);
374
            $str .= trim('	});');
375
        }
376
 
377
        foreach($wlSearchArr as $k=>$v) {
378
            $str .= trim('el = document.getElementById("' . $k . '");');
379
            $str .= trim('if (el) document.getElementById("' . $k . '").addEventListener("click", function() {');
380
            $str .= trim($v);
381
            $str .= trim('	});');
382
        }
383
        $str .= trim('}');
384
        $str .= trim('addDiscogsEventsWait();');
385
        $xh->insert_code($str);
386
    $xh->close(); // script
387
 
388
    $xh->close(); // div
389
    $xh->close(); // form>";
390
    $xh->close(); // div>";
81 - 391
}
392
 
127 - 393
function addMatch(&$xh, $item, $cnt, $mediaType, &$wlAddArr, &$wlSearchArr) {
394
    $xhmod = new Html;
395
    $xhmod->init($_SESSION["htmlIndent"]);
396
 
81 - 397
    $artists = getArtists($item);
99 - 398
    $contributers = getContributers($item);
81 - 399
 
99 - 400
    $label = "";
401
    if (!empty($item->ItemInfo->ByLineInfo->Manufacturer)) {
100 - 402
        $label = $item->ItemInfo->ByLineInfo->Manufacturer->DisplayValue;
81 - 403
    }
404
 
405
    $languages = [];
99 - 406
    if (!empty($item->ItemInfo->ContentInfo->Languages)) {
407
        foreach ($item->ItemInfo->ContentInfo->Languages->DisplayValues as $language) {
81 - 408
            if ((string)$language->Type != "Unknown") {
99 - 409
                $languages[] = $language->DisplayValue . " (" . $language->Type . ")";
81 - 410
            }
411
        }
412
    }
413
 
101 - 414
    $genres = [];
415
    if (!empty($item->ItemInfo->Genre)) {
416
        foreach($item->ItemInfo->Genre as $genre) {
417
            $genres[] = join(" ", array_map('ucfirst', explode('-', $genre)));
418
        }
419
    }
420
 
421
    $runningTime = "";
422
    if (!empty($item->ItemInfo->RunningTime)) {
423
        if ($mediaType != 'Digital') {
424
            $runningTime = (string)$item->ItemInfo->RunningTime . " minutes";
425
        } else {
426
            $runningTime = gmdate("H:i:s", (int)$item->ItemInfo->RunningTime);
427
        }
428
    }
429
 
127 - 430
    $xh->add_attribute("class", "card mx-auto discogs-card");
431
    $xh->tag('div');
432
    $xh->add_attribute("class", "card-header bg-secondary d-flex");
433
    $xh->tag('div');
81 - 434
    $searchArtists = "";
105 - 435
    $wlArtists = "";
99 - 436
    if (!empty($artists)) {
437
        if (count($artists) < 5) {
438
            $wlArtists = join(", ", $artists);
439
            if (!empty($artists) && $artists[0] != 'Various') {
440
                $searchArtists = join(" ", $artists);
441
            }
442
        } else {
443
            $wlArtists = "Various Artists";
81 - 444
        }
445
    }
99 - 446
    else if (!empty($contributers)) {
447
        if (count($contributers) < 5) {
448
            $wlArtists = join(", ", $contributers);
449
            if (!empty($contributers) && $contributers[0] != 'Various') {
450
                $searchArtists = join(" ", $contributers);
451
            }
452
        } else {
453
            $wlArtists = "Various Artists";
454
        }
81 - 455
    }
127 - 456
 
457
    $str = htmlentities((string)$item->ItemInfo->Title->DisplayValue);
124 - 458
    if (!empty($wlArtists)) {
125 - 459
        $str .= " by " . htmlentities($wlArtists);
124 - 460
    }
127 - 461
    $xh->add_attribute("class", "card-title font-weight-bold small flex-grow-1");
462
    $xh->tag('p', $str);
463
    $xh->close(); // div
81 - 464
 
99 - 465
    $thumbnail = !empty($item->Images->Primary->Medium->URL) ? (string)$item->Images->Primary->Medium->URL : "images/no-image-available.jpg";
81 - 466
 
127 - 467
    $xh->add_attribute("class", "card-body d-flex justify-content-center align-items-center p-1 m-0");
468
    $xh->tag('div');
469
    $xh->add_attribute("class", "btn p-0 m-0 lazyload");
470
    $xh->add_attribute("src", PIXEL);
471
    $xh->add_attribute("data-src",  $thumbnail);
472
    $xh->add_attribute("data-toggle", "modal");
473
    $xh->add_attribute("data-target", "#masterModal" . $cnt);
474
    $xh->add_attribute("title", "Album Information");
475
    $xh->add_attribute("data-toggle2", "tooltip");
476
    $xh->add_attribute("alt", "Cover Thumbnail");
477
    $xh->single_tag('img');
478
    $xh->close(); // div
479
    $xh->add_attribute("class", "card-footer bg-secondary p-0 m-0");
480
    $xh->tag('div');
481
    $xh->add_attribute("class", "container clearfix p-0 m-0");
482
    $xh->tag('div');
483
    $xh->add_attribute("class", "float-left btn-group-sm");
484
    $xh->tag('span');
485
    $xh->add_attribute("type", "button");
486
    $xh->add_attribute("class", "btn btn-info btn-sm");
487
    $xh->add_attribute("data-toggle", "modal");
488
    $xh->add_attribute("data-target", "#masterModal" . $cnt);
489
    $xh->add_attribute("title", "Album Information");
490
    $xh->add_attribute("aria-label", "Album Information");
491
    $xh->add_attribute("data-toggle2", "tooltip");
492
    $xh->tag('button');
493
    $xh->add_attribute("class", "material-icons");
494
    $xh->tag('i', "info_outline");
495
    $xh->close(); // button
81 - 496
 
127 - 497
    $xh->close(); // span
81 - 498
 
127 - 499
    $xh->add_attribute("class", "float-right btn-group-sm");
500
    $xh->tag('span');
81 - 501
 
502
    $barcode = "";
503
    $tmpBarcode = "";
99 - 504
    if (isset($item->ItemInfo->ExternalIds->UPCs)) {
505
        $tmpBarcode = (string)$item->ItemInfo->ExternalIds->UPCs->DisplayValues[0];
81 - 506
    }
99 - 507
    else if (isset($item->ItemInfo->ExternalIds->EANs)) {
508
        $tmpBarcode = (string)$item->ItemInfo->ExternalIds->EANs->DisplayValues[0];
509
    }
510
    else if (isset($item->ItemInfo->ExternalIds->ISBNs)) {
511
        $tmpBarcode = (string)$item->ItemInfo->ExternalIds->ISBNs->DisplayValues[0];
512
    }
513
    else if (isset($item->ItemInfo->ExternalIds->EISBNs)) {
514
        $tmpBarcode = (string)$item->ItemInfo->ExternalIds->EISBNs->DisplayValues[0];
515
    }
81 - 516
    $barcodeType = clsLibGTIN::GTINCheck($tmpBarcode, false, 1);
517
    if (!empty($barcodeType)) {
518
        $barcode = $tmpBarcode;
519
    }
520
 
521
    if (isLoggedIn() && !checkWishlist('asin', $item->ASIN)) {
522
        $wlArr = array(
523
            'asin' => (string)$item->ASIN,
99 - 524
            'title' => (string)$item->ItemInfo->Title->DisplayValue,
81 - 525
            'artist' => $wlArtists,
526
            'barcode' => $barcode,
527
            'thumbnail' => $thumbnail,
528
            'url' => (string)$item->DetailPageURL
529
        );
530
        $wl = base64_encode(json_encode($wlArr));
127 - 531
        $xh->add_attribute("id", "wl" . $cnt . "Btn");
532
        $xh->add_attribute("type", "button");
533
        $xh->add_attribute("class", "btn btn-info btn-sm");
534
        $xh->add_attribute("title", "Add to Wishlist");
535
        $xh->add_attribute("aria-label", "Add to Wishlist");
536
        $xh->add_attribute("data-toggle", "tooltip");
537
        $xh->tag('button');
538
        $xh->add_attribute("class", "material-icons");
539
        $xh->tag('i', "bookmark");
540
        $xh->close(); // button
120 - 541
        $wlAddArr["wl" . $cnt . "Btn"] = 'addWishlist("' . $_SESSION['sessData']['userID'] . '", this,' . $cnt . ',"' . $wl . '");';
81 - 542
    }
543
 
125 - 544
    $searchTitle = 'Searching for:<br><br><strong>' . htmlentities((string)$item->ItemInfo->Title->DisplayValue) . ' by ' . htmlentities($wlArtists) . '</strong>';
81 - 545
    if (!empty($barcode)) {
546
        $searchTitle .= " (" . displayBarcode($barcode) . ")";
547
    }
548
 
127 - 549
    $xh->tag('span', " ");
550
    $xh->add_attribute("id", "discogsSearch" . $cnt . "Btn");
551
    $xh->add_attribute("type", "submit");
552
    $xh->add_attribute("name", "submit");
553
    $xh->add_attribute("value", "discogsSearch");
554
    $xh->add_attribute("class", "btn btn-success btn-sm");
555
    $xh->add_attribute("title", "Search for Store Offers");
556
    $xh->add_attribute("aria-label", "Search for Store Offers");
557
    $xh->add_attribute("data-toggle", "tooltip");
558
    $xh->tag('button');
559
    $xh->add_attribute("class", "material-icons");
560
    $xh->tag('i', "search");
561
    $xh->close(); // button
562
    $xh->close(); // span
563
    $xh->close(); // div
120 - 564
 
565
    $wlSearchArr["discogsSearch" . $cnt . "Btn"] = 'document.getElementById("discogsTitle").value = "' . addslashes((string)$item->ItemInfo->Title->DisplayValue) . '";' .
566
                                                   'document.getElementById("discogsArtist").value = "' . addslashes($searchArtists) . '";' .
567
                                                   'document.getElementById("discogsBarcode").value = "' . $barcode . '";' .
568
                                                   'progressBar("' . $searchTitle . '");';
569
 
127 - 570
    $xh->add_attribute("id", "wishlistAdd" . $cnt);
571
    $xh->tag('span', "");
572
    $xh->close(); // div
81 - 573
 
127 - 574
    $xhmod->add_attribute("id", "masterModal" . $cnt);
575
    $xhmod->add_attribute("class", "modal");
576
    $xhmod->tag('div');
577
    $xhmod->add_attribute("class", "modal-dialog");
578
    $xhmod->tag('div');
579
    $xhmod->add_attribute("class", "modal-content");
580
    $xhmod->tag('div');
581
    $xhmod->add_attribute("class", "modal-header bg-secondary");
582
    $xhmod->tag('div');
583
    $xhmod->add_attribute("class", "modal-title mx-auto display-6");
584
    $xhmod->tag('p', htmlentities((string)$item->ItemInfo->Title->DisplayValue) . " by " . htmlentities($wlArtists));
585
    $xhmod->add_attribute("type", "button");
586
    $xhmod->add_attribute("class", "close");
587
    $xhmod->add_attribute("data-dismiss", "modal");
588
    $xhmod->tag('button');
589
    $xhmod->add_attribute("class", "material-icons btn-dismiss");
590
    $xhmod->tag('i', "cancel_presentation");
591
    $xhmod->close(); // button
592
    $xhmod->close(); // div
81 - 593
 
127 - 594
    $xhmod->add_attribute("class", "modal-body mx-auto");
595
    $xhmod->tag('div');
81 - 596
 
99 - 597
    if (!empty($item->Images->Primary->Large->URL)) {
127 - 598
        $xhmod->add_attribute("class", "responsive-image mx-auto mb-4 lazyload");
599
        $xhmod->add_attribute("src", PIXEL);
600
        $xhmod->add_attribute("data-src", (string)$item->Images->Primary->Large->URL);
601
        $xhmod->add_attribute("alt", "Cover Image");
602
        $xhmod->single_tag('img');
81 - 603
    }
604
 
127 - 605
    $xhmod->add_attribute("class", "table-borderless table-condensed small mx-auto");
606
    $xhmod->tag('table');
81 - 607
 
127 - 608
    $xhmod->tag('tr');
609
    $xhmod->add_attribute("class", "px-1");
610
    $xhmod->tag('td', "Title:");
611
    $xhmod->add_attribute("class", "px-1");
612
    $xhmod->tag('td', htmlentities((string)$item->ItemInfo->Title->DisplayValue));
613
    $xhmod->close(); // tr
614
 
615
    $xhmod->tag('tr');
616
    $xhmod->add_attribute("class", "px-1");
617
    $xhmod->tag('td', "Artist:");
618
    $xhmod->add_attribute("class", "px-1");
619
    $xhmod->tag('td', htmlentities(join(", ", $artists)));
620
    $xhmod->close(); // tr
621
 
99 - 622
    if (!empty($contributers)) {
127 - 623
        $xhmod->tag('tr');
624
        $xhmod->add_attribute("class", "px-1");
625
        $xhmod->tag('td', "Creator:");
626
        $xhmod->add_attribute("class", "px-1");
627
        $xhmod->tag('td', htmlentities(join(", ", $contributers)));
628
        $xhmod->close(); // tr
81 - 629
    }
630
 
631
    if (!empty($actors)) {
127 - 632
        $xhmod->tag('tr');
633
        $xhmod->add_attribute("class", "px-1");
634
        $xhmod->tag('td', "Actor:");
635
        $xhmod->add_attribute("class", "px-1");
636
        $xhmod->tag('td', htmlentities(join(", ", $actors)));
637
        $xhmod->close(); // tr
81 - 638
    }
639
 
640
    if (!empty($directors)) {
127 - 641
        $xhmod->tag('tr');
642
        $xhmod->add_attribute("class", "px-1");
643
        $xhmod->tag('td', "Director:");
644
        $xhmod->add_attribute("class", "px-1");
645
        $xhmod->tag('td', htmlentities(join(", ", $directors)));
646
        $xhmod->close(); // tr
81 - 647
    }
648
 
649
    if (!empty($authors)) {
127 - 650
        $xhmod->tag('tr');
651
        $xhmod->add_attribute("class", "px-1");
652
        $xhmod->tag('td', "Author:");
653
        $xhmod->add_attribute("class", "px-1");
654
        $xhmod->tag('td', htmlentities(join(", ", $authors)));
655
        $xhmod->close(); // tr
81 - 656
    }
657
 
99 - 658
    if (!empty($item->ItemInfo->Classifications->Binding)) {
127 - 659
        $xhmod->tag('tr');
660
        $xhmod->add_attribute("class", "px-1");
661
        $xhmod->tag('td', "Type:");
662
        $xhmod->add_attribute("class", "px-1");
663
        $xhmod->tag('td', htmlentities((string)$item->ItemInfo->Classifications->Binding->DisplayValue));
664
        $xhmod->close(); // tr
81 - 665
    }
666
 
101 - 667
    if (!empty($item->ItemInfo->MediaType)) { //
127 - 668
        $xhmod->tag('tr');
669
        $xhmod->add_attribute("class", "px-1");
670
        $xhmod->tag('td', "Media Type:");
671
        $xhmod->add_attribute("class", "px-1");
672
        $xhmod->tag('td', htmlentities((string)$item->ItemInfo->MediaType));
673
        $xhmod->close(); // tr
81 - 674
    }
675
 
676
    if (!empty($barcode)) {
127 - 677
        $xhmod->tag('tr');
678
        $xhmod->add_attribute("class", "px-1");
679
        $xhmod->tag('td', "Barcode:");
680
        $xhmod->add_attribute("class", "px-1");
681
        $xhmod->tag('td', displayBarcode($barcode));
682
        $xhmod->close(); // tr
81 - 683
    }
684
 
99 - 685
    if (!empty($label)) {
127 - 686
        $xhmod->tag('tr');
687
        $xhmod->add_attribute("class", "px-1");
688
        $xhmod->tag('td', "Label:");
689
        $xhmod->add_attribute("class", "px-1");
690
        $xhmod->tag('td', htmlentities($label));
691
        $xhmod->close(); // tr
81 - 692
    }
693
 
694
    if (!empty($languages)) {
127 - 695
        $xhmod->tag('tr');
696
        $xhmod->add_attribute("class", "px-1");
697
        $xhmod->tag('td', "Languages:");
698
        $xhmod->add_attribute("class", "px-1");
699
        $xhmod->tag('td', htmlentities(join(", ", $languages)));
700
        $xhmod->close(); // tr
81 - 701
    }
702
 
99 - 703
    if (!empty($item->ItemInfo->ContentInfo->PublicationDate)) {
127 - 704
        $xhmod->tag('tr');
705
        $xhmod->add_attribute("class", "px-1");
706
        $xhmod->tag('td', "Publication Date:");
707
        $xhmod->add_attribute("class", "px-1");
708
        $xhmod->tag('td', htmlentities((string)$item->ItemInfo->ContentInfo->PublicationDate->DisplayValue));
709
        $xhmod->close(); // tr
81 - 710
    }
711
 
99 - 712
    if (!empty($item->ItemInfo->ContentInfo->ReleaseDate)) {
127 - 713
        $xhmod->tag('tr');
714
        $xhmod->add_attribute("class", "px-1");
715
        $xhmod->tag('td', "Release Date:");
716
        $xhmod->add_attribute("class", "px-1");
717
        $xhmod->tag('td', htmlentities((string)$item->ItemInfo->ContentInfo->ReleaseDate->DisplayValue));
718
        $xhmod->close(); // tr
81 - 719
    }
720
 
101 - 721
    if (!empty($genres)) {
127 - 722
        $xhmod->tag('tr');
723
        $xhmod->add_attribute("class", "px-1");
724
        $xhmod->tag('td', "Genre:");
725
        $xhmod->add_attribute("class", "px-1");
726
        $xhmod->tag('td', htmlentities(join(", ", $genres)));
727
        $xhmod->close(); // tr
101 - 728
    }
729
 
99 - 730
    if (!empty($item->ItemInfo->ContentInfo->UnitCount->DisplayValue)) {
127 - 731
        $xhmod->tag('tr');
732
        $xhmod->add_attribute("class", "px-1");
733
        $xhmod->tag('td', "Number of Discs:");
734
        $xhmod->add_attribute("class", "px-1");
735
        $xhmod->tag('td', htmlentities((string)$item->ItemInfo->ContentInfo->UnitCount->DisplayValue));
736
        $xhmod->close(); // tr
81 - 737
    }
738
 
99 - 739
    if (!empty($item->ItemInfo->ContentInfo->PagesCount->DisplayValue)) {
127 - 740
        $xhmod->tag('tr');
741
        $xhmod->add_attribute("class", "px-1");
742
        $xhmod->tag('td', "Number of Pages:");
743
        $xhmod->add_attribute("class", "px-1");
744
        $xhmod->tag('td', htmlentities((string)$item->ItemInfo->ContentInfo->PagesCount->DisplayValue));
745
        $xhmod->close(); // tr
81 - 746
    }
747
 
101 - 748
    if (!empty($item->ItemInfo->RunningTime)) {
127 - 749
        $xhmod->tag('tr');
750
        $xhmod->add_attribute("class", "px-1");
751
        $xhmod->tag('td', "Running Time:");
752
        $xhmod->add_attribute("class", "px-1");
753
        $xhmod->tag('td', htmlentities($runningTime));
754
        $xhmod->close(); // tr
101 - 755
    }
756
 
757
    if (!empty($item->ItemInfo->Edition)) {
127 - 758
        $xhmod->tag('tr');
759
        $xhmod->add_attribute("class", "px-1");
760
        $xhmod->tag('td', "Edition:");
761
        $xhmod->add_attribute("class", "px-1");
762
        $xhmod->tag('td', htmlentities((string)$item->ItemInfo->Edition));
763
        $xhmod->close(); // tr
101 - 764
    }
765
 
766
    if (!empty($item->Tracks)) {
127 - 767
        $xhmod->tag('tr');
768
        $xhmod->add_attribute("colspan", "2");
769
        $xhmod->add_attribute("class", "px-1");
770
        $xhmod->tag('td', "Tracks:");
771
        $xhmod->close(); // tr
772
 
773
        $xhmod->tag('tr');
774
        $xhmod->add_attribute("colspan", "2");
775
        $xhmod->tag('td');
776
        $xhmod->add_attribute("class", "pl-3 pt-0 small list-unstyled");
777
        $xhmod->tag('ul');
101 - 778
        foreach ($item->Tracks->Disc as $disc) {
779
            if ((int)$item->ItemInfo->ContentInfo->UnitCount->DisplayValue > 1 && !empty($disc->attributes())) {
127 - 780
                $xhmod->add_attribute("class", "font-weight-bold");
781
                $xhmod->tag('li', "Disc " . $disc->attributes() . ":");
101 - 782
            }
783
 
784
            foreach($disc->Track as $track) {
127 - 785
                $xhmod->tag('li', (!empty($track->attributes()) ? $track->attributes() . ") " : "") . htmlentities($track));
101 - 786
            }
787
        }
127 - 788
        $xhmod->close(); // ul
789
        $xhmod->close(); // td
790
        $xhmod->close(); // tr
101 - 791
    }
792
 
127 - 793
    $xhmod->close(); // table
794
    $xhmod->close(); // div
795
    $xhmod->add_attribute("class", "modal-footer bg-secondary justify-content-between");
796
    $xhmod->tag('div');
797
    $xhmod->add_attribute("class", "float-right");
798
    $xhmod->tag('span');
799
    $xhmod->add_attribute("type", "button");
800
    $xhmod->add_attribute("class", "btn btn-danger");
801
    $xhmod->add_attribute("data-dismiss", "modal");
802
    $xhmod->tag('button', "Close");
803
    $xhmod->close(); // span
804
    $xhmod->close(); // div
805
    $xhmod->close(); // div
806
    $xhmod->close(); // div
807
    $xhmod->close(); // div
808
    $html = $xhmod->flush();
809
    //error_log(print_r($html, 1));
81 - 810
 
127 - 811
    $xh->insert_code($html);
812
    $xh->close(); // div
813
 
814
    return;
81 - 815
}
816
 
817
function getArtists($item) {
818
    $artists = [];
819
 
101 - 820
    if (!empty($item->ItemInfo->Artist)){
821
        $artists[] = $item->ItemInfo->Artist;
822
    } else if (!empty($item->ItemInfo->ByLineInfo->Contributors)) {
99 - 823
        foreach ($item->ItemInfo->ByLineInfo->Contributors as $artist) {
824
            if ((string)$artist->Role == "Artist") {
825
                $artists[] = $artist->Name;
826
            }
81 - 827
        }
828
    }
829
 
830
    return $artists;
831
}
832
 
99 - 833
function getContributers($item) {
834
    $contributers = [];
835
 
836
    if (!empty($item->ItemInfo->ByLineInfo->Contributors)) {
837
        foreach ($item->ItemInfo->ByLineInfo->Contributors as $creator) {
838
            if ((string)$creator->Role == "Primary Contributor") {
839
                $contributers[] = $creator->Name;
81 - 840
            }
99 - 841
            else {
842
                $contributers[] = $creator->Name . " (" . $creator->Role . ")";
843
            }
81 - 844
        }
845
    }
846
 
99 - 847
    return $contributers;
81 - 848
}
99 - 849
 
850
class AwsV4 {
851
 
852
    private $accessKey = null;
853
    private $secretKey = null;
854
    private $path = null;
855
    private $regionName = null;
856
    private $serviceName = null;
857
    private $httpMethodName = null;
858
    private $queryParametes = array();
859
    private $awsHeaders = array();
860
    private $payload = "";
861
 
862
    private $HMACAlgorithm = "AWS4-HMAC-SHA256";
863
    private $aws4Request = "aws4_request";
864
    private $strSignedHeader = null;
865
    private $xAmzDate = null;
866
    private $currentDate = null;
867
 
868
    public function __construct($accessKey, $secretKey) {
869
        $this->accessKey = $accessKey;
870
        $this->secretKey = $secretKey;
871
        $this->xAmzDate = $this->getTimeStamp();
872
        $this->currentDate = $this->getDate();
873
    }
874
 
875
    function setPath($path) {
876
        $this->path = $path;
877
    }
878
 
879
    function setServiceName($serviceName) {
880
        $this->serviceName = $serviceName;
881
    }
882
 
883
    function setRegionName($regionName) {
884
        $this->regionName = $regionName;
885
    }
886
 
887
    function setPayload($payload) {
888
        $this->payload = $payload;
889
    }
890
 
891
    function setRequestMethod($method) {
892
        $this->httpMethodName = $method;
893
    }
894
 
895
    function addHeader($headerName, $headerValue) {
896
        $this->awsHeaders[$headerName] = $headerValue;
897
    }
898
 
899
    private function prepareCanonicalRequest() {
900
        $canonicalURL = "";
901
        $canonicalURL .= $this->httpMethodName . "\n";
902
        $canonicalURL .= $this->path . "\n" . "\n";
903
        $signedHeaders = '';
904
        foreach ($this->awsHeaders as $key => $value) {
905
            $signedHeaders .= $key . ";";
906
            $canonicalURL .= $key . ":" . $value . "\n";
907
        }
908
        $canonicalURL .= "\n";
909
        $this->strSignedHeader = substr($signedHeaders, 0, -1);
910
        $canonicalURL .= $this->strSignedHeader . "\n";
911
        $canonicalURL .= $this->generateHex($this->payload);
912
        return $canonicalURL;
913
    }
914
 
915
    private function prepareStringToSign($canonicalURL) {
916
        $stringToSign = '';
917
        $stringToSign .= $this->HMACAlgorithm . "\n";
918
        $stringToSign .= $this->xAmzDate . "\n";
919
        $stringToSign .= $this->currentDate . "/" . $this->regionName . "/" . $this->serviceName . "/" . $this->aws4Request . "\n";
920
        $stringToSign .= $this->generateHex($canonicalURL);
921
        return $stringToSign;
922
    }
923
 
924
    private function calculateSignature($stringToSign) {
925
        $signatureKey = $this->getSignatureKey($this->secretKey, $this->currentDate, $this->regionName, $this->serviceName);
926
        $signature = hash_hmac("sha256", $stringToSign, $signatureKey, true);
927
        $strHexSignature = strtolower(bin2hex($signature));
928
        return $strHexSignature;
929
    }
930
 
931
    public function getHeaders() {
932
        $this->awsHeaders['x-amz-date'] = $this->xAmzDate;
933
        ksort($this->awsHeaders);
934
 
935
        // Step 1: CREATE A CANONICAL REQUEST
936
        $canonicalURL = $this->prepareCanonicalRequest();
937
 
938
        // Step 2: CREATE THE STRING TO SIGN
939
        $stringToSign = $this->prepareStringToSign($canonicalURL);
940
 
941
        // Step 3: CALCULATE THE SIGNATURE
942
        $signature = $this->calculateSignature($stringToSign);
943
 
944
        // Step 4: CALCULATE AUTHORIZATION HEADER
945
        if ($signature) {
946
            $this->awsHeaders['Authorization'] = $this->buildAuthorizationString($signature);
947
            return $this->awsHeaders;
948
        }
949
    }
950
 
951
    private function buildAuthorizationString($strSignature) {
952
        return $this->HMACAlgorithm . " " . "Credential=" . $this->accessKey . "/" . $this->getDate() . "/" . $this->regionName . "/" . $this->serviceName . "/" . $this->aws4Request . "," . "SignedHeaders=" . $this->strSignedHeader . "," . "Signature=" . $strSignature;
953
    }
954
 
955
    private function generateHex($data) {
956
        return strtolower(bin2hex(hash("sha256", $data, true)));
957
    }
958
 
959
    private function getSignatureKey($key, $date, $regionName, $serviceName) {
960
        $kSecret = "AWS4" . $key;
961
        $kDate = hash_hmac("sha256", $date, $kSecret, true);
962
        $kRegion = hash_hmac("sha256", $regionName, $kDate, true);
963
        $kService = hash_hmac("sha256", $serviceName, $kRegion, true);
964
        $kSigning = hash_hmac("sha256", $this->aws4Request, $kService, true);
965
 
966
        return $kSigning;
967
    }
968
 
969
    private function getTimeStamp() {
970
        return gmdate("Ymd\THis\Z");
971
    }
972
 
973
    private function getDate() {
974
        return gmdate("Ymd");
975
    }
976
}