Subversion Repositories cheapmusic

Rev

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

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