Subversion Repositories cheapmusic

Rev

Rev 116 | Rev 121 | 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;
107 - 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;
431
            $href = "href=\"" . htmlentities($row["URL"]) . "\" target=\"_blank\" rel=\"nofollow noreferrer noopener\"";
59 - 432
            $title = $row["Title"];
433
            if (mb_strlen($row["Title"], 'UTF-8') > MAXTITLELENGTH) {
65 - 434
                $title = mb_substr($row["Title"], 0, MAXTITLELENGTH, 'UTF-8') . '...';
59 - 435
            }
5 - 436
 
65 - 437
            $str .= "<tr>";
13 - 438
 
9 - 439
            // Image
120 - 440
            $str .= "<td><a id=\"image" . $cnt . "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 - 441
 
9 - 442
            // Title / Merchant
120 - 443
            $str .= "<td class=\"text-left\"><span class=\"font-weight-bold\"><a id=\"title" . $cnt . "Save\" class=\"bg-info\" " . $href . " data-toggle=\"tooltip\" title=\"" . $buyItNowTooltip . "\">" . $title . "</a></span>";
58 - 444
            $str .= "<br/><br/>";
65 - 445
            $str .= "<span class=\"font-weight-bold\">" . $row["Merchant"] . "</span>";
446
            if ($row["FeedbackScore"] != - 1) {
447
                $str .= "<span class=\"hide-extra-small\"><br/>" . $row["SellerName"] . " (" . number_format($row["FeedbackScore"], 0, "", ",") . " / " . $row["FeedbackPercent"] . "%)</span>";
448
            }
449
            else if (!empty($row["SellerName"])) {
450
                $str .= "<span class=\"hide-extra-small\"><br/>" . $row["SellerName"] . "</span>";
451
            }
452
            if (!empty($row["TimeLeft"])) {
24 - 453
                $str .= "<br>" . $row["TimeLeft"];
65 - 454
            }
455
            $str .= "</td>";
1 - 456
 
9 - 457
            // Condition
65 - 458
            $str .= "<td>";
66 - 459
            $str .= "<span class=\"font-weight-bold\">" . $row["DetailCondition"] . "</span>";
65 - 460
            $str .= "<br/><br/>";
116 - 461
            $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 - 462
            $str .= "</td>";
5 - 463
 
9 - 464
            // Price
65 - 465
            $str .= "<td class=\"hide-small\">" . print_monetary($row["Price"], $row["Currency"]);
466
            if ($row["Currency"] != $_SESSION["buyer"]["Currency"]) {
467
                $str .= "<br/>&asymp; " . print_monetary($row["ConvertedPrice"], $_SESSION["buyer"]["Currency"]);
468
            }
469
            if ($row["BestOffer"] == "true") {
470
                $str .= "<br>Best Offer Accepted";
471
            }
472
            $str .= "</td>";
1 - 473
 
9 - 474
            // Shipping and Handling Cost
65 - 475
            $str .= "<td class=\"hide-small\">";
476
            if ($row["ShippingCost"] == 0.00) {
477
                $str .= "Free Shipping";
478
            }
479
            else {
480
                $str .= print_monetary($row["ShippingCost"], $row["ShippingCurrency"]);
81 - 481
                if ($row["ShippingEstimated"]) {
482
                    $str .= "*";
483
                }
65 - 484
            }
485
            if ($row["ShippingCost"] > 0.00 && $row["ShippingCurrency"] != $_SESSION["buyer"]["Currency"]) {
486
                $str .= "<br/>&asymp; " . print_monetary($row["ConvertedShippingCost"], $_SESSION["buyer"]["Currency"]);
487
            }
24 - 488
            if ($row["HandlingTime"] > 0) {
489
                $str .= "<br>Handling Time " . $row["HandlingTime"] . " day" . ($row["HandlingTime"] > 1 ? "s" : "");
490
            }
491
            if ($row["ShippingCost"] > 0.00 && $row["FreeShippingCap"] > 0) {
492
                $str .= "<br>Free Shipping over " . print_monetary($row["FreeShippingCap"], $_SESSION["buyer"]["Currency"]);
493
            }
116 - 494
            $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 - 495
 
9 - 496
            // Total Price
65 - 497
            $str .= "<td class=\"font-weight-bolder\">" . print_monetary($row["ConvertedTotalPrice"], $_SESSION["buyer"]["Currency"]) . "</td>";
1 - 498
 
9 - 499
            // Link
120 - 500
            $linkId = ' id="link' . $cnt . 'Save"';
54 - 501
            if ($row["Merchant"] == "iTunes") {
66 - 502
                if ($row["MediaType"] == "Digital") {
108 - 503
                    $badge = timeStampUrl("images/US-UK_Apple_Music_Badge_RGB.svg");
65 - 504
                }
505
                else {
108 - 506
                    $badge = timeStampUrl("images/US_UK_Apple_Books_Badge_Get_RGB_071818.svg");
54 - 507
                }
120 - 508
                $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 - 509
            } else if (strpos($row["Merchant"], "eBay") !== false) {
120 - 510
                $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 - 511
            } else if (strpos($row["Merchant"], "Amazon") !== false) {
120 - 512
                $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 - 513
            } else {
120 - 514
                $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 - 515
            }
65 - 516
            $str .= "<td class=\"hide-extra-small text-center\">" . $linkImage . "</td>";
1 - 517
 
65 - 518
            $str .= "</tr>";
120 - 519
 
520
            $str .= '<script nonce="' . base64_encode($_SESSION["nonce"]) . '">';
521
            $str .= 'document.addEventListener("DOMContentLoaded", function() {';
522
            $str .= '	document.getElementById("image' . $cnt . 'Save").addEventListener("click", function() {';
523
            $str .= '        saveTransfer("' . $row["URL"] . '");';
524
            $str .= '	});';
525
            $str .= '	document.getElementById("title' . $cnt . 'Save").addEventListener("click", function() {';
526
            $str .= '        saveTransfer("' . $row["URL"] . '");';
527
            $str .= '	});';
528
            $str .= '	document.getElementById("link' . $cnt . 'Save").addEventListener("click", function() {';
529
            $str .= '        saveTransfer("' . $row["URL"] . '");';
530
            $str .= '	});';
531
            $str .= '});';
532
            $str .= '</script>';
9 - 533
        }
17 - 534
 
65 - 535
        $str .= "</tbody>";
536
        $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>";
537
        $str .= "</table>";
538
        $str .= "</div>";
539
    }
540
    else {
59 - 541
        $str = printNoResultsWarning();
9 - 542
    }
1 - 543
 
65 - 544
    return ($str);
59 - 545
}
1 - 546
 
