Subversion Repositories cheapmusic

Rev

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

Rev Author Line No. Line
1 - 1
<?php
93 - 2
use Fuse\Fuse;
65 - 3
include_once ('php/clsLibGTIN.php');
4
include_once ('php/exchangeRates.php');
5
include_once ('php/countryCodes.php');
6
include_once ('php/constants.php');
7
include_once ('php/ebay.php');
8
include_once ('php/discogs.php');
9
include_once ('php/linkshare.php');
10
include_once ('php/cjaffiliate.php');
11
include_once ('php/walmart.php');
12
include_once ('php/itunes.php');
81 - 13
include_once ('php/amazon.php');
91 - 14
include_once ('php/amazon_scrape.php');
83 - 15
include_once ('php/impact.php');
99 - 16
include_once ('php/sessions_db.php');
116 - 17
include_once ('php/media.php');
1 - 18
 
20 - 19
error_reporting(E_ALL);
20
 
107 - 21
// meta description
22
function metaDescription($page) {
23
    switch ($page) {
24
        case "terms":
25
            $metaText = "By visiting our site and/or purchasing something from us, you engage in our Service and agree to be bound by these terms and conditions.";
26
            break;
27
 
28
        case "privacy":
29
            $metaText = "In our User Privacy Notice, we have compiled all essential information about our handling of your personal data and your corresponding rights for you.";
30
            break;
31
 
32
        case "help":
33
            $metaText = "The help page explains the basic functionality of the search page with its various sections of supporting information.";
34
            break;
35
 
36
        case "wishlist":
37
            $metaText = "Maintain a wishlist at FindCheapMusic to keep track of your favorite music albums or to receive price drop alerts right to your email. Free login required.";
38
            break;
39
 
40
        case "coupons":
41
            $metaText = "Weekly updated coupons and special offers from various music online stores. When they are gone, they are gone. Free login required.";
42
            break;
43
 
44
        case "priceMonitor":
45
            $metaText = "Explore your personal price monitor results. Results will be updated at user-defined intervals and published via email. Free login required.";
46
            break;
47
 
48
        case "random":
49
            $metaText = "See several completely random music album suggestions.";
50
            break;
51
 
52
        default:
53
            $metaText = "Search dozens of online stores at once for low-priced or hard to find Compact Discs, Vinyl Records, MP3s, Music Sheets and Music related books.";
54
            break;
55
    }
56
 
57
    return ('<meta name="description" content="' . $metaText . '">');
58
}
59
 
65 - 60
// search
5 - 61
function performSearch() {
14 - 62
    $currentMd5SearchTerm = md5SearchTerm();
116 - 63
    if (isset($_SESSION['md5LastSearch']) && $currentMd5SearchTerm == $_SESSION['md5LastSearch']) {
14 - 64
        return;
65
    }
66
    $_SESSION['md5LastSearch'] = $currentMd5SearchTerm;
67
 
81 - 68
    $_SESSION["barcode"]["Type"] = clsLibGTIN::GTINCheck($_SESSION["searchTerm"], false, 1);
69
    $_SESSION["barcode"]["Value"] = clsLibGTIN::GTINCheck($_SESSION["searchTerm"]);
70
 
22 - 71
    updatePbFile(true);
72
 
107 - 73
    getGeoLocation();
74
 
75
    updatePbFile(true);
76
 
81 - 77
    findDiscogsMaster($_SESSION["searchTerm"]);
78
    updatePbFile();
79
 
65 - 80
    $_SESSION["currentLayout"] = 'TableView';
81
    $_SESSION["resultArr"] = [];
99 - 82
    expireSearchCache();
65 - 83
    $_SESSION["resultArr"] = searchAll($_SESSION["searchTerm"]);
93 - 84
 
99 - 85
    verifyResultArr();
93 - 86
 
22 - 87
    updatePbFile();
23 - 88
 
65 - 89
    $_SESSION["resultArr"] = applySearchFilter($_SESSION["resultArr"]);
22 - 90
    updatePbFile();
5 - 91
 
65 - 92
    //echo "<pre>";print_r($_SESSION["resultArr"]);echo "</pre>";
66 - 93
    $_SESSION["lowestPrice"]["Used"] = findLowestCondition("Used");
94
    $_SESSION["lowestPrice"]["New"] = findLowestCondition("New");
95
    $_SESSION["lowestPrice"]["CD"] = findLowestMediaType("CD");
96
    $_SESSION["lowestPrice"]["Record"] = findLowestMediaType("Record");
97
    $_SESSION["lowestPrice"]["Digital"] = findLowestMediaType("Digital");
98
    $_SESSION["lowestPrice"]["Book"] = findLowestMediaType("Book");
65 - 99
    $_SESSION["lowestPrice"]["All"] = 0.00;
100
    if (array_sum($_SESSION["lowestPrice"]) > 0) {
101
        $_SESSION["lowestPrice"]["All"] = minNotNull($_SESSION["lowestPrice"]);
102
    }
22 - 103
    updatePbFile();
13 - 104
 
65 - 105
    saveSearchResult();
22 - 106
    updatePbFile();
5 - 107
}
108
 
9 - 109
function resetSessionVars() {
110
    $_SESSION["searchTerm"] = '';
46 - 111
    $_SESSION["discogsTitle"] = '';
112
    $_SESSION["discogsArtist"] = '';
14 - 113
    $_SESSION['md5LastSearch'] = '';
65 - 114
    $_SESSION["currentLayout"] = 'TableView';
115
    $_SESSION["barcode"]["Type"] = '';
116
    $_SESSION["barcode"]["Value"] = '';
9 - 117
 
65 - 118
    $_SESSION["resultArr"] = [];
9 - 119
 
65 - 120
    $_SESSION["lowestPrice"]["Used"] = 0.00;
121
    $_SESSION["lowestPrice"]["New"] = 0.00;
122
    $_SESSION["lowestPrice"]["CD"] = 0.00;
123
    $_SESSION["lowestPrice"]["Record"] = 0.00;
124
    $_SESSION["lowestPrice"]["Digital"] = 0.00;
125
    $_SESSION["lowestPrice"]["Book"] = 0.00;
126
    $_SESSION["lowestPrice"]["All"] = 0.00;
9 - 127
}
128
 
65 - 129
// search for items on all sites
72 - 130
function searchAll($searchKey, $batchFlag = false) {
65 - 131
    $arr = [];
132
    if ($_SESSION["filterCondition"]["New"]) {
133
        $arr = get_vendor($arr, 'get_ebay', $searchKey, constant("NEW"));
134
    }
72 - 135
    if (!$batchFlag) { updatePbFile(); }
65 - 136
    if ($_SESSION["filterCondition"]["New"]) {
137
        $arr = get_vendor($arr, 'get_linkshare', $searchKey, constant("NEW"));
138
    }
72 - 139
    if (!$batchFlag) { updatePbFile(); }
65 - 140
    if ($_SESSION["filterCondition"]["New"]) {
141
        $arr = get_vendor($arr, 'get_cjaffiliate', $searchKey, constant("NEW"));
142
    }
72 - 143
    if (!$batchFlag) { updatePbFile(); }
65 - 144
    if ($_SESSION["filterCondition"]["New"]) {
145
        $arr = get_vendor($arr, 'get_walmart', $searchKey, constant("NEW"));
146
    }
72 - 147
    if (!$batchFlag) { updatePbFile(); }
65 - 148
    if ($_SESSION["filterCondition"]["New"]) {
149
        $arr = get_vendor($arr, 'get_itunes', $searchKey, constant("NEW"));
150
    }
72 - 151
    if (!$batchFlag) { updatePbFile(); }
17 - 152
 
91 - 153
    $cntArr = count($arr);
81 - 154
    $arr = get_vendor($arr, 'get_amazon', $searchKey, constant("NEW"));
91 - 155
    if ($cntArr == count($arr)) {
156
        $arr = get_vendor($arr, 'get_amazon_scrape', $searchKey, constant("NEW"));
157
    }
81 - 158
    if (!$batchFlag) { updatePbFile(); }
159
 
83 - 160
    $arr = get_vendor($arr, 'get_impact', $searchKey, constant("NEW"));
161
    if (!$batchFlag) { updatePbFile(); }
162
 
65 - 163
    if ($_SESSION["filterCondition"]["Used"]) {
164
        $arr = get_vendor($arr, 'get_ebay', $searchKey, constant("USED"));
165
    }
72 - 166
    if (!$batchFlag) { updatePbFile(); }
17 - 167
 
66 - 168
//echo "<pre>";print_r($arr);echo "</pre";
24 - 169
 
65 - 170
    $arr = applyExchangeRates($arr);
171
    usort($arr, 'compare_price');
72 - 172
    if (!$batchFlag) { updatePbFile(); }
5 - 173
 
65 - 174
    return $arr;
5 - 175
}
176
 
20 - 177
// Search and merge
178
function get_vendor($arr, $func, $searchKey, $condition) {
65 - 179
    $arrTemp = $func($searchKey, $condition);
20 - 180
    return array_merge($arrTemp, $arr);
181
}
182
 
