Subversion Repositories cheapmusic

Rev

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

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