65 - 547
// build HTML card deck from array
78 - 548
function buildCardDeck($arr) {
86 - 549
    global $buyItNowTooltip;
66 - 550
 
65 - 551
    $str = "";
120 - 552
    $cnt = 0;
59 - 553
 
78 - 554
    if (count($arr) > 0) {
61 - 555
        $str .= "<div class=\"card-deck small\">";
59 - 556
 
78 - 557
        foreach ($arr as $row) {
65 - 558
            if (!$row["Show"]) {
559
                continue;
560
            }
59 - 561
 
120 - 562
            ++$cnt;
563
            $href = "href=\"" . htmlentities($row["URL"]) . "\" target=\"_blank\" rel=\"nofollow noreferrer noopener\"";
59 - 564
            $title = $row["Title"];
565
            if (mb_strlen($row["Title"], 'UTF-8') > MAXTITLELENGTH) {
65 - 566
                $title = mb_substr($row["Title"], 0, MAXTITLELENGTH, 'UTF-8') . '...';
59 - 567
            }
568
 
65 - 569
            $str .= "<div class=\"card m-2 shadow mx-auto result-card\">";
59 - 570
 
571
            // Image
120 - 572
            $str .= "<a id=\"image" . $cnt . "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 - 573
 
65 - 574
            $str .= "<div class=\"card-body bg-light d-flex flex-column\">";
59 - 575
            // Title / Merchant
120 - 576
            $str .= "<p class=\"card-title font-weight-bold\"><a id=\"title" . $cnt . "Save\"" . $href . " data-toggle=\"tooltip\" title=\"" . $buyItNowTooltip . "\">" . $title . "</a></p>";
65 - 577
            $str .= "<div class=\"card-text mt-auto\"><span class=\"font-weight-bold\">" . $row["Merchant"] . "</span>";
578
            $str .= "<br>";
59 - 579
 
66 - 580
            // Condition / MediaType
581
            $str .= $row["DetailCondition"];
116 - 582
            $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 - 583
            $str .= "<br>";
59 - 584
 
585
            // Total Price
65 - 586
            $str .= "<span class=\"font-weight-bolder\">" . print_monetary($row["ConvertedTotalPrice"], $_SESSION["buyer"]["Currency"]) . "</span>";
60 - 587
            $str .= "</div>";
59 - 588
 
589
            $str .= "</div>";
590
 
591
            // Link / Ships from Flag
120 - 592
            $linkId = ' id="link' . $cnt . 'Save"';
64 - 593
            $str .= "<div class=\"card-footer bg-dark\">";
60 - 594
            $str .= "<div class=\"row\">";
65 - 595
            $str .= "<div class=\"col-9\">";
59 - 596
            if ($row["Merchant"] == "iTunes") {
66 - 597
                if ($row["MediaType"] == "Digital") {
108 - 598
                    $badge = timeStampUrl("images/US-UK_Apple_Music_Badge_RGB.svg");
65 - 599
                }
600
                else {
108 - 601
                    $badge = timeStampUrl("images/US_UK_Apple_Books_Badge_Get_RGB_071818.svg");
59 - 602
                }
120 - 603
                $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 - 604
            } else if (strpos($row["Merchant"], "eBay") !== false) {
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=\"" . timeStampUrl("images/ebay-right-now.gif") . "\" alt=\"iTunes Badge\" /></a>";
81 - 606
            } else if (strpos($row["Merchant"], "Amazon") !== 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/amazon-buy3.gif") . "\" alt=\"iTunes Badge\" /></a>";
65 - 608
            }
609
            else {
120 - 610
                $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 - 611
            }
65 - 612
            $str .= $linkImage;
59 - 613
            $str .= "</div>";
65 - 614
            $str .= "<div class=\"col-3\">";
116 - 615
            $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 - 616
            $str .= "</div>";
65 - 617
            $str .= "</div>";
618
            $str .= "</div>";
59 - 619
 
65 - 620
            $str .= "</div>";
120 - 621
 
622
            $str .= '<script nonce="' . base64_encode($_SESSION["nonce"]) . '">';
623
            $str .= 'document.addEventListener("DOMContentLoaded", function() {';
624
            $str .= '	document.getElementById("image' . $cnt . 'Save").addEventListener("click", function() {';
625
            $str .= '        saveTransfer("' . $row["URL"] . '");';
626
            $str .= '	});';
627
            $str .= '	document.getElementById("title' . $cnt . 'Save").addEventListener("click", function() {';
628
            $str .= '        saveTransfer("' . $row["URL"] . '");';
629
            $str .= '	});';
630
            $str .= '	document.getElementById("link' . $cnt . 'Save").addEventListener("click", function() {';
631
            $str .= '        saveTransfer("' . $row["URL"] . '");';
632
            $str .= '	});';
633
            $str .= '});';
634
            $str .= '</script>';
59 - 635
        }
636
 
65 - 637
        $str .= "</div>";
638
        $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>";
639
    }
640
    else {
59 - 641
        $str = printNoResultsWarning();
642
    }
643
 
65 - 644
    return ($str);
5 - 645
}
646
 
65 - 647
// print directions when no results are found
59 - 648
function printNoResultsWarning() {
649
    $str = "<div class=\"text-center bg-warning p-3 rounded\">";
104 - 650
    $str .= "<p class=\"display-5 font-weight-bold\">Your search returned no store offers</p>";
59 - 651
    $str .= "<p>You may want to try the following:</p>";
114 - 652
    $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 - 653
    $str .= "</div>";
654
 
655
    return $str;
656
}
657
 