21 - 183
// delete results from array that do not match the search filters
184
function applySearchFilter($arr) {
66 - 185
    unset($_SESSION['AdditionalFilterCounters']);
186
    unset($_SESSION['AdditionalFilters']);
65 - 187
    foreach ($arr as $key => $row) {
66 - 188
        if (!$_SESSION["filterMediaType"][$row["MediaType"]] || !$_SESSION["filterCondition"][$row["Condition"]]) {
21 - 189
            unset($arr[$key]);
66 - 190
        } else {
191
            if (isset($_SESSION['AdditionalFilterCounters']['Condition']['All'])) {
192
                $_SESSION['AdditionalFilterCounters']['Condition']['All']++;
193
            } else {
194
                $_SESSION['AdditionalFilterCounters']['Condition']['All'] = 1;
195
            }
196
 
197
            if (isset($_SESSION['AdditionalFilterCounters']['Merchant'][$row['Merchant']])) {
198
                $_SESSION['AdditionalFilterCounters']['Merchant'][$row['Merchant']]++;
199
            } else {
200
                $_SESSION['AdditionalFilterCounters']['Merchant'][$row['Merchant']] = 1;
201
                $_SESSION['AdditionalFilters']['Merchant'][$row['Merchant']] = true;
202
            }
203
 
204
            if (!empty($row['SellerName'])) {
205
                if (isset($_SESSION['AdditionalFilterCounters']['Seller'][$row['SellerName']])) {
206
                    $_SESSION['AdditionalFilterCounters']['Seller'][$row['SellerName']]++;
207
                } else {
208
                    $_SESSION['AdditionalFilterCounters']['Seller'][$row['SellerName']] = 1;
209
                    $_SESSION['AdditionalFilters']['Seller'][$row['SellerName']] = true;
210
                }
211
            }
212
 
213
            if (isset($_SESSION['AdditionalFilterCounters']['Condition'][$row['Condition']])) {
214
                $_SESSION['AdditionalFilterCounters']['Condition'][$row['Condition']]++;
215
            } else {
216
                $_SESSION['AdditionalFilterCounters']['Condition'][$row['Condition']] = 1;
217
                $_SESSION['AdditionalFilters']['Condition'][$row['Condition']] = true;
218
            }
219
 
220
            if (isset($_SESSION['AdditionalFilterCounters']['MediaType'][$row['MediaType']])) {
221
                $_SESSION['AdditionalFilterCounters']['MediaType'][$row['MediaType']]++;
222
            } else {
223
                $_SESSION['AdditionalFilterCounters']['MediaType'][$row['MediaType']] = 1;
224
                $_SESSION['AdditionalFilters']['MediaType'][$row['MediaType']] = true;
225
            }
226
 
227
            if (isset($_SESSION['AdditionalFilterCounters']['DetailCondition'][$row['DetailCondition']])) {
228
                $_SESSION['AdditionalFilterCounters']['DetailCondition'][$row['DetailCondition']]++;
229
            } else {
230
                $_SESSION['AdditionalFilterCounters']['DetailCondition'][$row['DetailCondition']] = 1;
231
                $_SESSION['AdditionalFilters']['DetailCondition'][$row['DetailCondition']] = true;
232
            }
233
 
234
            if (isset($_SESSION['AdditionalFilterCounters']['ShippingFrom'][$row['Country']])) {
235
                $_SESSION['AdditionalFilterCounters']['ShippingFrom'][$row['Country']]++;
236
            } else {
237
                $_SESSION['AdditionalFilterCounters']['ShippingFrom'][$row['Country']] = 1;
238
                $_SESSION['AdditionalFilters']['ShippingFrom'][$row['Country']] = true;
239
            }
65 - 240
        }
241
    }
23 - 242
 
66 - 243
    if (isset($_SESSION['AdditionalFilters']['Merchant'])) {
244
        ksort($_SESSION['AdditionalFilters']['Merchant'], SORT_NATURAL | SORT_FLAG_CASE);
245
    }
246
 
247
    if (isset($_SESSION['AdditionalFilters']['Seller'])) {
248
        ksort($_SESSION['AdditionalFilters']['Seller'], SORT_NATURAL | SORT_FLAG_CASE);
249
    }
250
 
251
    if (isset($_SESSION['AdditionalFilters']['Condition'])) {
252
        ksort($_SESSION['AdditionalFilters']['Condition'], SORT_NATURAL | SORT_FLAG_CASE);
253
    }
254
 
255
    if (isset($_SESSION['AdditionalFilters']['DetailCondition'])) {
256
        ksort($_SESSION['AdditionalFilters']['DetailCondition'], SORT_NATURAL | SORT_FLAG_CASE);
257
    }
258
 
259
    if (isset($_SESSION['AdditionalFilters']['ShippingFrom'])) {
260
        ksort($_SESSION['AdditionalFilters']['ShippingFrom'], SORT_NATURAL | SORT_FLAG_CASE);
261
    }
262
 
263
    if (isset($_SESSION['AdditionalFilters']['MediaType'])) {
264
        ksort($_SESSION['AdditionalFilters']['MediaType'], SORT_NATURAL | SORT_FLAG_CASE);
265
    }
266
 
21 - 267
    return $arr;
268
}
269
 
66 - 270
// filter view result table $_SESSION["resultArr"] for detailed filter selection
271
function detailFilterResults($selArr) {
67 - 272
    if (!empty($selArr['filterCondition'])) {
273
        foreach($_SESSION['AdditionalFilters']['Condition'] as $key => $value) {
274
            $_SESSION['AdditionalFilters']['Condition'][$key] = false;
275
        }
276
        if (!is_array($selArr['filterCondition'])) { $selArr['filterCondition'] = [ $selArr['filterCondition'] ];}
277
        foreach($selArr['filterCondition'] as $value) {
278
            $_SESSION['AdditionalFilters']['Condition'][$value] = true;
279
        }
280
    } else {
68 - 281
        $selArr['filterCondition'] = [];
77 - 282
        if (!empty($_SESSION['AdditionalFilters']['Condition'])) {
283
            foreach($_SESSION['AdditionalFilters']['Condition'] as $key => $value) {
284
                if ($value) {
285
                    $selArr['filterCondition'][] = $key;
286
                }
68 - 287
            }
288
        }
66 - 289
    }
290
 
67 - 291
    if (!empty($selArr['filterMediaType'])) {
292
        foreach($_SESSION['AdditionalFilters']['MediaType'] as $key => $value) {
293
            $_SESSION['AdditionalFilters']['MediaType'][$key] = false;
294
        }
295
        if (!is_array($selArr['filterMediaType'])) { $selArr['filterMediaType'] = [ $selArr['filterMediaType'] ];}
296
        foreach($selArr['filterMediaType'] as $value) {
297
            $_SESSION['AdditionalFilters']['MediaType'][$value] = true;
298
        }
299
    } else {
68 - 300
        $selArr['filterMediaType'] = [];
77 - 301
        if (!empty($_SESSION['AdditionalFilters']['MediaType'])) {
302
            foreach($_SESSION['AdditionalFilters']['MediaType'] as $key => $value) {
303
                if ($value) {
304
                    $selArr['filterMediaType'][] = $key;
305
                }
68 - 306
            }
307
        }
66 - 308
    }
309
 
67 - 310
    if (!empty($selArr['filterShipFrom'])) {
311
        foreach($_SESSION['AdditionalFilters']['ShippingFrom'] as $key => $value) {
312
            $_SESSION['AdditionalFilters']['ShippingFrom'][$key] = false;
313
        }
314
        if (!is_array($selArr['filterShipFrom'])) { $selArr['filterShipFrom'] = [ $selArr['filterShipFrom'] ];}
315
        foreach($selArr['filterShipFrom'] as $value) {
316
            $_SESSION['AdditionalFilters']['ShippingFrom'][$value] = true;
317
        }
318
    } else {
68 - 319
        $selArr['filterShipFrom'] = [];
77 - 320
        if (!empty($_SESSION['AdditionalFilters']['ShippingFrom'])) {
321
            foreach($_SESSION['AdditionalFilters']['ShippingFrom'] as $key => $value) {
322
                if ($value) {
323
                    $selArr['filterShipFrom'][] = $key;
324
                }
68 - 325
            }
326
        }
66 - 327
    }
328
 
67 - 329
    if (!empty($selArr['filterMerchant'])) {
330
        foreach($_SESSION['AdditionalFilters']['Merchant'] as $key => $value) {
331
            $_SESSION['AdditionalFilters']['Merchant'][$key] = false;
332
        }
333
        if (!is_array($selArr['filterMerchant'])) { $selArr['filterMerchant'] = [ $selArr['filterMerchant'] ];}
334
        foreach($selArr['filterMerchant'] as $value) {
335
            $_SESSION['AdditionalFilters']['Merchant'][$value] = true;
336
        }
337
    } else {
68 - 338
        $selArr['filterMerchant'] = [];
77 - 339
        if (!empty($_SESSION['AdditionalFilters']['Merchant'])) {
340
            foreach($_SESSION['AdditionalFilters']['Merchant'] as $key => $value) {
341
                if ($value) {
342
                    $selArr['filterMerchant'][] = $key;
343
                }
68 - 344
            }
345
        }
66 - 346
    }
347
 
348
    foreach ($_SESSION["resultArr"] as & $row) {
349
        $row["Show"] = true;
350
 
351
        if (!in_array($row["Condition"], $selArr['filterCondition']) ||
352
            !in_array($row["MediaType"], $selArr['filterMediaType']) ||
353
            !in_array($row["Merchant"], $selArr['filterMerchant']) ||
354
            !in_array($row["Country"], $selArr['filterShipFrom'])) {
355
            $row["Show"] = false;
356
        }
357
    }
358
}
359
 
360
function resetDetailFilter() {
361
    if (isset($_SESSION['AdditionalFilters']['Merchant'])) {
362
        foreach($_SESSION['AdditionalFilters']['Merchant'] as $key => $field) {
363
            $_SESSION['AdditionalFilters']['Merchant'][$key] = true;
364
        }
365
    }
366
 
367
    if (isset($_SESSION['AdditionalFilters']['Seller'])) {
368
        foreach($_SESSION['AdditionalFilters']['Seller'] as $key => $field) {
369
            $_SESSION['AdditionalFilters']['Seller'][$key] = true;
370
        }
371
    }
372
 
373
    if (isset($_SESSION['AdditionalFilters']['Condition'])) {
374
        foreach($_SESSION['AdditionalFilters']['Condition'] as $key => $field) {
375
            $_SESSION['AdditionalFilters']['Condition'][$key] = true;
376
        }
377
    }
378
 
379
    if (isset($_SESSION['AdditionalFilters']['DetailCondition'])) {
380
        foreach($_SESSION['AdditionalFilters']['DetailCondition'] as $key => $field) {
381
            $_SESSION['AdditionalFilters']['DetailCondition'][$key] = true;
382
        }
383
    }
384
 
385
    if (isset($_SESSION['AdditionalFilters']['ShippingFrom'])) {
386
        foreach($_SESSION['AdditionalFilters']['ShippingFrom'] as $key => $field) {
387
            $_SESSION['AdditionalFilters']['ShippingFrom'][$key] = true;
388
        }
389
    }
390
 
391
    if (isset($_SESSION['AdditionalFilters']['MediaType'])) {
392
        foreach($_SESSION['AdditionalFilters']['MediaType'] as $key => $field) {
393
            $_SESSION['AdditionalFilters']['MediaType'][$key] = true;
394
        }
395
    }
107 - 396
 
66 - 397
    foreach ($_SESSION["resultArr"] as & $row) {
398
        $row["Show"] = true;
399
    }
400
}
401
 
