Subversion Repositories cheapmusic

Rev

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