66 - 658
function printResultHeader() {
659
    $str = '';
660
    $str .= '<nav class="navbar bg-black mt-2 pb-0">';
113 - 661
    $str .= '<span class="mr-3">';
662
    if ($_SESSION["lowestPrice"]["New"] > 0) {
663
        $str .= 'New from ' . print_monetary($_SESSION["lowestPrice"]["New"], $_SESSION["buyer"]["Currency"]);
664
    }
665
    if ($_SESSION["lowestPrice"]["New"] > 0 && $_SESSION["lowestPrice"]["Used"] > 0) {
666
        $str .= '<br>';
667
    }
668
    if ($_SESSION["lowestPrice"]["Used"] > 0) {
669
        $str .= 'Used from ' . print_monetary($_SESSION["lowestPrice"]["Used"], $_SESSION["buyer"]["Currency"]);
670
    }
671
    $str .= '</span>';
672
    $str .= '<ul class="nav nav-tabs ml-3">';
66 - 673
    $str .= '  <li class="nav-item border-0">';
116 - 674
    $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 - 675
    $str .= '  </li>';
676
    $str .= '</ul>';
677
    $str .= '<span class="ml-auto">';
107 - 678
    if ($_SESSION["currentLayout"] == 'CardView') {
120 - 679
        $str .= '    <button id="resultViewToggle" name="submit" value="TableView" type="submit" class="btn filterButtonSmall btn-primary active"';
680
        $str .= ' data-toggle="tooltip" title="Table View" aria-label="Results Table View"><i class="material-icons md-36">view_list</i></button>';
107 - 681
    } else {
120 - 682
        $str .= '    <button id="resultViewToggle" name="submit" value="CardView" type="submit" class="btn filterButtonSmall btn-primary active"';
683
        $str .= ' data-toggle="tooltip" title="Card View" aria-label="Results Card View"><i class="material-icons md-36">view_module</i></button>';
107 - 684
    }
66 - 685
    $str .= '</span>';
120 - 686
    $str .= '<script nonce="' . base64_encode($_SESSION["nonce"]) .'">';
687
    $str .= 'document.addEventListener("DOMContentLoaded", function() {';
688
    $str .= '	document.getElementById("resultViewToggle").addEventListener("click", function() {';
689
    $str .= '        $(this).tooltip("hide");';
690
    $str .= '	});';
691
    $str .= '});';
692
    $str .= '</script>';
66 - 693
    $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>';
694
    $str .= '</nav>';
68 - 695
    $str .= '<div class="tab-content mb-3 bg-white">';
107 - 696
    $str .= '  <div id="detailFilter" class="container tab-pane bg-white"><br>';
66 - 697
    $str .= detailResultHeader();
698
    $str .= '  </div>';
699
    $str .= '</div>';
700
 
701
  return $str;
702
}
703
 
65 - 704
// print summary/header on top of listing table
66 - 705
function detailResultHeader() {
706
 
707
    $str = '';
708
    $str .= '            <form id="detailFilterForm">';
116 - 709
    $str .= '                <input type="hidden" name="sessionTab" value="' . MySessionHandler::getSessionTab() . '" />';
66 - 710
    $str .= '                <div class="">';
711
    $str .= '                    <div class="card-group">';
712
    $str .= '';
713
 
714
    // Condition
715
    if (isset($_SESSION['AdditionalFilterCounters']['Condition'])) {
716
        $str .= '                        <div class="card m-2">';
717
        $str .= '                            <div class="card-header font-weight-bold">Condition</div>';
718
        $str .= '                            <div class="card-body">';
719
        $cnt = count($_SESSION['AdditionalFilterCounters']['Condition']);
720
        foreach($_SESSION['AdditionalFilters']['Condition'] as $key => $value) {
721
            $str .= '                                <div class="form-check">';
722
            $str .= '                                    <label class="form-check-label">';
723
            $str .= '                                        <input name="filterCondition[]" type="checkbox" value="' . $key . '" class="form-check-input"';
724
            $str .= ($value ? " checked" : "");
725
            $str .= ($cnt > 2 ? "" : " disabled");
116 - 726
            $str .= ' />' . $key . '<span class="badge badge-pill badge-dark ml-2">' . $_SESSION['AdditionalFilterCounters']['Condition'][$key] . '</span>';
66 - 727
            $str .= '                                    </label>';
728
            $str .= '                                </div>';
729
        }
730
        $str .= '                            </div>';
731
        $str .= '                        </div>';
13 - 732
    }
66 - 733
 
734
    // Media Type
735
    if (isset($_SESSION['AdditionalFilterCounters']['MediaType'])) {
736
        $str .= '                        <div class="card m-2">';
737
        $str .= '                            <div class="card-header font-weight-bold">Media Type</div>';
738
        $str .= '                            <div class="card-body">';
739
        $cnt = count($_SESSION['AdditionalFilterCounters']['MediaType']);
740
        foreach($_SESSION['AdditionalFilters']['MediaType'] as $key => $value) {
741
            $str .= '                                <div class="form-check">';
742
            $str .= '                                    <label class="form-check-label">';
743
            $str .= '                                        <input name="filterMediaType[]" type="checkbox" value="' . $key . '" class="form-check-input"';
744
            $str .= ($value ? " checked" : "");
745
            $str .= ($cnt > 1 ? "" : " disabled");
116 - 746
            $str .= ' /><i class="' . getMediaIconClass($key, "material-text") . '">' . getMediaIconAlias($key) . '</i> ' . getMediaIconText($key);
66 - 747
            $str .= '<span class="badge badge-pill badge-dark ml-2">' . $_SESSION['AdditionalFilterCounters']['MediaType'][$key] . '</span>';
748
            $str .= '                                    </label>';
749
            $str .= '                                </div>';
750
        }
751
        $str .= '                            </div>';
752
        $str .= '                        </div>';
65 - 753
    }
59 - 754
 
66 - 755
    // Merchant
756
    if (isset($_SESSION['AdditionalFilterCounters']['Merchant'])) {
757
        $str .= '                        <div class="card m-2">';
758
        $str .= '                            <div class="card-header font-weight-bold">Merchant</div>';
759
        $str .= '                            <div class="card-body">';
760
        $cnt = count($_SESSION['AdditionalFilterCounters']['Merchant']);
761
        foreach($_SESSION['AdditionalFilters']['Merchant'] as $key => $value) {
762
            $str .= '                                <div class="form-check">';
763
            $str .= '                                    <label class="form-check-label">';
764
            $str .= '                                        <input name="filterMerchant[]" type="checkbox" value="' . $key . '" class="form-check-input"';
765
            $str .= ($value ? " checked" : "");
766
            $str .= ($cnt > 1 ? "" : " disabled");
116 - 767
            $str .= ' />' . $key . '<span class="badge badge-pill badge-dark ml-2">' . $_SESSION['AdditionalFilterCounters']['Merchant'][$key] . '</span>';
66 - 768
            $str .= '                                    </label>';
769
            $str .= '                                </div>';
770
        }
771
        $str .= '                            </div>';
772
        $str .= '                        </div>';
773
    }
1 - 774
 
66 - 775
    // Shipping From
776
    if (isset($_SESSION['AdditionalFilterCounters']['ShippingFrom'])) {
777
        $str .= '                        <div class="card m-2">';
778
        $str .= '                            <div class="card-header font-weight-bold">Shipping From</div>';
779
        $str .= '                            <div class="card-body">';
780
        $cnt = count($_SESSION['AdditionalFilterCounters']['ShippingFrom']);
781
        foreach($_SESSION['AdditionalFilters']['ShippingFrom'] as $key => $value) {
782
            $str .= '                                <div class="form-check">';
783
            $str .= '                                    <label class="form-check-label">';
784
            $str .= '                                        <input name="filterShipFrom[]" type="checkbox" value="' . $key . '" class="form-check-input"';
785
            $str .= ($value ? " checked" : "");
786
            $str .= ($cnt > 1 ? "" : " disabled");
116 - 787
            $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 - 788
            $str .= '                                    </label>';
789
            $str .= '                                </div>';
790
        }
791
        $str .= '                            </div>';
792
        $str .= '                        </div>';
793
    }
794
 
795
    $str .= '                    </div>';
796
    $str .= '                </div>';
797
    $str .= '';
798
    $str .= '                <div class="p-2">';
799
    $str .= '                    <button type="submit" class="btn btn-success detailFilterButton" name="submit" value="Apply">Apply</button>';
800
    $str .= '                    <button type="submit" class="btn btn-danger detailFilterButton" name="submit" value="Reset">Reset</button>';
801
    $str .= '                </div>';
802
    $str .= '            </form>';
803
 
65 - 804
    return $str;
5 - 805
}
1 - 806
 