65 - 402
// print result table or card deck
59 - 403
function printResult() {
404
    if ($_SESSION["currentLayout"] == 'TableView') {
78 - 405
        return buildTable($_SESSION["resultArr"]);
65 - 406
    }
407
    else /* CardView */ {
78 - 408
        return buildCardDeck($_SESSION["resultArr"]);
59 - 409
    }
410
}
411
 
65 - 412
// build HTML table from array
78 - 413
function buildTable($arr) {
86 - 414
    global $buyItNowTooltip;
121 - 415
 
59 - 416
    $str = "";
120 - 417
    $cnt = 0;
1 - 418
 
78 - 419
    if (count($arr) > 0) {
81 - 420
        $str .= "<div class=\"table\">"; // bugbug responsive?
68 - 421
        $str .= "<table class=\"table table-striped table-condensed table-hover small bg-info\">";
81 - 422
        $str .= "<thead class=\"thead-dark table-header-sticky\"><tr><th>Image</th><th class=\"text-left\">Title / Merchant</th><th>Condition</th><th class=\"hide-small\">Price</th><th class=\"hide-small\">S/H</th><th>Total</th><th class=\"hide-extra-small\"></th></tr></thead>";
65 - 423
        $str .= "<tbody>";
17 - 424
 
78 - 425
        foreach ($arr as $row) {
65 - 426
            if (!$row["Show"]) {
427
                continue;
428
            }
1 - 429
 
120 - 430
            ++$cnt;
121 - 431
            $cntStr = (!empty($_SESSION["prefix"]) ? $_SESSION["prefix"] . '-' : '') . $cnt;
120 - 432
            $href = "href=\"" . htmlentities($row["URL"]) . "\" target=\"_blank\" rel=\"nofollow noreferrer noopener\"";
59 - 433
            $title = $row["Title"];
434
            if (mb_strlen($row["Title"], 'UTF-8') > MAXTITLELENGTH) {
65 - 435
                $title = mb_substr($row["Title"], 0, MAXTITLELENGTH, 'UTF-8') . '...';
59 - 436
            }
5 - 437
 
65 - 438
            $str .= "<tr>";
13 - 439
 
9 - 440
            // Image
121 - 441
            $str .= "<td><a id=\"image" . $cntStr . "Save\" " . $href . " data-toggle=\"tooltip\" title=\"" . $buyItNowTooltip . "\"><img class=\"img-fluid lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . htmlentities($row["Image"]) . "\" alt=\"Item Image\" /></a></td>";
1 - 442
 
9 - 443
            // Title / Merchant
121 - 444
            $str .= "<td class=\"text-left\"><span class=\"font-weight-bold\"><a id=\"title" . $cntStr . "Save\" class=\"bg-info\" " . $href . " data-toggle=\"tooltip\" title=\"" . $buyItNowTooltip . "\">" . $title . "</a></span>";
58 - 445
            $str .= "<br/><br/>";
65 - 446
            $str .= "<span class=\"font-weight-bold\">" . $row["Merchant"] . "</span>";
447
            if ($row["FeedbackScore"] != - 1) {
448
                $str .= "<span class=\"hide-extra-small\"><br/>" . $row["SellerName"] . " (" . number_format($row["FeedbackScore"], 0, "", ",") . " / " . $row["FeedbackPercent"] . "%)</span>";
449
            }
450
            else if (!empty($row["SellerName"])) {
451
                $str .= "<span class=\"hide-extra-small\"><br/>" . $row["SellerName"] . "</span>";
452
            }
453
            if (!empty($row["TimeLeft"])) {
24 - 454
                $str .= "<br>" . $row["TimeLeft"];
65 - 455
            }
456
            $str .= "</td>";
1 - 457
 
9 - 458
            // Condition
65 - 459
            $str .= "<td>";
66 - 460
            $str .= "<span class=\"font-weight-bold\">" . $row["DetailCondition"] . "</span>";
65 - 461
            $str .= "<br/><br/>";
116 - 462
            $str .= "<i class=\"" . getMediaIconClass($row["MediaType"], "media-icon") . "\" title=\"" . getMediaIconText($row["MediaType"]) . "\" data-toggle=\"tooltip\" data-placement=\"right\" data-delay=\"200\">" . getMediaIconAlias($row["MediaType"]) . "</i>";
65 - 463
            $str .= "</td>";
5 - 464
 
9 - 465
            // Price
65 - 466
            $str .= "<td class=\"hide-small\">" . print_monetary($row["Price"], $row["Currency"]);
467
            if ($row["Currency"] != $_SESSION["buyer"]["Currency"]) {
468
                $str .= "<br/>&asymp; " . print_monetary($row["ConvertedPrice"], $_SESSION["buyer"]["Currency"]);
469
            }
470
            if ($row["BestOffer"] == "true") {
471
                $str .= "<br>Best Offer Accepted";
472
            }
473
            $str .= "</td>";
1 - 474
 
9 - 475
            // Shipping and Handling Cost
65 - 476
            $str .= "<td class=\"hide-small\">";
477
            if ($row["ShippingCost"] == 0.00) {
478
                $str .= "Free Shipping";
479
            }
480
            else {
481
                $str .= print_monetary($row["ShippingCost"], $row["ShippingCurrency"]);
81 - 482
                if ($row["ShippingEstimated"]) {
483
                    $str .= "*";
484
                }
65 - 485
            }
486
            if ($row["ShippingCost"] > 0.00 && $row["ShippingCurrency"] != $_SESSION["buyer"]["Currency"]) {
487
                $str .= "<br/>&asymp; " . print_monetary($row["ConvertedShippingCost"], $_SESSION["buyer"]["Currency"]);
488
            }
24 - 489
            if ($row["HandlingTime"] > 0) {
490
                $str .= "<br>Handling Time " . $row["HandlingTime"] . " day" . ($row["HandlingTime"] > 1 ? "s" : "");
491
            }
492
            if ($row["ShippingCost"] > 0.00 && $row["FreeShippingCap"] > 0) {
493
                $str .= "<br>Free Shipping over " . print_monetary($row["FreeShippingCap"], $_SESSION["buyer"]["Currency"]);
494
            }
116 - 495
            $str .= "<br/><img class=\"img-fluid lazyload\" title=\"Ships from " . getCountry($row["Country"]) . "\" data-toggle=\"tooltip\" data-placement=\"right\" data-delay=\"200\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . timeStampUrl("images/flags/" . $row["Country"] . ".png") . "\" alt=\"" . getCountry($row["Country"]) . " Flag\" /></td>";
1 - 496
 
9 - 497
            // Total Price
65 - 498
            $str .= "<td class=\"font-weight-bolder\">" . print_monetary($row["ConvertedTotalPrice"], $_SESSION["buyer"]["Currency"]) . "</td>";
1 - 499
 
9 - 500
            // Link
121 - 501
            $linkId = ' id="link' . $cntStr . 'Save"';
54 - 502
            if ($row["Merchant"] == "iTunes") {
66 - 503
                if ($row["MediaType"] == "Digital") {
108 - 504
                    $badge = timeStampUrl("images/US-UK_Apple_Music_Badge_RGB.svg");
65 - 505
                }
506
                else {
108 - 507
                    $badge = timeStampUrl("images/US_UK_Apple_Books_Badge_Get_RGB_071818.svg");
54 - 508
                }
120 - 509
                $linkImage = "<a ". $linkId . " class=\"btn\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><img class=\"lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . $badge . "\" alt=\"iTunes Badge\" /></a>";
81 - 510
            } else if (strpos($row["Merchant"], "eBay") !== false) {
120 - 511
                $linkImage = "<a ". $linkId . " class=\"btn\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><img class=\"lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . timeStampUrl("images/ebay-right-now.gif") . "\" alt=\"iTunes Badge\" /></a>";
81 - 512
            } else if (strpos($row["Merchant"], "Amazon") !== false) {
120 - 513
                $linkImage = "<a ". $linkId . " class=\"btn\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><img class=\"lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . timeStampUrl("images/amazon-buy3.gif") . "\" alt=\"iTunes Badge\" /></a>";
81 - 514
            } else {
120 - 515
                $linkImage = "<a ". $linkId . " class=\"btn btn-danger\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><i class=\"material-icons md-36\">store</i></a>";
54 - 516
            }
65 - 517
            $str .= "<td class=\"hide-extra-small text-center\">" . $linkImage . "</td>";
1 - 518
 
65 - 519
            $str .= "</tr>";
120 - 520
 
521
            $str .= '<script nonce="' . base64_encode($_SESSION["nonce"]) . '">';
522
            $str .= 'document.addEventListener("DOMContentLoaded", function() {';
121 - 523
            $str .= '	document.getElementById("image' . $cntStr . 'Save").addEventListener("click", function() {';
120 - 524
            $str .= '        saveTransfer("' . $row["URL"] . '");';
525
            $str .= '	});';
121 - 526
            $str .= '	document.getElementById("title' . $cntStr . 'Save").addEventListener("click", function() {';
120 - 527
            $str .= '        saveTransfer("' . $row["URL"] . '");';
528
            $str .= '	});';
121 - 529
            $str .= '	document.getElementById("link' . $cntStr . 'Save").addEventListener("click", function() {';
120 - 530
            $str .= '        saveTransfer("' . $row["URL"] . '");';
531
            $str .= '	});';
532
            $str .= '});';
533
            $str .= '</script>';
9 - 534
        }
17 - 535
 
65 - 536
        $str .= "</tbody>";
537
        $str .= "<tfoot class=\"text-right\"><tr><td class=\"font-italic\" colspan=\"7\">Prices retrieved on " . gmdate("Y-m-d H:i") . " UTC<br>Daily exchange rates update</td></tr></tfoot>";
538
        $str .= "</table>";
539
        $str .= "</div>";
540
    }
541
    else {
59 - 542
        $str = printNoResultsWarning();
9 - 543
    }
1 - 544
 
65 - 545
    return ($str);
59 - 546
}
1 - 547
 
