Subversion Repositories cheapmusic

Rev

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