65 - 807
// compare price for sort low to high
808
function compare_price($a, $b) {
809
    return strnatcmp($a['ConvertedTotalPrice'], $b['ConvertedTotalPrice']);
5 - 810
}
13 - 811
 
65 - 812
// print monetary values with correct symbol and thousands/decimal delimiters
813
function print_monetary($num, $curr) {
814
    if ($curr == "USD") {
815
        return ("$" . number_format($num, 2, '.', ','));
816
    }
817
    else if ($curr == "CAD") {
818
        return ("C $" . number_format($num, 2, '.', ','));
819
    }
820
    else if ($curr == "EUR") {
821
        return (number_format($num, 2, ',', '.') . "&euro;");
822
    }
823
    else if ($curr == "GBP") {
824
        return ("&pound;" . number_format($num, 2, '.', ','));
825
    }
826
    else if ($curr == "AUD") {
827
        return ("AU $" . number_format($num, 2, '.', ','));
828
    }
1 - 829
 
65 - 830
    return ($curr . " " . number_format($num, 2, '.', ','));
5 - 831
}
1 - 832
 
65 - 833
// find lowest used / new prices
66 - 834
function findLowestCondition($condition) {
65 - 835
    foreach ($_SESSION["resultArr"] as $row) {
836
        if (!$row["Show"]) {
837
            continue;
838
        }
1 - 839
 
66 - 840
        if ($condition == $row["Condition"]) {
65 - 841
            return ($row["ConvertedTotalPrice"]);
842
        }
843
    }
5 - 844
 
65 - 845
    return (0);
5 - 846
}
847
 
65 - 848
// find lowest cd, record, digital and book prices
66 - 849
function findLowestMediaType($mediaType) {
65 - 850
    foreach ($_SESSION["resultArr"] as $row) {
851
        if (!$row["Show"]) {
852
            continue;
853
        }
20 - 854
 
66 - 855
        if ($mediaType == $row["MediaType"]) {
65 - 856
            return ($row["ConvertedTotalPrice"]);
857
        }
858
    }
20 - 859
 
65 - 860
    return (0);
20 - 861
}
862
 
65 - 863
// find lowest non-zero double value in array
864
function minNotNull(Array $values) {
865
    return min(array_diff(array_map('doubleval', $values) , array(
866
 
867
    )));
13 - 868
}
11 - 869
 
65 - 870
// apply exchange rates
871
function applyExchangeRates($arr) {
872
    foreach ($arr as & $value) {
873
        $value["ConvertedPrice"] = $value["Price"];
874
        $value["ConvertedShippingCost"] = $value["ShippingCost"];
1 - 875
 
65 - 876
        if ($_SESSION["buyer"]["Currency"] != $value["Currency"]) {
877
            $value["ConvertedPrice"] = number_format($value["Price"] / getExchangeRate($_SESSION["buyer"]["Currency"], $value["Currency"]) , 2, '.', '');
878
        }
1 - 879
 
65 - 880
        if ($_SESSION["buyer"]["Currency"] != $value["ShippingCurrency"]) {
881
            $value["ConvertedShippingCost"] = number_format($value["ShippingCost"] / getExchangeRate($_SESSION["buyer"]["Currency"], $value["ShippingCurrency"]) , 2, '.', '');
882
        }
1 - 883
 
65 - 884
        $value["ConvertedTotalPrice"] = number_format($value["ConvertedPrice"] + $value["ConvertedShippingCost"], 2, '.', '');
885
    }
5 - 886
 
65 - 887
    return ($arr);
5 - 888
}
889
 
36 - 890
// sanitize user input
65 - 891
function sanitizeInput($data) {
892
    $data = trim(preg_replace('/[\t\n\r\s]+/', ' ', $data));
893
    $data = stripslashes($data);
894
    $data = htmlspecialchars($data);
895
    return $data;
5 - 896
}
1 - 897
 
52 - 898
// sanitize user input (plus delete apostrophe)
899
function sanitizeInput2($data) {
65 - 900
    $data = trim(preg_replace('/[\t\n\r\s\']+/', ' ', $data));
901
    $data = stripslashes($data);
902
    $data = htmlspecialchars($data, ENT_QUOTES | ENT_HTML5);
903
    return $data;
52 - 904
}
905
 
14 - 906
// convert certain utf-8 characters to ascii
907
function cleanString($str) {
908
    $utf8 = array(
65 - 909
        '/[áàâãªä]/u' => 'a',
910
        '/[ÁÀÂÃÄ]/u' => 'A',
911
        '/[ÍÌÎÏ]/u' => 'I',
912
        '/[íìîï]/u' => 'i',
913
        '/[éèêë]/u' => 'e',
914
        '/[ÉÈÊË]/u' => 'E',
915
        '/[óòôõºö]/u' => 'o',
916
        '/[ÓÒÔÕÖ]/u' => 'O',
917
        '/[úùûü]/u' => 'u',
918
        '/[ÚÙÛÜ]/u' => 'U',
919
        '/ç/' => 'c',
920
        '/Ç/' => 'C',
921
        '/ñ/' => 'n',
922
        '/Ñ/' => 'N',
923
        '/–/' => '-', // UTF-8 hyphen to "normal" hyphen
924
        '/[’‘‹›‚]/u' => ' ', // Literally a single quote
925
        '/[“”«»„]/u' => ' ', // Double quote
926
        '/ /' => ' ', // nonbreaking space (equiv. to 0x160)
66 - 927
 
14 - 928
    );
929
 
65 - 930
    return preg_replace(array_keys($utf8) , array_values($utf8) , $str);
14 - 931
}
932
 
933
// Clean the search string
934
function searchFriendlyString($str) {
935
    $str = strip_tags($str);
936
    $str = stripslashes($str);
937
    $str = cleanString($str);
65 - 938
    $str = str_replace(array(
939
        "[",
940
        "]",
941
        "<",
942
        ">",
943
        "(",
944
        ")",
945
        " - ",
946
        " & ",
947
        " / "
948
    ) , " ", $str); // eliminate single '-', '&', '/' and brackets
949
    $str = trim(preg_replace('/[\t\n\r\s]+/', ' ', $str)); // delete extra whitespaces
14 - 950
    return ucwords($str);
951
}
952
 