65 - 548
// build HTML card deck from array
78 - 549
function buildCardDeck($arr) {
86 - 550
    global $buyItNowTooltip;
66 - 551
 
65 - 552
    $str = "";
120 - 553
    $cnt = 0;
59 - 554
 
78 - 555
    if (count($arr) > 0) {
61 - 556
        $str .= "<div class=\"card-deck small\">";
59 - 557
 
78 - 558
        foreach ($arr as $row) {
65 - 559
            if (!$row["Show"]) {
560
                continue;
561
            }
59 - 562
 
120 - 563
            ++$cnt;
121 - 564
            $cntStr = (!empty($_SESSION["prefix"]) ? $_SESSION["prefix"] . '-' : '') . $cnt;
120 - 565
            $href = "href=\"" . htmlentities($row["URL"]) . "\" target=\"_blank\" rel=\"nofollow noreferrer noopener\"";
59 - 566
            $title = $row["Title"];
567
            if (mb_strlen($row["Title"], 'UTF-8') > MAXTITLELENGTH) {
65 - 568
                $title = mb_substr($row["Title"], 0, MAXTITLELENGTH, 'UTF-8') . '...';
59 - 569
            }
570
 
65 - 571
            $str .= "<div class=\"card m-2 shadow mx-auto result-card\">";
59 - 572
 
573
            // Image
121 - 574
            $str .= "<a id=\"image" . $cntStr . "Save\" class=\"p-0 m-0 bg-light text-center result-image\" " . $href . " data-toggle=\"tooltip\" title=\"" . $buyItNowTooltip . "\"><img class=\"p-0 m-0 responsive-image lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . htmlentities($row["Image"]) . "\" alt=\"Item Image\" /></a>";
59 - 575
 
65 - 576
            $str .= "<div class=\"card-body bg-light d-flex flex-column\">";
59 - 577
            // Title / Merchant
121 - 578
            $str .= "<p class=\"card-title font-weight-bold\"><a id=\"title" . $cntStr . "Save\" " . $href . " data-toggle=\"tooltip\" title=\"" . $buyItNowTooltip . "\">" . $title . "</a></p>";
65 - 579
            $str .= "<div class=\"card-text mt-auto\"><span class=\"font-weight-bold\">" . $row["Merchant"] . "</span>";
580
            $str .= "<br>";
59 - 581
 
66 - 582
            // Condition / MediaType
583
            $str .= $row["DetailCondition"];
116 - 584
            $str .= "<i class=\"" . getMediaIconClass($row["MediaType"], "media-icon float-right") . "\" title=\"" . getMediaIconText($row["MediaType"]) . "\" data-toggle=\"tooltip\" data-placement=\"right\" data-delay=\"200\">" . getMediaIconAlias($row["MediaType"]) . "</i>";
65 - 585
            $str .= "<br>";
59 - 586
 
587
            // Total Price
65 - 588
            $str .= "<span class=\"font-weight-bolder\">" . print_monetary($row["ConvertedTotalPrice"], $_SESSION["buyer"]["Currency"]) . "</span>";
60 - 589
            $str .= "</div>";
59 - 590
 
591
            $str .= "</div>";
592
 
593
            // Link / Ships from Flag
121 - 594
            $linkId = ' id="link' . $cntStr . 'Save"';
64 - 595
            $str .= "<div class=\"card-footer bg-dark\">";
60 - 596
            $str .= "<div class=\"row\">";
65 - 597
            $str .= "<div class=\"col-9\">";
59 - 598
            if ($row["Merchant"] == "iTunes") {
66 - 599
                if ($row["MediaType"] == "Digital") {
108 - 600
                    $badge = timeStampUrl("images/US-UK_Apple_Music_Badge_RGB.svg");
65 - 601
                }
602
                else {
108 - 603
                    $badge = timeStampUrl("images/US_UK_Apple_Books_Badge_Get_RGB_071818.svg");
59 - 604
                }
120 - 605
                $linkImage = "<a ". $linkId . " class=\"btn p-0 m-0\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><img class=\"img-fluid p-0 m-0 lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . $badge . "\" alt=\"iTunes Badge\" /></a>";
81 - 606
            } else if (strpos($row["Merchant"], "eBay") !== false) {
120 - 607
                $linkImage = "<a ". $linkId . " class=\"btn p-0 m-0\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><img class=\"img-fluid p-0 m-0 lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . timeStampUrl("images/ebay-right-now.gif") . "\" alt=\"iTunes Badge\" /></a>";
81 - 608
            } else if (strpos($row["Merchant"], "Amazon") !== false) {
120 - 609
                $linkImage = "<a ". $linkId . " class=\"btn p-0 m-0\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><img class=\"img-fluid p-0 m-0 lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . timeStampUrl("images/amazon-buy3.gif") . "\" alt=\"iTunes Badge\" /></a>";
65 - 610
            }
611
            else {
120 - 612
                $linkImage = "<a ". $linkId . " class=\"btn btn-danger m-0\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><i class=\"material-icons md-24\">store</i></a>";
59 - 613
            }
65 - 614
            $str .= $linkImage;
59 - 615
            $str .= "</div>";
65 - 616
            $str .= "<div class=\"col-3\">";
116 - 617
            $str .= "<img class=\"float-right lazyload\" title=\"Ships from " . getCountry($row["Country"]) . "\" data-toggle=\"tooltip\" data-placement=\"right\" data-delay=\"200\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . timeStampUrl("images/flags/" . $row["Country"] . ".png") . "\" alt=\"" . getCountry($row["Country"]) . " Flag\" />";
60 - 618
            $str .= "</div>";
65 - 619
            $str .= "</div>";
620
            $str .= "</div>";
59 - 621
 
65 - 622
            $str .= "</div>";
120 - 623
 
624
            $str .= '<script nonce="' . base64_encode($_SESSION["nonce"]) . '">';
625
            $str .= 'document.addEventListener("DOMContentLoaded", function() {';
121 - 626
            $str .= '	document.getElementById("image' . $cntStr . 'Save").addEventListener("click", function() {';
120 - 627
            $str .= '        saveTransfer("' . $row["URL"] . '");';
628
            $str .= '	});';
121 - 629
            $str .= '	document.getElementById("title' . $cntStr . 'Save").addEventListener("click", function() {';
120 - 630
            $str .= '        saveTransfer("' . $row["URL"] . '");';
631
            $str .= '	});';
121 - 632
            $str .= '	document.getElementById("link' . $cntStr . 'Save").addEventListener("click", function() {';
120 - 633
            $str .= '        saveTransfer("' . $row["URL"] . '");';
634
            $str .= '	});';
635
            $str .= '});';
636
            $str .= '</script>';
59 - 637
        }
638
 
65 - 639
        $str .= "</div>";
640
        $str .= "<div class=\"py-2 text-right\"><p class=\"font-italic\">Prices retrieved on " . gmdate("Y-m-d H:i") . " UTC<br>Daily exchange rates update</p></div>";
641
    }
642
    else {
59 - 643
        $str = printNoResultsWarning();
644
    }
645
 
65 - 646
    return ($str);
5 - 647
}
648
 
65 - 649
// print directions when no results are found
59 - 650
function printNoResultsWarning() {
651
    $str = "<div class=\"text-center bg-warning p-3 rounded\">";
104 - 652
    $str .= "<p class=\"display-5 font-weight-bold\">Your search returned no store offers</p>";
59 - 653
    $str .= "<p>You may want to try the following:</p>";
114 - 654
    $str .= "<ul><li>Check the spelling</li><li>Try using fewer words</li><li>Try using artist and title if you used a barcode; some albums have been released under various barcodes</li></ul>";
59 - 655
    $str .= "</div>";
656
 
657
    return $str;
658
}
659
 
66 - 660
function printResultHeader() {
661
    $str = '';
662
    $str .= '<nav class="navbar bg-black mt-2 pb-0">';
113 - 663
    $str .= '<span class="mr-3">';
664
    if ($_SESSION["lowestPrice"]["New"] > 0) {
665
        $str .= 'New from ' . print_monetary($_SESSION["lowestPrice"]["New"], $_SESSION["buyer"]["Currency"]);
666
    }
667
    if ($_SESSION["lowestPrice"]["New"] > 0 && $_SESSION["lowestPrice"]["Used"] > 0) {
668
        $str .= '<br>';
669
    }
670
    if ($_SESSION["lowestPrice"]["Used"] > 0) {
671
        $str .= 'Used from ' . print_monetary($_SESSION["lowestPrice"]["Used"], $_SESSION["buyer"]["Currency"]);
672
    }
673
    $str .= '</span>';
674
    $str .= '<ul class="nav nav-tabs ml-3">';
66 - 675
    $str .= '  <li class="nav-item border-0">';
116 - 676
    $str .= '    <a id="detailTab" class="nav-link active bg-white" href="#detailFilter">Filter <span id="detailTabArrow"><i class="material-icons material-text">expand_more</i></span></a>';
66 - 677
    $str .= '  </li>';
678
    $str .= '</ul>';
679
    $str .= '<span class="ml-auto">';
107 - 680
    if ($_SESSION["currentLayout"] == 'CardView') {
120 - 681
        $str .= '    <button id="resultViewToggle" name="submit" value="TableView" type="submit" class="btn filterButtonSmall btn-primary active"';
682
        $str .= ' data-toggle="tooltip" title="Table View" aria-label="Results Table View"><i class="material-icons md-36">view_list</i></button>';
107 - 683
    } else {
120 - 684
        $str .= '    <button id="resultViewToggle" name="submit" value="CardView" type="submit" class="btn filterButtonSmall btn-primary active"';
685
        $str .= ' data-toggle="tooltip" title="Card View" aria-label="Results Card View"><i class="material-icons md-36">view_module</i></button>';
107 - 686
    }
66 - 687
    $str .= '</span>';
120 - 688
    $str .= '<script nonce="' . base64_encode($_SESSION["nonce"]) .'">';
689
    $str .= 'document.addEventListener("DOMContentLoaded", function() {';
690
    $str .= '	document.getElementById("resultViewToggle").addEventListener("click", function() {';
691
    $str .= '        $(this).tooltip("hide");';
692
    $str .= '	});';
693
    $str .= '});';
694
    $str .= '</script>';
66 - 695
    $str .= '<span class="navbar-text text-white float-right ml-3">Showing ' . count(array_filter($_SESSION["resultArr"], function ($entry) { return ($entry['Show'] === true); })) . ' of ' . count($_SESSION["resultArr"]) . '</span>';
696
    $str .= '</nav>';
68 - 697
    $str .= '<div class="tab-content mb-3 bg-white">';
107 - 698
    $str .= '  <div id="detailFilter" class="container tab-pane bg-white"><br>';
66 - 699
    $str .= detailResultHeader();
700
    $str .= '  </div>';
701
    $str .= '</div>';
702
 
703
  return $str;
704
}
705
 