65 - 953
// get a SESSION value, return empty string if not set
954
function getSV($var) {
955
    if (!isset($_SESSION[$var])) {
956
        return ('');
957
    }
1 - 958
 
65 - 959
    return ($_SESSION[$var]);
5 - 960
}
961
 
65 - 962
// initialize a SESSION value if not set
963
function initSV($var, $value) {
964
    if (!isset($_SESSION[$var])) {
965
        $_SESSION[$var] = $value;
966
    }
5 - 967
}
1 - 968
 
65 - 969
// initialize sessions variables
970
function initSessionVariables() {
971
    initSV("resultArr", []);
972
    initSV("barcode", array(
973
        "Type" => "",
974
        "Value" => ""
975
    ));
976
    initSV("buyer", array(
977
        "Country" => "United States",
978
        "Currency" => "USD",
979
        "Zip" => ""
980
    ));
981
    initSV("filterCondition", array(
982
        "New" => true,
983
        "Used" => true
984
    ));
985
    initSV("filterMediaType", array(
986
        "CD" => true,
987
        "Record" => true,
988
        "Digital" => true,
989
        "Book" => true
990
    ));
991
    initSV("currentLayout", "TableView");
992
    initSV("lowestPrice", array(
993
        "Used" => 0.00,
994
        "New" => 0.00,
995
        "CD" => 0.00,
996
        "Record" => 0.00,
997
        "Digital" => 0.00,
998
        "Book" => "0.00",
999
        "All" => 0.00
1000
    ));
5 - 1001
}
1002
 
14 - 1003
function md5SearchTerm() {
1004
    $data = array();
1005
    $data['cond'] = $_SESSION['filterCondition'];
1006
    $data['type'] = $_SESSION['filterMediaType'];
17 - 1007
    $data['buyer'] = $_SESSION['buyer'];
65 - 1008
    $data['term'] = array(
1009
        $_SESSION['searchTerm']
1010
    );
14 - 1011
 
65 - 1012
    return (md5(json_encode($data)));
14 - 1013
}
1014
 
65 - 1015
// check POST value, return true if set and false if not
1016
function checkPV($var) {
1017
    if (isset($_POST[$var])) {
1018
        return (true);
1019
    }
1 - 1020
 
65 - 1021
    return (false);
5 - 1022
}
1023
 
65 - 1024
// get POST or GET value, return empty if not set
1025
function getPGV($var) {
1026
    if (isset($_POST[$var])) {
1027
        return ($_POST[$var]);
1028
    }
1029
    else if (isset($_GET[$var])) {
1030
        return ($_GET[$var]);
1031
    }
14 - 1032
 
65 - 1033
    return ("");
14 - 1034
}
1035
 
3 - 1036
// print search info modal
65 - 1037
function printSearchInfoModal() {
66 - 1038
 
65 - 1039
    $str = '';
1040
    $str .= '<div class="modal fade" id="searchInfoModal">';
1041
    $str .= '    <div class="modal-dialog">';
1042
    $str .= '        <div class="modal-content">';
1043
    $str .= '';
1044
    $str .= '            <div class="modal-header bg-primary">';
107 - 1045
    $str .= '                <p class="modal-title display-5">Search Tips</p>';
116 - 1046
    $str .= '                <button type="button" class="close" data-dismiss="modal"><i class="material-icons btn-dismiss">cancel_presentation</i></button>';
65 - 1047
    $str .= '            </div>';
1048
    $str .= '';
1049
    $str .= '            <div class="modal-body bg-light text-dark">';
1050
    $str .= '              <div class="shadow p-4 bg-white">';
116 - 1051
    $str .= '                <p class="display-5"><i class="material-icons material-text md-36">search</i> Search Keywords</p>';
65 - 1052
    $str .= '                <p><span class="font-weight-bold">Barcode:</span>';
114 - 1053
    $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 - 1054
    $str .= '                <p><span class="font-weight-bold">Artist and Title:</span>';
1055
    $str .= '                    <br>The full name of the album, including artist and title, will usually lead to a specific album.</p>';
1056
    $str .= '                <p><span class="font-weight-bold">Just Artist or Title:</span>';
1057
    $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 - 1058
    $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 - 1059
    $str .= '              </div>';
1060
    $str .= '            </div>';
1061
    $str .= '            <div class="modal-footer bg-primary">';
1062
    $str .= '                <button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>';
1063
    $str .= '            </div>';
1064
    $str .= '        </div>';
1065
    $str .= '    </div>';
1066
    $str .= '</div>';
3 - 1067
 
65 - 1068
    return ($str);
3 - 1069
}
8 - 1070
 
65 - 1071
function saveSearchResult() {
1072
    $conn = MySessionHandler::getDBSessionId();
13 - 1073
 
65 - 1074
    $access = mysqli_real_escape_string($conn, time());
1075
    // BUGBUG
1076
    //  country
1077
    //  currency
1078
    $zip = mysqli_real_escape_string($conn, $_SESSION['buyer']['Zip']);
1079
    $condNew = $_SESSION['filterCondition']['New'] ? 'Y' : 'N';
1080
    $condUsed = $_SESSION['filterCondition']['Used'] ? 'Y' : 'N';
1081
    $mediaCD = $_SESSION['filterMediaType']['CD'] ? 'Y' : 'N';
1082
    $mediaRecord = $_SESSION['filterMediaType']['Record'] ? 'Y' : 'N';
1083
    $mediaDigital = $_SESSION['filterMediaType']['Digital'] ? 'Y' : 'N';
1084
    $mediaBook = $_SESSION['filterMediaType']['Book'] ? 'Y' : 'N';
1085
    $data = mysqli_real_escape_string($conn, $_SESSION['searchTerm']);
1086
    $lowNew = floatval($_SESSION['lowestPrice']['New']);
1087
    $lowUsed = floatval($_SESSION['lowestPrice']['Used']);
116 - 1088
    $lowCD = floatval($_SESSION['lowestPrice']['CD']);
1089
    $lowRecord = floatval($_SESSION['lowestPrice']['Record']);
65 - 1090
    $lowDigital = floatval($_SESSION['lowestPrice']['Digital']);
1091
    $lowBook = floatval($_SESSION['lowestPrice']['Book']);
1092
    $count = count($_SESSION['resultArr']);
1093
    $userId = (empty($_SESSION['sessData']['userID']) ? 'NULL' : $_SESSION['sessData']['userID']);
96 - 1094
    $ip = inet_pton($_SERVER['REMOTE_ADDR']);
8 - 1095
 
65 - 1096
    $sql = "INSERT
20 - 1097
                INTO searches
116 - 1098
                (sessId, access, ip, zip, condNew, condUsed, mediaCD, mediaRecord, mediaDigital, mediaBook, data, lowNew, lowUsed, lowCD, lowRecord, lowDigital, lowBook, count, userId)
1099
                VALUES ('" . session_id() . "', '$access', '$ip', '$zip', '$condNew', '$condUsed', '$mediaCD', '$mediaRecord', '$mediaDigital', '$mediaBook', '$data', $lowNew, $lowUsed, $lowCD, $lowRecord, $lowDigital, $lowBook, $count, $userId)";
8 - 1100
 
65 - 1101
    if (!($result = mysqli_query($conn, $sql))) {
1102
        error_log("MySQL Write Searches Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1103
    }
13 - 1104
 
65 - 1105
    return $result;
1106
}
13 - 1107
 
17 - 1108
function getUrl($url, $userAgent = null) {
1109
    $ch = curl_init();
1110
 
1111
    // Set request header with language and charset
1112
    $header = array(
1113
        "Accept-Language: en-US,en;q=0.5",
1114
        "Accept-Charset: UTF-8,*;q=0.5"
1115
    );
1116
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
1117
 
1118
    // Set optional user-agent
1119
    if ($userAgent) {
1120
        curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
1121
    }
1122
 
1123
    curl_setopt($ch, CURLOPT_ENCODING, "gzip,deflate");
1124
    curl_setopt($ch, CURLOPT_AUTOREFERER, true);
1125
    curl_setopt($ch, CURLOPT_HEADER, 0);
84 - 1126
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
1127
    curl_setopt($ch, CURLOPT_TIMEOUT, 15);
17 - 1128
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
1129
    curl_setopt($ch, CURLOPT_URL, $url);
1130
    $response = curl_exec($ch);
1131
    if ($response === false) {
20 - 1132
        error_log('Curl Request Error: ' . curl_error($ch) . ' (' . curl_errno($ch) . ')');
1133
        error_log('Url: ' . $url);
17 - 1134
        $response = '';
1135
    }
23 - 1136
 
17 - 1137
    curl_close($ch);
1138
 
1139
    return $response;
1140
}
1141
 
20 - 1142
// Retrieve search history for current session id
14 - 1143
function getSearchHistory() {
1144
    $str = "";
38 - 1145
    $sql = "select data, max(access) from searches where sessId = '" . session_id() . "'";
1146
    if (!empty($_SESSION['sessData']['userID'])) {
1147
        $sql .= " or userID = '" . $_SESSION['sessData']['userID'] . "'";
1148
    }
1149
    $sql .= " group by data order by max(access) desc, data limit 0,30;";
14 - 1150
    $conn = MySessionHandler::getDBSessionId();
1151
 
20 - 1152
    if ($result = mysqli_query($conn, $sql)) {
1153
        if (mysqli_num_rows($result) > 0) {
65 - 1154
            while ($row = mysqli_fetch_assoc($result)) {
20 - 1155
                $str .= "<option>" . $row["data"] . "</option>";
1156
            }
14 - 1157
        }
1158
    }
65 - 1159
    else if (mysqli_errno($conn)) {
1160
        error_log("MySQL Read Searches SQL: " . $sql);
1161
        error_log("MySQL Read Searches Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1162
    }
14 - 1163
 
1164
    return $str;
1165
}
1166
 
41 - 1167
// Retrieve coupons codes
1168
function getCouponCodes() {
1169
    $str = "";
1170
    $lastAdvertiser = "";
1171
 
1172
    if (!isLoggedIn()) {
116 - 1173
        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 - 1174
    }
1175
 
65 - 1176
    $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 - 1177
    $conn = MySessionHandler::getDBSessionId();
1178
 
1179
    if ($result = mysqli_query($conn, $sql)) {
1180
        if (mysqli_num_rows($result) > 0) {
68 - 1181
            $str .= "<div class=\"container py-4 bg-secondary border\">";
65 - 1182
            while ($row = mysqli_fetch_assoc($result)) {
1183
                if ($row["advertiser"] != $lastAdvertiser) {
41 - 1184
                    if (!empty($lastAdvertiser)) {
68 - 1185
                        $str .= "</ul>";
41 - 1186
                    }
107 - 1187
                    $str .= "<h2 class=\"bg-primary text-center mt-3 mb-1\">" . $row["advertiser"] . "</h2>";
68 - 1188
                    $str .= "<ul class=\"list-group\">";
41 - 1189
                    $lastAdvertiser = $row["advertiser"];
1190
                }
51 - 1191
                if (!empty($row["url"])) {
68 - 1192
                    $str .= "<li class=\"list-group-item\"><a class=\"btn btn-link text-left\" target=\"_blank\" href=\"";
120 - 1193
                    $str .= htmlentities($row["url"]);
107 - 1194
                    $str .= "\" rel=\"nofollow noreferrer noopener\">";
68 - 1195
                    $str .= "<strong>" . $row["description"] . "</strong> until " . $row["enddate"];
51 - 1196
                    if (!empty($row["couponcode"])) {
1197
                        $str .= " (Use Coupon Code \"" . $row["couponcode"] . "\")";
1198
                    }
1199
                    $str .= "</a>";
1200
                    if (!empty($row["pixel"])) {
120 - 1201
                        $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 - 1202
                    }
68 - 1203
                    $str .= "</li>";
41 - 1204
                }
1205
            }
68 - 1206
            $str .= "</ul>";
41 - 1207
            $str .= "</div>";
1208
        }
65 - 1209
    }
1210
    else if (mysqli_errno($conn)) {
41 - 1211
        $str .= "<h2>No Coupons available at the moment...</h2>";
1212
    }
1213
 
1214
    return $str;
1215
}
1216
 
14 - 1217
// Delete left over progressbar files older than 2 days
1218
function cleanupPbFiles() {
84 - 1219
    $files = glob("../MyFiles/tmp/pb*.txt");
65 - 1220
    $now = time();
14 - 1221
    foreach ($files as $file) {
1222
        if (is_file($file)) {
1223
            if ($now - filemtime($file) >= 60 * 60 * 24 * 2) { // 2 days and older
1224
                unlink($file);
1225
            }
65 - 1226
        }
14 - 1227
    }
1228
}
1229
 
1230
// Update progressbar file for a session
22 - 1231
function updatePbFile($flag = false) {
107 - 1232
    static $max_pb = 15; // max progressbar steps
22 - 1233
    static $current = 0;
23 - 1234
 
22 - 1235
    if ($flag) {
1236
        $current = 0;
65 - 1237
    }
1238
    else {
22 - 1239
        ++$current;
1240
    }
1241
 
1242
    if ($current > $max_pb) {
1243
        error_log("max_pb $max_pb is too small, current step is $current. Adjust tools.php (updatePbFile).");
1244
        $max_pb = $current;
1245
    }
65 - 1246
    $filename = session_id() . "_" . MySessionHandler::getSessionTab();
14 - 1247
    $arr_content = array();
1248
 
20 - 1249
    $percent = intval($current / $max_pb * 100);
14 - 1250
 
1251
    $arr_content['percent'] = $percent;
1252
    $arr_content['message'] = $current . " search(es) processed.";
84 - 1253
    $file = "../MyFiles/tmp/pb_" . $filename . ".txt";
14 - 1254
 
77 - 1255
    if ($percent >= 100) {
1256
        @unlink($file);
1257
    } else {
1258
        file_put_contents($file, json_encode($arr_content));
1259
    }
14 - 1260
}
20 - 1261
 
1262
// Linkshare / CJ Affiliate csv dump
1263
function ls_cj_csv($fields) {
1264
    static $fh = null;
1265
    $delimiter = ',';
1266
    $enclosure = '"';
1267
    $mysql_null = false;
1268
 
1269
    if (!$fh) {
1270
        $fh = fopen("ls_cj.csv", "a+");
1271
    }
1272
 
1273
    $delimiter_esc = preg_quote($delimiter, '/');
1274
    $enclosure_esc = preg_quote($enclosure, '/');
1275
 
1276
    $output = array();
1277
    foreach ($fields as $field) {
1278
        if ($field === null && $mysql_null) {
1279
            $output[] = 'NULL';
1280
            continue;
1281
        }
1282
 
65 - 1283
        $output[] = preg_match("/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field) ? ($enclosure . str_replace($enclosure, $enclosure . $enclosure, $field) . $enclosure) : $field;
20 - 1284
    }
1285
 
1286
    fwrite($fh, join($delimiter, $output) . "\n");
1287
}
35 - 1288
 
1289
// Login in check
1290
function isLoggedIn() {
65 - 1291
    return (!empty($_SESSION['sessData']['userLoggedIn']) && !empty($_SESSION['sessData']['userID'])) ? true : false;
35 - 1292
}
1293
 
1294
// unset all login system session data
1295
function unsetSessData() {
1296
    unset($_SESSION['sessData']['userLoggedIn']);
1297
    unset($_SESSION['sessData']['userID']);
1298
    unset($_SESSION['sessData']['loginType']);
36 - 1299
}
1300
 
1301
// get user image name
1302
function getUserImage($userData) {
1303
    if (empty($userData) || empty($userData['picture'])) {
109 - 1304
        return 'login/assets/images/default.png';
36 - 1305
    }
38 - 1306
 
36 - 1307
    $httpPos = strpos($userData['picture'], 'http');
1308
    if ($httpPos === false) {
65 - 1309
        return 'login/' . UPLOAD_PATH . 'profile_picture/' . $userData['picture'];
36 - 1310
    }
1311
 
1312
    return $userData['picture'];
38 - 1313
}
39 - 1314
 
1315
function startsWith($haystack, $needle) {
1316
    return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
1317
}
1318
 
1319
function endsWith($haystack, $needle) {
1320
    return substr_compare($haystack, $needle, -strlen($needle)) === 0;
45 - 1321
}
50 - 1322
 
1323
function displayBarcode($barcode) {
1324
    $barcode = trim(preg_replace("/[^0-9]/", "", $barcode));
1325
    $barcodeType = clsLibGTIN::GTINCheck($barcode, false, 1);
1326
 
1327
    if ($barcodeType == "UPC" && strlen($barcode) == 12) {
1328
        return substr($barcode, 0, 1) . "-" . substr($barcode, 1, 5) . "-" . substr($barcode, 6, 5) . "-" . substr($barcode, 11, 1);
65 - 1329
    }
1330
    else if (($barcodeType == "EAN" || $barcodeType == "ISBN") && strlen($barcode) == 13) {
50 - 1331
        return substr($barcode, 0, 1) . "-" . substr($barcode, 1, 6) . "-" . substr($barcode, 7, 6);
65 - 1332
    }
1333
    else if ($barcodeType == "EAN" && strlen($barcode) == 14) {
50 - 1334
        return substr($barcode, 0, 1) . "-" . substr($barcode, 1, 2) . "-" . substr($barcode, 3, 5) . "-" . substr($barcode, 8, 5) . "-" . substr($barcode, 13, 1);
65 - 1335
    }
1336
    else {
50 - 1337
        return $barcode;
1338
    }
52 - 1339
}
93 - 1340
 
1341
// fuzzy search to verify titles are relevant
1342
function verifyResultArr() {
1343
    require_once ('php/Fuse/Bitap/Bitap.php');
1344
    require_once ('php/Fuse/Bitap/matched_indices.php');
1345
    require_once ('php/Fuse/Bitap/pattern_alphabet.php');
1346
    require_once ('php/Fuse/Bitap/regex_search.php');
1347
    require_once ('php/Fuse/Bitap/score.php');
1348
    require_once ('php/Fuse/Bitap/search.php');
1349
    require_once ('php/Fuse/Helpers/deep_value.php');
1350
    require_once ('php/Fuse/Helpers/is_list.php');
1351
    require_once ('php/Fuse/Fuse.php');
1352
 
1353
    if (!empty($_SESSION["barcode"]["Value"]) || empty($_SESSION["resultArr"])) {
1354
        return;
1355
    }
1356
 
1357
    $options = [
1358
      'shouldSort' => false,
1359
    //  'tokenize' => true,
1360
    //  'matchAllTokens' => true,
1361
    //  'findAllMatches' => true,
1362
      'includeScore' => true,
1363
      'includeMatches' => true,
1364
      'threshold' => 0.6,
1365
      'location' => 0,
1366
      'distance' => 100,
1367
      'minMatchCharLength' => 5,
1368
      'keys' => [ "Title" ]
1369
    ];
1370
 
1371
    $fuse = new Fuse($_SESSION["resultArr"], $options);
1372
    $result = $fuse->search($_SESSION["searchTerm"]);
1373
 
1374
    $_SESSION["resultArr"] = [];
1375
    foreach($result as $r) {
97 - 1376
        $r['item']['score'] = (!empty($r['score']) ? $r['score'] : 0);
1377
        $r['item']['indices'] = (!empty($r['matches'][0]['indices']) ? $r['matches'][0]['indices'] : []);
93 - 1378
        $_SESSION['resultArr'][] = $r['item'];
1379
    }
1380
 
1381
    /* debug start
1382
    $lines = [];
1383
    foreach($_SESSION['resultArr'] as $r) {
1384
        $p = 0;
1385
        $t = '';
1386
        foreach($r['indices'] as $ind) {
1387
            if ($p < $ind[0]) {
1388
                $t .= substr($r['Title'], $p, $ind[0] - $p);
1389
            }
1390
            $t .= "<b>" . substr($r['Title'], $ind[0], $ind[1] - $ind[0] + 1) . "</b>";
1391
            $p = $ind[1] + 1;
1392
        }
1393
        if ($p < strlen($r['Title'])) {
1394
            $t .= substr($r['Title'], $p);
1395
        }
1396
        $lines[] = array ('score' => $r['score'], 'title' => $t);
1397
    }
1398
 
1399
    usort($lines, 'compare_score');
1400
    echo "<p>";
1401
    foreach($lines as $l) {
1402
        echo $l['score'] . ": " . $l['title'] . "<br/>";
1403
    }
1404
    echo "</p>";
1405
    debug end */
1406
}
1407
 
1408
// compare score for sort low to high
1409
function compare_score($a, $b) {
1410
    return ($a['score'] > $b['score']);
1411
}
96 - 1412
 
1413
function my_error_log($msg) {
1414
    error_log("[" . date("d-M-Y H:m:s") . "] " . $msg . PHP_EOL, 3, $_SERVER['DOCUMENT_ROOT'] . "/../MyFiles/logs/my_php_error.log");
1415
}
99 - 1416
 
1417
function saveSearchCache($vendor, $query, $subquery, $text) {
1418
    $conn = MySessionHandler::getDBSessionId();
1419
 
1420
    $created = mysqli_real_escape_string($conn, time());
1421
    $v = mysqli_real_escape_string($conn, $vendor);
1422
    $q = mysqli_real_escape_string($conn, $query);
1423
    $s = mysqli_real_escape_string($conn, $subquery);
1424
    $r = base64_encode(gzencode($text));
1425
 
1426
    $sql = "INSERT
1427
                INTO searchCache
1428
                (created, vendor, query, subquery, result)
110 - 1429
                VALUES ('$created', '$v', '$q', '$s', '$r')
1430
                ON DUPLICATE KEY UPDATE result = '$r'";
99 - 1431
 
1432
    if (!($result = mysqli_query($conn, $sql))) {
1433
        error_log("MySQL Write SearchCache Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1434
    }
1435
 
1436
    return $result;
1437
}
1438
 
1439
 
1440
function expireSearchCache() {
1441
    $conn = MySessionHandler::getDBSessionId();
1442
    $t = MySessionHandler::getDBExpirationTime();
1443
 
1444
    $expired = mysqli_real_escape_string($conn, time() - $t);
1445
 
1446
    $sql = "DELETE
1447
                FROM searchCache
1448
                WHERE created < $expired";
1449
 
1450
    if (!($result = mysqli_query($conn, $sql))) {
1451
        error_log("MySQL Delete SearchCache Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1452
    }
1453
}
1454
 
1455
function getSearchCache($vendor, $query, $subquery) {
1456
    $conn = MySessionHandler::getDBSessionId();
1457
 
1458
    $v = mysqli_real_escape_string($conn, $vendor);
1459
    $q = mysqli_real_escape_string($conn, $query);
1460
    $s = mysqli_real_escape_string($conn, $subquery);
1461
    $sql = "select result from searchCache where vendor = '$v' and query = '$q' and subquery = '$s'";
1462
 
1463
    if ($result = mysqli_query($conn, $sql)) {
1464
        if (mysqli_num_rows($result) == 1) {
1465
            if ($row = mysqli_fetch_assoc($result)) {
1466
                return gzdecode(base64_decode($row["result"]));
1467
            }
1468
        }
1469
    }
1470
    else if (mysqli_errno($conn)) {
1471
        error_log("MySQL Read SearchCache SQL: " . $sql);
1472
        error_log("MySQL Read SearchCache Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1473
    }
1474
 
1475
    return false;
104 - 1476
}
107 - 1477
 
1478
 
1479
function getGeoLocation() {
1480
    if (!empty($_SESSION['buyer']['Zip']) || empty($_SERVER['REMOTE_ADDR'])) {
1481
        return;
1482
    }
1483
 
1484
    $conn = MySessionHandler::getDBSessionId();
1485
    $ip = inet_pton($_SERVER['REMOTE_ADDR']);
1486
 
1487
    $sql = "select zip from geoLocation where ip = '$ip'";
1488
 
1489
    if ($result = mysqli_query($conn, $sql)) {
1490
        if (mysqli_num_rows($result) == 1) {
1491
            if ($row = mysqli_fetch_assoc($result)) {
1492
                $_SESSION['buyer']['Zip'] = $row["zip"];
1493
                return;
1494
            }
1495
        }
1496
    }
1497
    else if (mysqli_errno($conn)) {
1498
        error_log("MySQL Read geoLocation SQL: " . $sql);
1499
        error_log("MySQL Read geoLocation Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1500
    }
1501
 
1502
    $vendors = Vendors::getInstance();
1503
    $config = $vendors->getVendor(Vendors::IPAPI);
1504
    $key = $config['KEY'];
1505
 
1506
    $loc = file_get_contents("http://api.ipapi.com/api/" . $_SERVER['REMOTE_ADDR'] . "?access_key=" . $key);
1507
    if ($loc == false) {
1508
        return;
1509
    }
1510
 
1511
    $json = json_decode($loc);
1512
    if (!empty($json->error)) {
1513
        error_log("geoLocation Error: " . $json->error->info . " (" . $json->error->code . " | " . $json->error->type . ")");
1514
        return;
1515
    }
1516
 
1517
    $created = mysqli_real_escape_string($conn, time());
1518
    $countryCode = mysqli_real_escape_string($conn, $json->{'country_code'});
1519
    $zip = mysqli_real_escape_string($conn, $json->zip);
1520
    $language = mysqli_real_escape_string($conn, $json->location->languages[0]->code);
1521
    $is_eu = mysqli_real_escape_string($conn, $json->location->{'is_eu'} ? '1' : '0');
1522
 
1523
    $sql = "INSERT
1524
                INTO geoLocation
1525
                (ip, created, countryCode, zip, language, is_eu)
1526
                VALUES ('$ip', $created, '$countryCode', '$zip', '$language', '$is_eu')";
1527
 
1528
    if (!($result = mysqli_query($conn, $sql))) {
1529
        error_log("MySQL Write geoLocation Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1530
    }
1531
}
1532
 
1533
function timeStampUrl($file) {
109 - 1534
    if (file_exists($file)) {
1535
        return $file . "?" . filemtime($file);
1536
    }
1537
 
1538
    return $file;
108 - 1539
}