65 - 706
// print summary/header on top of listing table
66 - 707
function detailResultHeader() {
708
 
709
    $str = '';
710
    $str .= '            <form id="detailFilterForm">';
116 - 711
    $str .= '                <input type="hidden" name="sessionTab" value="' . MySessionHandler::getSessionTab() . '" />';
122 - 712
    $str .= '                <input type="hidden" name="nonce" value="' . $_SESSION['nonce'] . '" />';
66 - 713
    $str .= '                <div class="">';
714
    $str .= '                    <div class="card-group">';
715
    $str .= '';
716
 
717
    // Condition
718
    if (isset($_SESSION['AdditionalFilterCounters']['Condition'])) {
719
        $str .= '                        <div class="card m-2">';
720
        $str .= '                            <div class="card-header font-weight-bold">Condition</div>';
721
        $str .= '                            <div class="card-body">';
722
        $cnt = count($_SESSION['AdditionalFilterCounters']['Condition']);
723
        foreach($_SESSION['AdditionalFilters']['Condition'] as $key => $value) {
724
            $str .= '                                <div class="form-check">';
725
            $str .= '                                    <label class="form-check-label">';
726
            $str .= '                                        <input name="filterCondition[]" type="checkbox" value="' . $key . '" class="form-check-input"';
727
            $str .= ($value ? " checked" : "");
728
            $str .= ($cnt > 2 ? "" : " disabled");
116 - 729
            $str .= ' />' . $key . '<span class="badge badge-pill badge-dark ml-2">' . $_SESSION['AdditionalFilterCounters']['Condition'][$key] . '</span>';
66 - 730
            $str .= '                                    </label>';
731
            $str .= '                                </div>';
732
        }
733
        $str .= '                            </div>';
734
        $str .= '                        </div>';
13 - 735
    }
66 - 736
 
737
    // Media Type
738
    if (isset($_SESSION['AdditionalFilterCounters']['MediaType'])) {
739
        $str .= '                        <div class="card m-2">';
740
        $str .= '                            <div class="card-header font-weight-bold">Media Type</div>';
741
        $str .= '                            <div class="card-body">';
742
        $cnt = count($_SESSION['AdditionalFilterCounters']['MediaType']);
743
        foreach($_SESSION['AdditionalFilters']['MediaType'] as $key => $value) {
744
            $str .= '                                <div class="form-check">';
745
            $str .= '                                    <label class="form-check-label">';
746
            $str .= '                                        <input name="filterMediaType[]" type="checkbox" value="' . $key . '" class="form-check-input"';
747
            $str .= ($value ? " checked" : "");
748
            $str .= ($cnt > 1 ? "" : " disabled");
116 - 749
            $str .= ' /><i class="' . getMediaIconClass($key, "material-text") . '">' . getMediaIconAlias($key) . '</i> ' . getMediaIconText($key);
66 - 750
            $str .= '<span class="badge badge-pill badge-dark ml-2">' . $_SESSION['AdditionalFilterCounters']['MediaType'][$key] . '</span>';
751
            $str .= '                                    </label>';
752
            $str .= '                                </div>';
753
        }
754
        $str .= '                            </div>';
755
        $str .= '                        </div>';
65 - 756
    }
59 - 757
 
66 - 758
    // Merchant
759
    if (isset($_SESSION['AdditionalFilterCounters']['Merchant'])) {
760
        $str .= '                        <div class="card m-2">';
761
        $str .= '                            <div class="card-header font-weight-bold">Merchant</div>';
762
        $str .= '                            <div class="card-body">';
763
        $cnt = count($_SESSION['AdditionalFilterCounters']['Merchant']);
764
        foreach($_SESSION['AdditionalFilters']['Merchant'] as $key => $value) {
765
            $str .= '                                <div class="form-check">';
766
            $str .= '                                    <label class="form-check-label">';
767
            $str .= '                                        <input name="filterMerchant[]" type="checkbox" value="' . $key . '" class="form-check-input"';
768
            $str .= ($value ? " checked" : "");
769
            $str .= ($cnt > 1 ? "" : " disabled");
116 - 770
            $str .= ' />' . $key . '<span class="badge badge-pill badge-dark ml-2">' . $_SESSION['AdditionalFilterCounters']['Merchant'][$key] . '</span>';
66 - 771
            $str .= '                                    </label>';
772
            $str .= '                                </div>';
773
        }
774
        $str .= '                            </div>';
775
        $str .= '                        </div>';
776
    }
1 - 777
 
66 - 778
    // Shipping From
779
    if (isset($_SESSION['AdditionalFilterCounters']['ShippingFrom'])) {
780
        $str .= '                        <div class="card m-2">';
781
        $str .= '                            <div class="card-header font-weight-bold">Shipping From</div>';
782
        $str .= '                            <div class="card-body">';
783
        $cnt = count($_SESSION['AdditionalFilterCounters']['ShippingFrom']);
784
        foreach($_SESSION['AdditionalFilters']['ShippingFrom'] as $key => $value) {
785
            $str .= '                                <div class="form-check">';
786
            $str .= '                                    <label class="form-check-label">';
787
            $str .= '                                        <input name="filterShipFrom[]" type="checkbox" value="' . $key . '" class="form-check-input"';
788
            $str .= ($value ? " checked" : "");
789
            $str .= ($cnt > 1 ? "" : " disabled");
116 - 790
            $str .= ' /><img class="img-fluid lazyload" title="Ships from ' . getCountry($key) . '" data-toggle="tooltip" data-delay="200" src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="' . timeStampUrl("images/flags/" . $key . ".png") . '" alt="' . getCountry($key) . ' Flag" /><span class="badge badge-pill badge-dark ml-2">' . $_SESSION['AdditionalFilterCounters']['ShippingFrom'][$key] . '</span>';
66 - 791
            $str .= '                                    </label>';
792
            $str .= '                                </div>';
793
        }
794
        $str .= '                            </div>';
795
        $str .= '                        </div>';
796
    }
797
 
798
    $str .= '                    </div>';
799
    $str .= '                </div>';
800
    $str .= '';
801
    $str .= '                <div class="p-2">';
802
    $str .= '                    <button type="submit" class="btn btn-success detailFilterButton" name="submit" value="Apply">Apply</button>';
803
    $str .= '                    <button type="submit" class="btn btn-danger detailFilterButton" name="submit" value="Reset">Reset</button>';
804
    $str .= '                </div>';
805
    $str .= '            </form>';
806
 
65 - 807
    return $str;
5 - 808
}
1 - 809
 
65 - 810
// compare price for sort low to high
811
function compare_price($a, $b) {
812
    return strnatcmp($a['ConvertedTotalPrice'], $b['ConvertedTotalPrice']);
5 - 813
}
13 - 814
 
65 - 815
// print monetary values with correct symbol and thousands/decimal delimiters
816
function print_monetary($num, $curr) {
817
    if ($curr == "USD") {
818
        return ("$" . number_format($num, 2, '.', ','));
819
    }
820
    else if ($curr == "CAD") {
821
        return ("C $" . number_format($num, 2, '.', ','));
822
    }
823
    else if ($curr == "EUR") {
824
        return (number_format($num, 2, ',', '.') . "&euro;");
825
    }
826
    else if ($curr == "GBP") {
827
        return ("&pound;" . number_format($num, 2, '.', ','));
828
    }
829
    else if ($curr == "AUD") {
830
        return ("AU $" . number_format($num, 2, '.', ','));
831
    }
1 - 832
 
65 - 833
    return ($curr . " " . number_format($num, 2, '.', ','));
5 - 834
}
1 - 835
 
65 - 836
// find lowest used / new prices
66 - 837
function findLowestCondition($condition) {
65 - 838
    foreach ($_SESSION["resultArr"] as $row) {
839
        if (!$row["Show"]) {
840
            continue;
841
        }
1 - 842
 
66 - 843
        if ($condition == $row["Condition"]) {
65 - 844
            return ($row["ConvertedTotalPrice"]);
845
        }
846
    }
5 - 847
 
65 - 848
    return (0);
5 - 849
}
850
 
65 - 851
// find lowest cd, record, digital and book prices
66 - 852
function findLowestMediaType($mediaType) {
65 - 853
    foreach ($_SESSION["resultArr"] as $row) {
854
        if (!$row["Show"]) {
855
            continue;
856
        }
20 - 857
 
66 - 858
        if ($mediaType == $row["MediaType"]) {
65 - 859
            return ($row["ConvertedTotalPrice"]);
860
        }
861
    }
20 - 862
 
65 - 863
    return (0);
20 - 864
}
865
 
65 - 866
// find lowest non-zero double value in array
867
function minNotNull(Array $values) {
868
    return min(array_diff(array_map('doubleval', $values) , array(
869
 
870
    )));
13 - 871
}
11 - 872
 
65 - 873
// apply exchange rates
874
function applyExchangeRates($arr) {
875
    foreach ($arr as & $value) {
876
        $value["ConvertedPrice"] = $value["Price"];
877
        $value["ConvertedShippingCost"] = $value["ShippingCost"];
1 - 878
 
65 - 879
        if ($_SESSION["buyer"]["Currency"] != $value["Currency"]) {
880
            $value["ConvertedPrice"] = number_format($value["Price"] / getExchangeRate($_SESSION["buyer"]["Currency"], $value["Currency"]) , 2, '.', '');
881
        }
1 - 882
 
65 - 883
        if ($_SESSION["buyer"]["Currency"] != $value["ShippingCurrency"]) {
884
            $value["ConvertedShippingCost"] = number_format($value["ShippingCost"] / getExchangeRate($_SESSION["buyer"]["Currency"], $value["ShippingCurrency"]) , 2, '.', '');
885
        }
1 - 886
 
65 - 887
        $value["ConvertedTotalPrice"] = number_format($value["ConvertedPrice"] + $value["ConvertedShippingCost"], 2, '.', '');
888
    }
5 - 889
 
65 - 890
    return ($arr);
5 - 891
}
892
 
36 - 893
// sanitize user input
65 - 894
function sanitizeInput($data) {
895
    $data = trim(preg_replace('/[\t\n\r\s]+/', ' ', $data));
896
    $data = stripslashes($data);
897
    $data = htmlspecialchars($data);
898
    return $data;
5 - 899
}
1 - 900
 
52 - 901
// sanitize user input (plus delete apostrophe)
902
function sanitizeInput2($data) {
65 - 903
    $data = trim(preg_replace('/[\t\n\r\s\']+/', ' ', $data));
904
    $data = stripslashes($data);
905
    $data = htmlspecialchars($data, ENT_QUOTES | ENT_HTML5);
906
    return $data;
52 - 907
}
908
 
14 - 909
// convert certain utf-8 characters to ascii
910
function cleanString($str) {
911
    $utf8 = array(
65 - 912
        '/[áàâãªä]/u' => 'a',
913
        '/[ÁÀÂÃÄ]/u' => 'A',
914
        '/[ÍÌÎÏ]/u' => 'I',
915
        '/[íìîï]/u' => 'i',
916
        '/[éèêë]/u' => 'e',
917
        '/[ÉÈÊË]/u' => 'E',
918
        '/[óòôõºö]/u' => 'o',
919
        '/[ÓÒÔÕÖ]/u' => 'O',
920
        '/[úùûü]/u' => 'u',
921
        '/[ÚÙÛÜ]/u' => 'U',
922
        '/ç/' => 'c',
923
        '/Ç/' => 'C',
924
        '/ñ/' => 'n',
925
        '/Ñ/' => 'N',
926
        '/–/' => '-', // UTF-8 hyphen to "normal" hyphen
927
        '/[’‘‹›‚]/u' => ' ', // Literally a single quote
928
        '/[“”«»„]/u' => ' ', // Double quote
929
        '/ /' => ' ', // nonbreaking space (equiv. to 0x160)
66 - 930
 
14 - 931
    );
932
 
65 - 933
    return preg_replace(array_keys($utf8) , array_values($utf8) , $str);
14 - 934
}
935
 
936
// Clean the search string
937
function searchFriendlyString($str) {
938
    $str = strip_tags($str);
939
    $str = stripslashes($str);
940
    $str = cleanString($str);
65 - 941
    $str = str_replace(array(
942
        "[",
943
        "]",
944
        "<",
945
        ">",
946
        "(",
947
        ")",
948
        " - ",
949
        " & ",
950
        " / "
951
    ) , " ", $str); // eliminate single '-', '&', '/' and brackets
952
    $str = trim(preg_replace('/[\t\n\r\s]+/', ' ', $str)); // delete extra whitespaces
14 - 953
    return ucwords($str);
954
}
955
 
65 - 956
// get a SESSION value, return empty string if not set
957
function getSV($var) {
958
    if (!isset($_SESSION[$var])) {
959
        return ('');
960
    }
1 - 961
 
65 - 962
    return ($_SESSION[$var]);
5 - 963
}
964
 
65 - 965
// initialize a SESSION value if not set
966
function initSV($var, $value) {
967
    if (!isset($_SESSION[$var])) {
968
        $_SESSION[$var] = $value;
969
    }
5 - 970
}
1 - 971
 
65 - 972
// initialize sessions variables
973
function initSessionVariables() {
974
    initSV("resultArr", []);
975
    initSV("barcode", array(
976
        "Type" => "",
977
        "Value" => ""
978
    ));
979
    initSV("buyer", array(
980
        "Country" => "United States",
981
        "Currency" => "USD",
982
        "Zip" => ""
983
    ));
984
    initSV("filterCondition", array(
985
        "New" => true,
986
        "Used" => true
987
    ));
988
    initSV("filterMediaType", array(
989
        "CD" => true,
990
        "Record" => true,
991
        "Digital" => true,
992
        "Book" => true
993
    ));
994
    initSV("currentLayout", "TableView");
995
    initSV("lowestPrice", array(
996
        "Used" => 0.00,
997
        "New" => 0.00,
998
        "CD" => 0.00,
999
        "Record" => 0.00,
1000
        "Digital" => 0.00,
1001
        "Book" => "0.00",
1002
        "All" => 0.00
1003
    ));
5 - 1004
}
1005
 
14 - 1006
function md5SearchTerm() {
1007
    $data = array();
1008
    $data['cond'] = $_SESSION['filterCondition'];
1009
    $data['type'] = $_SESSION['filterMediaType'];
17 - 1010
    $data['buyer'] = $_SESSION['buyer'];
65 - 1011
    $data['term'] = array(
1012
        $_SESSION['searchTerm']
1013
    );
14 - 1014
 
65 - 1015
    return (md5(json_encode($data)));
14 - 1016
}
1017
 
65 - 1018
// check POST value, return true if set and false if not
1019
function checkPV($var) {
1020
    if (isset($_POST[$var])) {
1021
        return (true);
1022
    }
1 - 1023
 
65 - 1024
    return (false);
5 - 1025
}
1026
 
65 - 1027
// get POST or GET value, return empty if not set
1028
function getPGV($var) {
1029
    if (isset($_POST[$var])) {
1030
        return ($_POST[$var]);
1031
    }
1032
    else if (isset($_GET[$var])) {
1033
        return ($_GET[$var]);
1034
    }
14 - 1035
 
65 - 1036
    return ("");
14 - 1037
}
1038
 
3 - 1039
// print search info modal
65 - 1040
function printSearchInfoModal() {
66 - 1041
 
65 - 1042
    $str = '';
1043
    $str .= '<div class="modal fade" id="searchInfoModal">';
1044
    $str .= '    <div class="modal-dialog">';
1045
    $str .= '        <div class="modal-content">';
1046
    $str .= '';
1047
    $str .= '            <div class="modal-header bg-primary">';
107 - 1048
    $str .= '                <p class="modal-title display-5">Search Tips</p>';
116 - 1049
    $str .= '                <button type="button" class="close" data-dismiss="modal"><i class="material-icons btn-dismiss">cancel_presentation</i></button>';
65 - 1050
    $str .= '            </div>';
1051
    $str .= '';
1052
    $str .= '            <div class="modal-body bg-light text-dark">';
1053
    $str .= '              <div class="shadow p-4 bg-white">';
116 - 1054
    $str .= '                <p class="display-5"><i class="material-icons material-text md-36">search</i> Search Keywords</p>';
65 - 1055
    $str .= '                <p><span class="font-weight-bold">Barcode:</span>';
114 - 1056
    $str .= '                    <br>The 12 or 13 digit barcode, normally located on the back, offers the best chance to find a specific album. See our <a href="https://blog.findcheapmusic.com/2020/03/music-cd-barcodes-and-identifiers.html" target="_blank" rel="noopener noreferrer">blog post</a> for more information about music barcodes.</p>';
65 - 1057
    $str .= '                <p><span class="font-weight-bold">Artist and Title:</span>';
1058
    $str .= '                    <br>The full name of the album, including artist and title, will usually lead to a specific album.</p>';
1059
    $str .= '                <p><span class="font-weight-bold">Just Artist or Title:</span>';
1060
    $str .= '                    <br>Searches for artist or title alone will bring up multiple albums. You can later narrow your search further down, if necessary.</p>';
82 - 1061
    $str .= '                    <p><span class="font-italic">The search algorithm prefers the barcode number whenever available. Since some albums have been released under various barcodes, try searching again for artist and title should the barcode search come up empty.</span></p>';
65 - 1062
    $str .= '              </div>';
1063
    $str .= '            </div>';
1064
    $str .= '            <div class="modal-footer bg-primary">';
1065
    $str .= '                <button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>';
1066
    $str .= '            </div>';
1067
    $str .= '        </div>';
1068
    $str .= '    </div>';
1069
    $str .= '</div>';
3 - 1070
 
65 - 1071
    return ($str);
3 - 1072
}
8 - 1073
 
65 - 1074
function saveSearchResult() {
1075
    $conn = MySessionHandler::getDBSessionId();
13 - 1076
 
65 - 1077
    $access = mysqli_real_escape_string($conn, time());
1078
    // BUGBUG
1079
    //  country
1080
    //  currency
1081
    $zip = mysqli_real_escape_string($conn, $_SESSION['buyer']['Zip']);
1082
    $condNew = $_SESSION['filterCondition']['New'] ? 'Y' : 'N';
1083
    $condUsed = $_SESSION['filterCondition']['Used'] ? 'Y' : 'N';
1084
    $mediaCD = $_SESSION['filterMediaType']['CD'] ? 'Y' : 'N';
1085
    $mediaRecord = $_SESSION['filterMediaType']['Record'] ? 'Y' : 'N';
1086
    $mediaDigital = $_SESSION['filterMediaType']['Digital'] ? 'Y' : 'N';
1087
    $mediaBook = $_SESSION['filterMediaType']['Book'] ? 'Y' : 'N';
1088
    $data = mysqli_real_escape_string($conn, $_SESSION['searchTerm']);
1089
    $lowNew = floatval($_SESSION['lowestPrice']['New']);
1090
    $lowUsed = floatval($_SESSION['lowestPrice']['Used']);
116 - 1091
    $lowCD = floatval($_SESSION['lowestPrice']['CD']);
1092
    $lowRecord = floatval($_SESSION['lowestPrice']['Record']);
65 - 1093
    $lowDigital = floatval($_SESSION['lowestPrice']['Digital']);
1094
    $lowBook = floatval($_SESSION['lowestPrice']['Book']);
1095
    $count = count($_SESSION['resultArr']);
1096
    $userId = (empty($_SESSION['sessData']['userID']) ? 'NULL' : $_SESSION['sessData']['userID']);
96 - 1097
    $ip = inet_pton($_SERVER['REMOTE_ADDR']);
8 - 1098
 
65 - 1099
    $sql = "INSERT
20 - 1100
                INTO searches
116 - 1101
                (sessId, access, ip, zip, condNew, condUsed, mediaCD, mediaRecord, mediaDigital, mediaBook, data, lowNew, lowUsed, lowCD, lowRecord, lowDigital, lowBook, count, userId)
1102
                VALUES ('" . session_id() . "', '$access', '$ip', '$zip', '$condNew', '$condUsed', '$mediaCD', '$mediaRecord', '$mediaDigital', '$mediaBook', '$data', $lowNew, $lowUsed, $lowCD, $lowRecord, $lowDigital, $lowBook, $count, $userId)";
8 - 1103
 
65 - 1104
    if (!($result = mysqli_query($conn, $sql))) {
1105
        error_log("MySQL Write Searches Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1106
    }
13 - 1107
 
65 - 1108
    return $result;
1109
}
13 - 1110
 
17 - 1111
function getUrl($url, $userAgent = null) {
1112
    $ch = curl_init();
1113
 
1114
    // Set request header with language and charset
1115
    $header = array(
1116
        "Accept-Language: en-US,en;q=0.5",
1117
        "Accept-Charset: UTF-8,*;q=0.5"
1118
    );
1119
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
1120
 
1121
    // Set optional user-agent
1122
    if ($userAgent) {
1123
        curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
1124
    }
1125
 
1126
    curl_setopt($ch, CURLOPT_ENCODING, "gzip,deflate");
1127
    curl_setopt($ch, CURLOPT_AUTOREFERER, true);
1128
    curl_setopt($ch, CURLOPT_HEADER, 0);
84 - 1129
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
1130
    curl_setopt($ch, CURLOPT_TIMEOUT, 15);
17 - 1131
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
1132
    curl_setopt($ch, CURLOPT_URL, $url);
1133
    $response = curl_exec($ch);
1134
    if ($response === false) {
20 - 1135
        error_log('Curl Request Error: ' . curl_error($ch) . ' (' . curl_errno($ch) . ')');
1136
        error_log('Url: ' . $url);
17 - 1137
        $response = '';
1138
    }
23 - 1139
 
17 - 1140
    curl_close($ch);
1141
 
1142
    return $response;
1143
}
1144
 
20 - 1145
// Retrieve search history for current session id
14 - 1146
function getSearchHistory() {
1147
    $str = "";
38 - 1148
    $sql = "select data, max(access) from searches where sessId = '" . session_id() . "'";
1149
    if (!empty($_SESSION['sessData']['userID'])) {
1150
        $sql .= " or userID = '" . $_SESSION['sessData']['userID'] . "'";
1151
    }
1152
    $sql .= " group by data order by max(access) desc, data limit 0,30;";
14 - 1153
    $conn = MySessionHandler::getDBSessionId();
1154
 
20 - 1155
    if ($result = mysqli_query($conn, $sql)) {
1156
        if (mysqli_num_rows($result) > 0) {
65 - 1157
            while ($row = mysqli_fetch_assoc($result)) {
20 - 1158
                $str .= "<option>" . $row["data"] . "</option>";
1159
            }
14 - 1160
        }
1161
    }
65 - 1162
    else if (mysqli_errno($conn)) {
1163
        error_log("MySQL Read Searches SQL: " . $sql);
1164
        error_log("MySQL Read Searches Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1165
    }
14 - 1166
 
1167
    return $str;
1168
}
1169
 
41 - 1170
// Retrieve coupons codes
1171
function getCouponCodes() {
1172
    $str = "";
1173
    $lastAdvertiser = "";
1174
 
1175
    if (!isLoggedIn()) {
116 - 1176
        return ('<div class="container bg-warning text-center py-3"><p class="display-6"><i class="material-icons">error_outline</i> Please login to your Find Cheap Music account in order to see the coupons.</p></div>');
41 - 1177
    }
1178
 
65 - 1179
    $sql = 'select advertiser, date_format(enddate, "%M %e, %Y") as enddate, description, couponcode, url, pixel from coupons where DATE(NOW()) between startdate and enddate group by advertiser, description order by advertiser, id';
41 - 1180
    $conn = MySessionHandler::getDBSessionId();
1181
 
1182
    if ($result = mysqli_query($conn, $sql)) {
1183
        if (mysqli_num_rows($result) > 0) {
68 - 1184
            $str .= "<div class=\"container py-4 bg-secondary border\">";
65 - 1185
            while ($row = mysqli_fetch_assoc($result)) {
1186
                if ($row["advertiser"] != $lastAdvertiser) {
41 - 1187
                    if (!empty($lastAdvertiser)) {
68 - 1188
                        $str .= "</ul>";
41 - 1189
                    }
107 - 1190
                    $str .= "<h2 class=\"bg-primary text-center mt-3 mb-1\">" . $row["advertiser"] . "</h2>";
68 - 1191
                    $str .= "<ul class=\"list-group\">";
41 - 1192
                    $lastAdvertiser = $row["advertiser"];
1193
                }
51 - 1194
                if (!empty($row["url"])) {
68 - 1195
                    $str .= "<li class=\"list-group-item\"><a class=\"btn btn-link text-left\" target=\"_blank\" href=\"";
120 - 1196
                    $str .= htmlentities($row["url"]);
107 - 1197
                    $str .= "\" rel=\"nofollow noreferrer noopener\">";
68 - 1198
                    $str .= "<strong>" . $row["description"] . "</strong> until " . $row["enddate"];
51 - 1199
                    if (!empty($row["couponcode"])) {
1200
                        $str .= " (Use Coupon Code \"" . $row["couponcode"] . "\")";
1201
                    }
1202
                    $str .= "</a>";
1203
                    if (!empty($row["pixel"])) {
120 - 1204
                        $str .= "<img class=\"lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . htmlentities($row["pixel"]) . "\" width=\"1\" height=\"1\" class=\"border-0\" alt=\"" . $row["advertiser"] . " Coupon\"/ />";
51 - 1205
                    }
68 - 1206
                    $str .= "</li>";
41 - 1207
                }
1208
            }
68 - 1209
            $str .= "</ul>";
41 - 1210
            $str .= "</div>";
1211
        }
65 - 1212
    }
1213
    else if (mysqli_errno($conn)) {
41 - 1214
        $str .= "<h2>No Coupons available at the moment...</h2>";
1215
    }
1216
 
1217
    return $str;
1218
}
1219
 
14 - 1220
// Delete left over progressbar files older than 2 days
1221
function cleanupPbFiles() {
84 - 1222
    $files = glob("../MyFiles/tmp/pb*.txt");
65 - 1223
    $now = time();
14 - 1224
    foreach ($files as $file) {
1225
        if (is_file($file)) {
1226
            if ($now - filemtime($file) >= 60 * 60 * 24 * 2) { // 2 days and older
1227
                unlink($file);
1228
            }
65 - 1229
        }
14 - 1230
    }
1231
}
1232
 
1233
// Update progressbar file for a session
22 - 1234
function updatePbFile($flag = false) {
107 - 1235
    static $max_pb = 15; // max progressbar steps
22 - 1236
    static $current = 0;
23 - 1237
 
22 - 1238
    if ($flag) {
1239
        $current = 0;
65 - 1240
    }
1241
    else {
22 - 1242
        ++$current;
1243
    }
1244
 
1245
    if ($current > $max_pb) {
1246
        error_log("max_pb $max_pb is too small, current step is $current. Adjust tools.php (updatePbFile).");
1247
        $max_pb = $current;
1248
    }
65 - 1249
    $filename = session_id() . "_" . MySessionHandler::getSessionTab();
14 - 1250
    $arr_content = array();
1251
 
20 - 1252
    $percent = intval($current / $max_pb * 100);
14 - 1253
 
1254
    $arr_content['percent'] = $percent;
1255
    $arr_content['message'] = $current . " search(es) processed.";
84 - 1256
    $file = "../MyFiles/tmp/pb_" . $filename . ".txt";
14 - 1257
 
77 - 1258
    if ($percent >= 100) {
1259
        @unlink($file);
1260
    } else {
1261
        file_put_contents($file, json_encode($arr_content));
1262
    }
14 - 1263
}
20 - 1264
 
1265
// Linkshare / CJ Affiliate csv dump
1266
function ls_cj_csv($fields) {
1267
    static $fh = null;
1268
    $delimiter = ',';
1269
    $enclosure = '"';
1270
    $mysql_null = false;
1271
 
1272
    if (!$fh) {
1273
        $fh = fopen("ls_cj.csv", "a+");
1274
    }
1275
 
1276
    $delimiter_esc = preg_quote($delimiter, '/');
1277
    $enclosure_esc = preg_quote($enclosure, '/');
1278
 
1279
    $output = array();
1280
    foreach ($fields as $field) {
1281
        if ($field === null && $mysql_null) {
1282
            $output[] = 'NULL';
1283
            continue;
1284
        }
1285
 
65 - 1286
        $output[] = preg_match("/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field) ? ($enclosure . str_replace($enclosure, $enclosure . $enclosure, $field) . $enclosure) : $field;
20 - 1287
    }
1288
 
1289
    fwrite($fh, join($delimiter, $output) . "\n");
1290
}
35 - 1291
 
1292
// Login in check
1293
function isLoggedIn() {
65 - 1294
    return (!empty($_SESSION['sessData']['userLoggedIn']) && !empty($_SESSION['sessData']['userID'])) ? true : false;
35 - 1295
}
1296
 
1297
// unset all login system session data
1298
function unsetSessData() {
1299
    unset($_SESSION['sessData']['userLoggedIn']);
1300
    unset($_SESSION['sessData']['userID']);
1301
    unset($_SESSION['sessData']['loginType']);
36 - 1302
}
1303
 
1304
// get user image name
1305
function getUserImage($userData) {
1306
    if (empty($userData) || empty($userData['picture'])) {
109 - 1307
        return 'login/assets/images/default.png';
36 - 1308
    }
38 - 1309
 
36 - 1310
    $httpPos = strpos($userData['picture'], 'http');
1311
    if ($httpPos === false) {
65 - 1312
        return 'login/' . UPLOAD_PATH . 'profile_picture/' . $userData['picture'];
36 - 1313
    }
1314
 
1315
    return $userData['picture'];
38 - 1316
}
39 - 1317
 
1318
function startsWith($haystack, $needle) {
1319
    return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
1320
}
1321
 
1322
function endsWith($haystack, $needle) {
1323
    return substr_compare($haystack, $needle, -strlen($needle)) === 0;
45 - 1324
}
50 - 1325
 
1326
function displayBarcode($barcode) {
1327
    $barcode = trim(preg_replace("/[^0-9]/", "", $barcode));
1328
    $barcodeType = clsLibGTIN::GTINCheck($barcode, false, 1);
1329
 
1330
    if ($barcodeType == "UPC" && strlen($barcode) == 12) {
1331
        return substr($barcode, 0, 1) . "-" . substr($barcode, 1, 5) . "-" . substr($barcode, 6, 5) . "-" . substr($barcode, 11, 1);
65 - 1332
    }
1333
    else if (($barcodeType == "EAN" || $barcodeType == "ISBN") && strlen($barcode) == 13) {
50 - 1334
        return substr($barcode, 0, 1) . "-" . substr($barcode, 1, 6) . "-" . substr($barcode, 7, 6);
65 - 1335
    }
1336
    else if ($barcodeType == "EAN" && strlen($barcode) == 14) {
50 - 1337
        return substr($barcode, 0, 1) . "-" . substr($barcode, 1, 2) . "-" . substr($barcode, 3, 5) . "-" . substr($barcode, 8, 5) . "-" . substr($barcode, 13, 1);
65 - 1338
    }
1339
    else {
50 - 1340
        return $barcode;
1341
    }
52 - 1342
}
93 - 1343
 
1344
// fuzzy search to verify titles are relevant
1345
function verifyResultArr() {
1346
    require_once ('php/Fuse/Bitap/Bitap.php');
1347
    require_once ('php/Fuse/Bitap/matched_indices.php');
1348
    require_once ('php/Fuse/Bitap/pattern_alphabet.php');
1349
    require_once ('php/Fuse/Bitap/regex_search.php');
1350
    require_once ('php/Fuse/Bitap/score.php');
1351
    require_once ('php/Fuse/Bitap/search.php');
1352
    require_once ('php/Fuse/Helpers/deep_value.php');
1353
    require_once ('php/Fuse/Helpers/is_list.php');
1354
    require_once ('php/Fuse/Fuse.php');
1355
 
1356
    if (!empty($_SESSION["barcode"]["Value"]) || empty($_SESSION["resultArr"])) {
1357
        return;
1358
    }
1359
 
1360
    $options = [
1361
      'shouldSort' => false,
1362
    //  'tokenize' => true,
1363
    //  'matchAllTokens' => true,
1364
    //  'findAllMatches' => true,
1365
      'includeScore' => true,
1366
      'includeMatches' => true,
1367
      'threshold' => 0.6,
1368
      'location' => 0,
1369
      'distance' => 100,
1370
      'minMatchCharLength' => 5,
1371
      'keys' => [ "Title" ]
1372
    ];
1373
 
1374
    $fuse = new Fuse($_SESSION["resultArr"], $options);
1375
    $result = $fuse->search($_SESSION["searchTerm"]);
1376
 
1377
    $_SESSION["resultArr"] = [];
1378
    foreach($result as $r) {
97 - 1379
        $r['item']['score'] = (!empty($r['score']) ? $r['score'] : 0);
1380
        $r['item']['indices'] = (!empty($r['matches'][0]['indices']) ? $r['matches'][0]['indices'] : []);
93 - 1381
        $_SESSION['resultArr'][] = $r['item'];
1382
    }
1383
 
1384
    /* debug start
1385
    $lines = [];
1386
    foreach($_SESSION['resultArr'] as $r) {
1387
        $p = 0;
1388
        $t = '';
1389
        foreach($r['indices'] as $ind) {
1390
            if ($p < $ind[0]) {
1391
                $t .= substr($r['Title'], $p, $ind[0] - $p);
1392
            }
1393
            $t .= "<b>" . substr($r['Title'], $ind[0], $ind[1] - $ind[0] + 1) . "</b>";
1394
            $p = $ind[1] + 1;
1395
        }
1396
        if ($p < strlen($r['Title'])) {
1397
            $t .= substr($r['Title'], $p);
1398
        }
1399
        $lines[] = array ('score' => $r['score'], 'title' => $t);
1400
    }
1401
 
1402
    usort($lines, 'compare_score');
1403
    echo "<p>";
1404
    foreach($lines as $l) {
1405
        echo $l['score'] . ": " . $l['title'] . "<br/>";
1406
    }
1407
    echo "</p>";
1408
    debug end */
1409
}
1410
 
1411
// compare score for sort low to high
1412
function compare_score($a, $b) {
1413
    return ($a['score'] > $b['score']);
1414
}
96 - 1415
 
1416
function my_error_log($msg) {
1417
    error_log("[" . date("d-M-Y H:m:s") . "] " . $msg . PHP_EOL, 3, $_SERVER['DOCUMENT_ROOT'] . "/../MyFiles/logs/my_php_error.log");
1418
}
99 - 1419
 
1420
function saveSearchCache($vendor, $query, $subquery, $text) {
1421
    $conn = MySessionHandler::getDBSessionId();
1422
 
1423
    $created = mysqli_real_escape_string($conn, time());
1424
    $v = mysqli_real_escape_string($conn, $vendor);
1425
    $q = mysqli_real_escape_string($conn, $query);
1426
    $s = mysqli_real_escape_string($conn, $subquery);
1427
    $r = base64_encode(gzencode($text));
1428
 
1429
    $sql = "INSERT
1430
                INTO searchCache
1431
                (created, vendor, query, subquery, result)
110 - 1432
                VALUES ('$created', '$v', '$q', '$s', '$r')
1433
                ON DUPLICATE KEY UPDATE result = '$r'";
99 - 1434
 
1435
    if (!($result = mysqli_query($conn, $sql))) {
1436
        error_log("MySQL Write SearchCache Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1437
    }
1438
 
1439
    return $result;
1440
}
1441
 
1442
 
1443
function expireSearchCache() {
1444
    $conn = MySessionHandler::getDBSessionId();
1445
    $t = MySessionHandler::getDBExpirationTime();
1446
 
1447
    $expired = mysqli_real_escape_string($conn, time() - $t);
1448
 
1449
    $sql = "DELETE
1450
                FROM searchCache
1451
                WHERE created < $expired";
1452
 
1453
    if (!($result = mysqli_query($conn, $sql))) {
1454
        error_log("MySQL Delete SearchCache Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1455
    }
1456
}
1457
 
1458
function getSearchCache($vendor, $query, $subquery) {
1459
    $conn = MySessionHandler::getDBSessionId();
1460
 
1461
    $v = mysqli_real_escape_string($conn, $vendor);
1462
    $q = mysqli_real_escape_string($conn, $query);
1463
    $s = mysqli_real_escape_string($conn, $subquery);
1464
    $sql = "select result from searchCache where vendor = '$v' and query = '$q' and subquery = '$s'";
1465
 
1466
    if ($result = mysqli_query($conn, $sql)) {
1467
        if (mysqli_num_rows($result) == 1) {
1468
            if ($row = mysqli_fetch_assoc($result)) {
1469
                return gzdecode(base64_decode($row["result"]));
1470
            }
1471
        }
1472
    }
1473
    else if (mysqli_errno($conn)) {
1474
        error_log("MySQL Read SearchCache SQL: " . $sql);
1475
        error_log("MySQL Read SearchCache Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1476
    }
1477
 
1478
    return false;
104 - 1479
}
107 - 1480
 
1481
 
1482
function getGeoLocation() {
1483
    if (!empty($_SESSION['buyer']['Zip']) || empty($_SERVER['REMOTE_ADDR'])) {
1484
        return;
1485
    }
1486
 
1487
    $conn = MySessionHandler::getDBSessionId();
1488
    $ip = inet_pton($_SERVER['REMOTE_ADDR']);
1489
 
1490
    $sql = "select zip from geoLocation where ip = '$ip'";
1491
 
1492
    if ($result = mysqli_query($conn, $sql)) {
1493
        if (mysqli_num_rows($result) == 1) {
1494
            if ($row = mysqli_fetch_assoc($result)) {
1495
                $_SESSION['buyer']['Zip'] = $row["zip"];
1496
                return;
1497
            }
1498
        }
1499
    }
1500
    else if (mysqli_errno($conn)) {
1501
        error_log("MySQL Read geoLocation SQL: " . $sql);
1502
        error_log("MySQL Read geoLocation Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1503
    }
1504
 
1505
    $vendors = Vendors::getInstance();
1506
    $config = $vendors->getVendor(Vendors::IPAPI);
1507
    $key = $config['KEY'];
1508
 
1509
    $loc = file_get_contents("http://api.ipapi.com/api/" . $_SERVER['REMOTE_ADDR'] . "?access_key=" . $key);
1510
    if ($loc == false) {
1511
        return;
1512
    }
1513
 
1514
    $json = json_decode($loc);
1515
    if (!empty($json->error)) {
1516
        error_log("geoLocation Error: " . $json->error->info . " (" . $json->error->code . " | " . $json->error->type . ")");
1517
        return;
1518
    }
1519
 
1520
    $created = mysqli_real_escape_string($conn, time());
1521
    $countryCode = mysqli_real_escape_string($conn, $json->{'country_code'});
1522
    $zip = mysqli_real_escape_string($conn, $json->zip);
1523
    $language = mysqli_real_escape_string($conn, $json->location->languages[0]->code);
1524
    $is_eu = mysqli_real_escape_string($conn, $json->location->{'is_eu'} ? '1' : '0');
1525
 
1526
    $sql = "INSERT
1527
                INTO geoLocation
1528
                (ip, created, countryCode, zip, language, is_eu)
1529
                VALUES ('$ip', $created, '$countryCode', '$zip', '$language', '$is_eu')";
1530
 
1531
    if (!($result = mysqli_query($conn, $sql))) {
1532
        error_log("MySQL Write geoLocation Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1533
    }
1534
}
1535
 
1536
function timeStampUrl($file) {
121 - 1537
    if (@file_exists($file)) {
109 - 1538
        return $file . "?" . filemtime($file);
1539
    }
1540
 
1541
    return $file;
108 - 1542
}