Subversion Repositories cheapmusic

Rev

Rev 134 | Rev 137 | 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');
127 - 18
include_once ('php/class.html.php');
19
include_once ('php/htmlTools.php');
1 - 20
 
20 - 21
error_reporting(E_ALL);
22
 
65 - 23
// search
5 - 24
function performSearch() {
14 - 25
    $currentMd5SearchTerm = md5SearchTerm();
116 - 26
    if (isset($_SESSION['md5LastSearch']) && $currentMd5SearchTerm == $_SESSION['md5LastSearch']) {
14 - 27
        return;
28
    }
29
    $_SESSION['md5LastSearch'] = $currentMd5SearchTerm;
81 - 30
    $_SESSION["barcode"]["Type"] = clsLibGTIN::GTINCheck($_SESSION["searchTerm"], false, 1);
31
    $_SESSION["barcode"]["Value"] = clsLibGTIN::GTINCheck($_SESSION["searchTerm"]);
32
 
129 - 33
    updatePbFile(true, "Start");
22 - 34
 
107 - 35
    getGeoLocation();
36
 
81 - 37
    findDiscogsMaster($_SESSION["searchTerm"]);
129 - 38
    updatePbFile(false, "Discogs");
81 - 39
 
65 - 40
    $_SESSION["resultArr"] = [];
99 - 41
    expireSearchCache();
65 - 42
    $_SESSION["resultArr"] = searchAll($_SESSION["searchTerm"]);
93 - 43
 
99 - 44
    verifyResultArr();
93 - 45
 
65 - 46
    $_SESSION["resultArr"] = applySearchFilter($_SESSION["resultArr"]);
5 - 47
 
65 - 48
    //echo "<pre>";print_r($_SESSION["resultArr"]);echo "</pre>";
66 - 49
    $_SESSION["lowestPrice"]["Used"] = findLowestCondition("Used");
50
    $_SESSION["lowestPrice"]["New"] = findLowestCondition("New");
51
    $_SESSION["lowestPrice"]["CD"] = findLowestMediaType("CD");
52
    $_SESSION["lowestPrice"]["Record"] = findLowestMediaType("Record");
53
    $_SESSION["lowestPrice"]["Digital"] = findLowestMediaType("Digital");
54
    $_SESSION["lowestPrice"]["Book"] = findLowestMediaType("Book");
65 - 55
    $_SESSION["lowestPrice"]["All"] = 0.00;
56
    if (array_sum($_SESSION["lowestPrice"]) > 0) {
57
        $_SESSION["lowestPrice"]["All"] = minNotNull($_SESSION["lowestPrice"]);
58
    }
13 - 59
 
129 - 60
    $aiVal = saveSearchResult();
61
 
62
    updatePbFile(true, "End:$aiVal");
5 - 63
}
64
 
9 - 65
function resetSessionVars() {
66
    $_SESSION["searchTerm"] = '';
46 - 67
    $_SESSION["discogsTitle"] = '';
68
    $_SESSION["discogsArtist"] = '';
14 - 69
    $_SESSION['md5LastSearch'] = '';
65 - 70
    $_SESSION["barcode"]["Type"] = '';
71
    $_SESSION["barcode"]["Value"] = '';
9 - 72
 
65 - 73
    $_SESSION["resultArr"] = [];
9 - 74
 
65 - 75
    $_SESSION["lowestPrice"]["Used"] = 0.00;
76
    $_SESSION["lowestPrice"]["New"] = 0.00;
77
    $_SESSION["lowestPrice"]["CD"] = 0.00;
78
    $_SESSION["lowestPrice"]["Record"] = 0.00;
79
    $_SESSION["lowestPrice"]["Digital"] = 0.00;
80
    $_SESSION["lowestPrice"]["Book"] = 0.00;
81
    $_SESSION["lowestPrice"]["All"] = 0.00;
9 - 82
}
83
 
65 - 84
// search for items on all sites
72 - 85
function searchAll($searchKey, $batchFlag = false) {
65 - 86
    $arr = [];
87
    if ($_SESSION["filterCondition"]["New"]) {
129 - 88
        get_vendor($arr, 'get_ebay', $searchKey, constant("NEW"));
65 - 89
    }
129 - 90
    if (!$batchFlag) { updatePbFile(false, "eBay New"); }
65 - 91
    if ($_SESSION["filterCondition"]["New"]) {
129 - 92
        get_vendor($arr, 'get_linkshare', $searchKey, constant("NEW"));
65 - 93
    }
129 - 94
    if (!$batchFlag) { updatePbFile(false, "Linkshare"); }
65 - 95
    if ($_SESSION["filterCondition"]["New"]) {
129 - 96
        get_vendor($arr, 'get_cjaffiliate', $searchKey, constant("NEW"));
65 - 97
    }
129 - 98
    if (!$batchFlag) { updatePbFile(false, "CJ Affiliate"); }
65 - 99
    if ($_SESSION["filterCondition"]["New"]) {
129 - 100
        get_vendor($arr, 'get_walmart', $searchKey, constant("NEW"));
65 - 101
    }
129 - 102
    if (!$batchFlag) { updatePbFile(false, "Walmart"); }
65 - 103
    if ($_SESSION["filterCondition"]["New"]) {
129 - 104
        get_vendor($arr, 'get_itunes', $searchKey, constant("NEW"));
65 - 105
    }
129 - 106
    if (!$batchFlag) { updatePbFile(false, "iTunes"); }
17 - 107
 
91 - 108
    $cntArr = count($arr);
129 - 109
    get_vendor($arr, 'get_amazon', $searchKey, constant("NEW"));
110
    if (!$batchFlag) { updatePbFile(false, "Amazon API"); }
91 - 111
    if ($cntArr == count($arr)) {
129 - 112
        get_vendor($arr, 'get_amazon_scrape', $searchKey, constant("NEW"));
91 - 113
    }
129 - 114
    if (!$batchFlag) { updatePbFile(false, "Amazon Scrape"); }
81 - 115
 
129 - 116
    get_vendor($arr, 'get_impact', $searchKey, constant("NEW"));
117
    if (!$batchFlag) { updatePbFile(false, "Impact"); }
83 - 118
 
65 - 119
    if ($_SESSION["filterCondition"]["Used"]) {
129 - 120
        get_vendor($arr, 'get_ebay', $searchKey, constant("USED"));
65 - 121
    }
129 - 122
    if (!$batchFlag) { updatePbFile(false, "eBay Used"); }
17 - 123
 
66 - 124
//echo "<pre>";print_r($arr);echo "</pre";
24 - 125
 
65 - 126
    $arr = applyExchangeRates($arr);
127
    usort($arr, 'compare_price');
5 - 128
 
65 - 129
    return $arr;
5 - 130
}
131
 
20 - 132
// Search and merge
129 - 133
function get_vendor(&$arr, $func, $searchKey, $condition) {
65 - 134
    $arrTemp = $func($searchKey, $condition);
129 - 135
    foreach($arrTemp as $value) {
136
        $arr[] = $value;
137
    }
20 - 138
}
139
 
21 - 140
// delete results from array that do not match the search filters
141
function applySearchFilter($arr) {
66 - 142
    unset($_SESSION['AdditionalFilterCounters']);
143
    unset($_SESSION['AdditionalFilters']);
65 - 144
    foreach ($arr as $key => $row) {
66 - 145
        if (!$_SESSION["filterMediaType"][$row["MediaType"]] || !$_SESSION["filterCondition"][$row["Condition"]]) {
21 - 146
            unset($arr[$key]);
66 - 147
        } else {
148
            if (isset($_SESSION['AdditionalFilterCounters']['Condition']['All'])) {
149
                $_SESSION['AdditionalFilterCounters']['Condition']['All']++;
150
            } else {
151
                $_SESSION['AdditionalFilterCounters']['Condition']['All'] = 1;
152
            }
153
 
154
            if (isset($_SESSION['AdditionalFilterCounters']['Merchant'][$row['Merchant']])) {
155
                $_SESSION['AdditionalFilterCounters']['Merchant'][$row['Merchant']]++;
156
            } else {
157
                $_SESSION['AdditionalFilterCounters']['Merchant'][$row['Merchant']] = 1;
158
                $_SESSION['AdditionalFilters']['Merchant'][$row['Merchant']] = true;
159
            }
160
 
161
            if (!empty($row['SellerName'])) {
162
                if (isset($_SESSION['AdditionalFilterCounters']['Seller'][$row['SellerName']])) {
163
                    $_SESSION['AdditionalFilterCounters']['Seller'][$row['SellerName']]++;
164
                } else {
165
                    $_SESSION['AdditionalFilterCounters']['Seller'][$row['SellerName']] = 1;
166
                    $_SESSION['AdditionalFilters']['Seller'][$row['SellerName']] = true;
167
                }
168
            }
169
 
170
            if (isset($_SESSION['AdditionalFilterCounters']['Condition'][$row['Condition']])) {
171
                $_SESSION['AdditionalFilterCounters']['Condition'][$row['Condition']]++;
172
            } else {
173
                $_SESSION['AdditionalFilterCounters']['Condition'][$row['Condition']] = 1;
174
                $_SESSION['AdditionalFilters']['Condition'][$row['Condition']] = true;
175
            }
176
 
177
            if (isset($_SESSION['AdditionalFilterCounters']['MediaType'][$row['MediaType']])) {
178
                $_SESSION['AdditionalFilterCounters']['MediaType'][$row['MediaType']]++;
179
            } else {
180
                $_SESSION['AdditionalFilterCounters']['MediaType'][$row['MediaType']] = 1;
181
                $_SESSION['AdditionalFilters']['MediaType'][$row['MediaType']] = true;
182
            }
183
 
184
            if (isset($_SESSION['AdditionalFilterCounters']['DetailCondition'][$row['DetailCondition']])) {
185
                $_SESSION['AdditionalFilterCounters']['DetailCondition'][$row['DetailCondition']]++;
186
            } else {
187
                $_SESSION['AdditionalFilterCounters']['DetailCondition'][$row['DetailCondition']] = 1;
188
                $_SESSION['AdditionalFilters']['DetailCondition'][$row['DetailCondition']] = true;
189
            }
190
 
191
            if (isset($_SESSION['AdditionalFilterCounters']['ShippingFrom'][$row['Country']])) {
192
                $_SESSION['AdditionalFilterCounters']['ShippingFrom'][$row['Country']]++;
193
            } else {
194
                $_SESSION['AdditionalFilterCounters']['ShippingFrom'][$row['Country']] = 1;
195
                $_SESSION['AdditionalFilters']['ShippingFrom'][$row['Country']] = true;
196
            }
65 - 197
        }
198
    }
23 - 199
 
66 - 200
    if (isset($_SESSION['AdditionalFilters']['Merchant'])) {
201
        ksort($_SESSION['AdditionalFilters']['Merchant'], SORT_NATURAL | SORT_FLAG_CASE);
202
    }
203
 
204
    if (isset($_SESSION['AdditionalFilters']['Seller'])) {
205
        ksort($_SESSION['AdditionalFilters']['Seller'], SORT_NATURAL | SORT_FLAG_CASE);
206
    }
207
 
208
    if (isset($_SESSION['AdditionalFilters']['Condition'])) {
209
        ksort($_SESSION['AdditionalFilters']['Condition'], SORT_NATURAL | SORT_FLAG_CASE);
210
    }
211
 
212
    if (isset($_SESSION['AdditionalFilters']['DetailCondition'])) {
213
        ksort($_SESSION['AdditionalFilters']['DetailCondition'], SORT_NATURAL | SORT_FLAG_CASE);
214
    }
215
 
216
    if (isset($_SESSION['AdditionalFilters']['ShippingFrom'])) {
217
        ksort($_SESSION['AdditionalFilters']['ShippingFrom'], SORT_NATURAL | SORT_FLAG_CASE);
218
    }
219
 
220
    if (isset($_SESSION['AdditionalFilters']['MediaType'])) {
221
        ksort($_SESSION['AdditionalFilters']['MediaType'], SORT_NATURAL | SORT_FLAG_CASE);
222
    }
223
 
21 - 224
    return $arr;
225
}
226
 
66 - 227
// filter view result table $_SESSION["resultArr"] for detailed filter selection
228
function detailFilterResults($selArr) {
67 - 229
    if (!empty($selArr['filterCondition'])) {
230
        foreach($_SESSION['AdditionalFilters']['Condition'] as $key => $value) {
231
            $_SESSION['AdditionalFilters']['Condition'][$key] = false;
232
        }
233
        if (!is_array($selArr['filterCondition'])) { $selArr['filterCondition'] = [ $selArr['filterCondition'] ];}
234
        foreach($selArr['filterCondition'] as $value) {
235
            $_SESSION['AdditionalFilters']['Condition'][$value] = true;
236
        }
237
    } else {
68 - 238
        $selArr['filterCondition'] = [];
77 - 239
        if (!empty($_SESSION['AdditionalFilters']['Condition'])) {
240
            foreach($_SESSION['AdditionalFilters']['Condition'] as $key => $value) {
241
                if ($value) {
242
                    $selArr['filterCondition'][] = $key;
243
                }
68 - 244
            }
245
        }
66 - 246
    }
247
 
67 - 248
    if (!empty($selArr['filterMediaType'])) {
249
        foreach($_SESSION['AdditionalFilters']['MediaType'] as $key => $value) {
250
            $_SESSION['AdditionalFilters']['MediaType'][$key] = false;
251
        }
252
        if (!is_array($selArr['filterMediaType'])) { $selArr['filterMediaType'] = [ $selArr['filterMediaType'] ];}
253
        foreach($selArr['filterMediaType'] as $value) {
254
            $_SESSION['AdditionalFilters']['MediaType'][$value] = true;
255
        }
256
    } else {
68 - 257
        $selArr['filterMediaType'] = [];
77 - 258
        if (!empty($_SESSION['AdditionalFilters']['MediaType'])) {
259
            foreach($_SESSION['AdditionalFilters']['MediaType'] as $key => $value) {
260
                if ($value) {
261
                    $selArr['filterMediaType'][] = $key;
262
                }
68 - 263
            }
264
        }
66 - 265
    }
266
 
67 - 267
    if (!empty($selArr['filterShipFrom'])) {
268
        foreach($_SESSION['AdditionalFilters']['ShippingFrom'] as $key => $value) {
269
            $_SESSION['AdditionalFilters']['ShippingFrom'][$key] = false;
270
        }
271
        if (!is_array($selArr['filterShipFrom'])) { $selArr['filterShipFrom'] = [ $selArr['filterShipFrom'] ];}
272
        foreach($selArr['filterShipFrom'] as $value) {
273
            $_SESSION['AdditionalFilters']['ShippingFrom'][$value] = true;
274
        }
275
    } else {
68 - 276
        $selArr['filterShipFrom'] = [];
77 - 277
        if (!empty($_SESSION['AdditionalFilters']['ShippingFrom'])) {
278
            foreach($_SESSION['AdditionalFilters']['ShippingFrom'] as $key => $value) {
279
                if ($value) {
280
                    $selArr['filterShipFrom'][] = $key;
281
                }
68 - 282
            }
283
        }
66 - 284
    }
285
 
67 - 286
    if (!empty($selArr['filterMerchant'])) {
287
        foreach($_SESSION['AdditionalFilters']['Merchant'] as $key => $value) {
288
            $_SESSION['AdditionalFilters']['Merchant'][$key] = false;
289
        }
290
        if (!is_array($selArr['filterMerchant'])) { $selArr['filterMerchant'] = [ $selArr['filterMerchant'] ];}
291
        foreach($selArr['filterMerchant'] as $value) {
292
            $_SESSION['AdditionalFilters']['Merchant'][$value] = true;
293
        }
294
    } else {
68 - 295
        $selArr['filterMerchant'] = [];
77 - 296
        if (!empty($_SESSION['AdditionalFilters']['Merchant'])) {
297
            foreach($_SESSION['AdditionalFilters']['Merchant'] as $key => $value) {
298
                if ($value) {
299
                    $selArr['filterMerchant'][] = $key;
300
                }
68 - 301
            }
302
        }
66 - 303
    }
304
 
305
    foreach ($_SESSION["resultArr"] as & $row) {
306
        $row["Show"] = true;
307
 
308
        if (!in_array($row["Condition"], $selArr['filterCondition']) ||
309
            !in_array($row["MediaType"], $selArr['filterMediaType']) ||
310
            !in_array($row["Merchant"], $selArr['filterMerchant']) ||
311
            !in_array($row["Country"], $selArr['filterShipFrom'])) {
312
            $row["Show"] = false;
313
        }
314
    }
315
}
316
 
317
function resetDetailFilter() {
318
    if (isset($_SESSION['AdditionalFilters']['Merchant'])) {
319
        foreach($_SESSION['AdditionalFilters']['Merchant'] as $key => $field) {
320
            $_SESSION['AdditionalFilters']['Merchant'][$key] = true;
321
        }
322
    }
323
 
324
    if (isset($_SESSION['AdditionalFilters']['Seller'])) {
325
        foreach($_SESSION['AdditionalFilters']['Seller'] as $key => $field) {
326
            $_SESSION['AdditionalFilters']['Seller'][$key] = true;
327
        }
328
    }
329
 
330
    if (isset($_SESSION['AdditionalFilters']['Condition'])) {
331
        foreach($_SESSION['AdditionalFilters']['Condition'] as $key => $field) {
332
            $_SESSION['AdditionalFilters']['Condition'][$key] = true;
333
        }
334
    }
335
 
336
    if (isset($_SESSION['AdditionalFilters']['DetailCondition'])) {
337
        foreach($_SESSION['AdditionalFilters']['DetailCondition'] as $key => $field) {
338
            $_SESSION['AdditionalFilters']['DetailCondition'][$key] = true;
339
        }
340
    }
341
 
342
    if (isset($_SESSION['AdditionalFilters']['ShippingFrom'])) {
343
        foreach($_SESSION['AdditionalFilters']['ShippingFrom'] as $key => $field) {
344
            $_SESSION['AdditionalFilters']['ShippingFrom'][$key] = true;
345
        }
346
    }
347
 
348
    if (isset($_SESSION['AdditionalFilters']['MediaType'])) {
349
        foreach($_SESSION['AdditionalFilters']['MediaType'] as $key => $field) {
350
            $_SESSION['AdditionalFilters']['MediaType'][$key] = true;
351
        }
352
    }
107 - 353
 
66 - 354
    foreach ($_SESSION["resultArr"] as & $row) {
355
        $row["Show"] = true;
356
    }
357
}
358
 
65 - 359
// print result table or card deck
59 - 360
function printResult() {
361
    if ($_SESSION["currentLayout"] == 'TableView') {
78 - 362
        return buildTable($_SESSION["resultArr"]);
65 - 363
    }
364
    else /* CardView */ {
78 - 365
        return buildCardDeck($_SESSION["resultArr"]);
59 - 366
    }
367
}
368
 
65 - 369
// build HTML table from array
78 - 370
function buildTable($arr) {
86 - 371
    global $buyItNowTooltip;
127 - 372
 
373
    $xh = new Html;
374
    $xh->init($_SESSION["htmlIndent"]);
375
 
78 - 376
    if (count($arr) > 0) {
127 - 377
        $xh->add_attribute("class", "table");
378
        $xh->tag('div');
379
        $xh->add_attribute("class", "table table-striped table-condensed table-hover small");
130 - 380
        $xh->add_attribute("id", "storeOfferTable");
127 - 381
        $xh->tag('table');
382
        $xh->add_attribute("class", "thead-dark table-header-sticky");
383
        $xh->tag('thead');
384
        $xh->tag('tr');
17 - 385
 
127 - 386
        $xh->tag('th', "Image");
387
        $xh->add_attribute("class", "text-left");
388
        $xh->tag('th', "Title / Merchant");
389
        $xh->tag('th', "Condition");
390
        $xh->add_attribute("class", "hide-small");
391
        $xh->tag('th', "Price");
392
        $xh->add_attribute("class", "hide-small");
393
        $xh->tag('th', "S/H");
394
        $xh->tag('th', "Total");
395
        $xh->add_attribute("class", "hide-extra-small");
396
        $xh->tag('th', "");
397
 
398
        $xh->close(); // tr
399
        $xh->close(); // thead
400
 
401
        $xh->tag('tbody');
402
 
78 - 403
        foreach ($arr as $row) {
65 - 404
            if (!$row["Show"]) {
405
                continue;
406
            }
1 - 407
 
59 - 408
            $title = $row["Title"];
409
            if (mb_strlen($row["Title"], 'UTF-8') > MAXTITLELENGTH) {
65 - 410
                $title = mb_substr($row["Title"], 0, MAXTITLELENGTH, 'UTF-8') . '...';
59 - 411
            }
124 - 412
            $title = htmlentities($title);
5 - 413
 
127 - 414
            $xh->add_attribute("class", "border");
130 - 415
            $xh->add_attribute("data-url", $row["URL"]);
416
            $xh->add_attribute("data-merchant", $row["Merchant"]);
127 - 417
            $xh->tag('tr');
13 - 418
 
9 - 419
            // Image
127 - 420
            $xh->tag('td');
421
            $xh->add_attribute("href", htmlentities($row["URL"]));
422
            $xh->add_attribute("target", "_blank");
423
            $xh->add_attribute("rel", "sponsored noreferrer noopener");
424
            $xh->add_attribute("data-toggle", "tooltip");
425
            $xh->add_attribute("title", $buyItNowTooltip);
426
            $xh->tag('a');
133 - 427
            $xh->add_attribute("class", "affiliate-link-table img-fluid result-table-image lazyload");
127 - 428
            $xh->add_attribute("src",PIXEL);
429
            $xh->add_attribute("data-src", htmlentities($row["Image"]));
430
            $xh->add_attribute("alt", "Item Image");
431
            $xh->single_tag('img');
432
            $xh->close(); // a
433
            $xh->close(); // td
1 - 434
 
9 - 435
            // Title / Merchant
127 - 436
            $xh->add_attribute("class", "text-left");
437
            $xh->tag('td');
438
            $xh->add_attribute("class", "font-weight-bold");
439
            $xh->tag('span');
133 - 440
            $xh->add_attribute("class", "affiliate-link-table");
127 - 441
            $xh->add_attribute("href", htmlentities($row["URL"]));
442
            $xh->add_attribute("target", "_blank");
443
            $xh->add_attribute("rel", "sponsored noreferrer noopener");
444
            $xh->add_attribute("data-toggle", "tooltip");
445
            $xh->add_attribute("title",$buyItNowTooltip);
446
            $xh->tag('a', $title);
447
            $xh->close(); // span
448
            $xh->brnl();
449
            $xh->brnl();
450
            $xh->add_attribute("class", "font-weight-bold");
451
            $xh->tag('span', htmlentities($row["Merchant"]));
65 - 452
            if ($row["FeedbackScore"] != - 1) {
127 - 453
                $xh->brnl();
454
                $xh->add_attribute("class", "hide-extra-small");
455
                $xh->tag('span', htmlentities($row["SellerName"]) . " (" . number_format($row["FeedbackScore"], 0, "", ", ") . " / " . $row["FeedbackPercent"] . "%)");
65 - 456
            }
457
            else if (!empty($row["SellerName"])) {
127 - 458
                $xh->brnl();
459
                $xh->add_attribute("class", "hide-extra-small");
460
                $xh->tag('span', htmlentities($row["SellerName"]));
65 - 461
            }
462
            if (!empty($row["TimeLeft"])) {
127 - 463
                $xh->brnl();
464
                $xh->tag('span', $row["TimeLeft"]);
65 - 465
            }
127 - 466
            $xh->close(); // td
1 - 467
 
9 - 468
            // Condition
127 - 469
            $xh->add_attribute("class", "text-center");
470
            $xh->tag('td');
471
            $xh->add_attribute("class", "font-weight-bold");
472
            $xh->tag('span', $row["DetailCondition"]);
473
            $xh->brnl();
474
            $xh->brnl();
475
            $xh->add_attribute("class",getMediaIconClass($row["MediaType"], "media-icon"));
476
            $xh->add_attribute("title",getMediaIconText($row["MediaType"]));
477
            $xh->add_attribute("data-toggle", "tooltip");
478
            $xh->add_attribute("data-placement", "right");
479
            $xh->add_attribute("data-delay", "200");
480
            $xh->tag('i', getMediaIconAlias($row["MediaType"]));
481
            $xh->close(); // td
5 - 482
 
9 - 483
            // Price
127 - 484
            $str = print_monetary($row["Price"], $row["Currency"]);
65 - 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
            }
127 - 491
            $xh->add_attribute("class", "hide-small");
492
            $xh->tag('td', $str);
1 - 493
 
9 - 494
            // Shipping and Handling Cost
127 - 495
            $str = "";
65 - 496
            if ($row["ShippingCost"] == 0.00) {
497
                $str .= "Free Shipping";
498
            }
499
            else {
500
                $str .= print_monetary($row["ShippingCost"], $row["ShippingCurrency"]);
81 - 501
                if ($row["ShippingEstimated"]) {
502
                    $str .= "*";
503
                }
65 - 504
            }
505
            if ($row["ShippingCost"] > 0.00 && $row["ShippingCurrency"] != $_SESSION["buyer"]["Currency"]) {
506
                $str .= "<br/>&asymp; " . print_monetary($row["ConvertedShippingCost"], $_SESSION["buyer"]["Currency"]);
507
            }
24 - 508
            if ($row["HandlingTime"] > 0) {
509
                $str .= "<br>Handling Time " . $row["HandlingTime"] . " day" . ($row["HandlingTime"] > 1 ? "s" : "");
510
            }
511
            if ($row["ShippingCost"] > 0.00 && $row["FreeShippingCap"] > 0) {
512
                $str .= "<br>Free Shipping over " . print_monetary($row["FreeShippingCap"], $_SESSION["buyer"]["Currency"]);
513
            }
127 - 514
            $str .= "<br/>";
515
            $xh->add_attribute("class", "hide-small");
516
            $xh->tag('td');
517
            $xh->tag('span', $str);
518
            $xh->add_attribute("class", "img-fluid lazyload");
519
            $xh->add_attribute("title", "Ships from " . getCountry($row["Country"]));
520
            $xh->add_attribute("data-toggle", "tooltip");
521
            $xh->add_attribute("data-placement", "right");
522
            $xh->add_attribute("data-delay", "200");
523
            $xh->add_attribute("src",PIXEL);
524
            $xh->add_attribute("data-src", timeStampUrl("images/flags/" . $row["Country"] . ".png"));
525
            $xh->add_attribute("alt", getCountry($row["Country"]) . " Flag");
526
            $xh->single_tag('img');
527
            $xh->close(); // td
1 - 528
 
9 - 529
            // Total Price
127 - 530
            $xh->add_attribute("class", "font-weight-bolder");
531
            $xh->tag('td', print_monetary($row["ConvertedTotalPrice"], $_SESSION["buyer"]["Currency"]));
1 - 532
 
9 - 533
            // Link
54 - 534
            if ($row["Merchant"] == "iTunes") {
66 - 535
                if ($row["MediaType"] == "Digital") {
127 - 536
                    $linkImage = timeStampUrl("images/US-UK_Apple_Music_Badge_RGB.svg");
65 - 537
                }
538
                else {
127 - 539
                    $linkImage = timeStampUrl("images/US_UK_Apple_Books_Badge_Get_RGB_071818.svg");
54 - 540
                }
127 - 541
                $class = "btn";
542
                $altText = "iTunes Badge";
81 - 543
            } else if (strpos($row["Merchant"], "eBay") !== false) {
127 - 544
                $class = "btn";
545
                $altText = "eBay Store";
546
                $linkImage = timeStampUrl("images/ebay-right-now.gif");
81 - 547
            } else if (strpos($row["Merchant"], "Amazon") !== false) {
127 - 548
                $class = "btn";
549
                $altText = "Amazon Store";
550
                $linkImage = timeStampUrl("images/amazon-buy3.gif");
81 - 551
            } else {
127 - 552
                $class = "btn btn-success";
553
                $altText = "";
554
                $linkImage = "";
54 - 555
            }
127 - 556
            $xh->add_attribute("class", "hide-extra-small text-center");
557
            $xh->tag('td');
130 - 558
            $xh->add_attribute("class", $class);
127 - 559
            $xh->add_attribute("title", $buyItNowTooltip);
560
            $xh->add_attribute("aria-label", "Go to store");
561
            $xh->add_attribute("data-toggle", "tooltip");
562
            $xh->add_attribute("role", "button");
130 - 563
            $xh->add_attribute("href", htmlentities($row["URL"]));
127 - 564
            $xh->add_attribute("target", "_blank");
565
            $xh->add_attribute("rel", "sponsored noreferrer noopener");
566
            $xh->tag('a');
567
            if (empty($linkImage)) {
133 - 568
                $xh->add_attribute("class", "affiliate-link-table material-icons md-36");
127 - 569
                $xh->tag('i', "store");
570
            } else {
133 - 571
                $xh->add_attribute("class", "affiliate-link-table lazyload");
130 - 572
                $xh->add_attribute("src", PIXEL);
127 - 573
                $xh->add_attribute("data-src", $linkImage);
130 - 574
                $xh->add_attribute("alt", $altText);
127 - 575
                $xh->single_tag('img');
576
            }
577
            $xh->close(); // a
578
            $xh->close(); // td
1 - 579
 
127 - 580
            $xh->close(); // tr
9 - 581
        }
17 - 582
 
127 - 583
        $xh->close(); // tbody
584
 
585
        $xh->add_attribute("class", "text-right");
586
        $xh->tag('tfoot');
587
        $xh->add_attribute("class", "border");
588
        $xh->tag('tr');
589
        $xh->add_attribute("class", "font-italic");
590
        $xh->add_attribute("colspan", "7");
591
        $xh->tag('td', "Prices retrieved on " . gmdate("Y-m-d H:i") . " UTC<br>Daily exchange rates update");
592
        $xh->close(); // tr
593
        $xh->close(); // tfoot
594
        $xh->close(); // table
130 - 595
 
127 - 596
        $xh->close(); // div
597
 
598
        $html = $xh->flush();
599
        //error_log(print_r($html, 1));
65 - 600
    }
601
    else {
127 - 602
        $html = printNoResultsWarning();
9 - 603
    }
1 - 604
 
127 - 605
    return ($html);
59 - 606
}
1 - 607
 
65 - 608
// build HTML card deck from array
78 - 609
function buildCardDeck($arr) {
86 - 610
    global $buyItNowTooltip;
66 - 611
 
127 - 612
    $xh = new Html;
613
    $xh->init($_SESSION["htmlIndent"]);
614
 
78 - 615
    if (count($arr) > 0) {
127 - 616
        $xh->add_attribute("class", "card-deck small");
130 - 617
        $xh->add_attribute("id", "storeOfferCards");
127 - 618
        $xh->tag('div');
59 - 619
 
78 - 620
        foreach ($arr as $row) {
65 - 621
            if (!$row["Show"]) {
622
                continue;
623
            }
59 - 624
 
124 - 625
            $href = "href=\"" . htmlentities($row["URL"]) . "\" target=\"_blank\" rel=\"sponsored noreferrer noopener\"";
59 - 626
            $title = $row["Title"];
627
            if (mb_strlen($row["Title"], 'UTF-8') > MAXTITLELENGTH) {
65 - 628
                $title = mb_substr($row["Title"], 0, MAXTITLELENGTH, 'UTF-8') . '...';
59 - 629
            }
124 - 630
            $title = htmlentities($title);
59 - 631
 
127 - 632
            $xh->add_attribute("class", "card m-2 shadow mx-auto result-card");
130 - 633
            $xh->add_attribute("data-url", $row["URL"]);
634
            $xh->add_attribute("data-merchant", $row["Merchant"]);
127 - 635
            $xh->tag('div');
59 - 636
 
637
            // Image
127 - 638
              $xh->add_attribute("class", "p-0 m-0 text-center");
639
              $xh->add_attribute("href", htmlentities($row["URL"]));
640
              $xh->add_attribute("target", "_blank");
641
              $xh->add_attribute("rel", "sponsored noreferrer noopener");
642
              $xh->add_attribute("data-toggle", "tooltip");
643
              $xh->add_attribute("title", $buyItNowTooltip);
644
              $xh->tag('a');
133 - 645
                $xh->add_attribute("class", "affiliate-link-card p-0 m-0 responsive-image result-card-image lazyload");
130 - 646
                $xh->add_attribute("src", PIXEL);
127 - 647
                $xh->add_attribute("data-src", htmlentities($row["Image"]));
648
                $xh->add_attribute("alt", $title . " Item Image");
649
                $xh->single_tag('img');
650
              $xh->close(); // a
59 - 651
 
127 - 652
              $xh->add_attribute("class", "card-body d-flex flex-column");
653
              $xh->tag('div');
654
 
59 - 655
            // Title / Merchant
127 - 656
              $xh->add_attribute("class", "card-title font-weight-bold");
657
              $xh->tag('p');
133 - 658
                $xh->add_attribute("class", "affiliate-link-card");
127 - 659
                $xh->add_attribute("href", htmlentities($row["URL"]));
660
                $xh->add_attribute("target", "_blank");
661
                $xh->add_attribute("rel", "sponsored noreferrer noopener");
662
                $xh->add_attribute("data-toggle", "tooltip");
663
                $xh->add_attribute("title", $buyItNowTooltip);
664
                $xh->tag('a', $title);
665
              $xh->close(); // p
666
              $xh->add_attribute("class", "card-text mt-auto");
667
              $xh->tag('div');
668
                $xh->add_attribute("class", "font-weight-bold");
669
                $xh->tag('span', htmlentities($row["Merchant"]));
670
                $xh->brnl();
59 - 671
 
66 - 672
            // Condition / MediaType
127 - 673
                $xh->tag('span', $row["DetailCondition"]);
674
                $xh->add_attribute("class", getMediaIconClass($row["MediaType"], "media-icon float-right"));
675
                $xh->add_attribute("title", getMediaIconText($row["MediaType"]));
676
                $xh->add_attribute("data-toggle", "tooltip");
677
                $xh->add_attribute("data-placement", "right");
678
                $xh->add_attribute("data-delay", "200");
679
                $xh->tag('i', getMediaIconAlias($row["MediaType"]));
680
                $xh->brnl();
59 - 681
 
682
            // Total Price
127 - 683
                $xh->add_attribute("class", "font-weight-bolder");
684
                $xh->tag('span', print_monetary($row["ConvertedTotalPrice"], $_SESSION["buyer"]["Currency"]));
685
            $xh->close(); // div
59 - 686
 
127 - 687
            $xh->close(); // div
59 - 688
 
689
            // Link / Ships from Flag
127 - 690
            $xh->add_attribute("class", "card-footer");
691
            $xh->tag('div');
692
            $xh->add_attribute("class", "row");
693
            $xh->tag('div');
694
            $xh->add_attribute("class", "col-9");
695
            $xh->tag('div');
59 - 696
            if ($row["Merchant"] == "iTunes") {
66 - 697
                if ($row["MediaType"] == "Digital") {
127 - 698
                    $linkImage = timeStampUrl("images/US-UK_Apple_Music_Badge_RGB.svg");
65 - 699
                }
700
                else {
127 - 701
                    $linkImage = timeStampUrl("images/US_UK_Apple_Books_Badge_Get_RGB_071818.svg");
59 - 702
                }
127 - 703
                $class = "btn p-0 m-0";
704
                $altText = "iTunes Badge";
81 - 705
            } else if (strpos($row["Merchant"], "eBay") !== false) {
127 - 706
                $class = "btn p-0 m-0";
707
                $altText = "eBay Store";
708
                $linkImage = timeStampUrl("images/ebay-right-now.gif");
81 - 709
            } else if (strpos($row["Merchant"], "Amazon") !== false) {
127 - 710
                $class = "btn p-0 m-0";
711
                $altText = "Amazon Store";
712
                $linkImage = timeStampUrl("images/amazon-buy3.gif");
713
            } else {
714
                $class = "btn btn-success m-0";
715
                $altText = "";
716
                $linkImage = "";
65 - 717
            }
127 - 718
 
133 - 719
            $xh->add_attribute("class", "affiliate-link-card " . $class);
127 - 720
            $xh->add_attribute("title", $buyItNowTooltip);
721
            $xh->add_attribute("aria-label", "Go to store");
722
            $xh->add_attribute("data-toggle", "tooltip");
723
            $xh->add_attribute("role", "button");
724
            $xh->add_attribute("href",htmlentities($row["URL"]));
725
            $xh->add_attribute("target", "_blank");
726
            $xh->add_attribute("rel", "sponsored noreferrer noopener");
727
            $xh->tag('a');
728
            if (empty($linkImage)) {
133 - 729
                $xh->add_attribute("class", "affiliate-link-card material-icons md-36");
127 - 730
                $xh->tag('i', "store");
731
            } else {
133 - 732
                $xh->add_attribute("class", $class . " affiliate-link-card img-fluid p-0 m-0 lazyload");
127 - 733
                $xh->add_attribute("src",PIXEL);
734
                $xh->add_attribute("data-src", $linkImage);
735
                $xh->add_attribute("alt",$altText);
736
                $xh->single_tag('img');
59 - 737
            }
127 - 738
            $xh->close(); // a
739
            $xh->close(); // div
740
            $xh->add_attribute("class", "col-3");
741
            $xh->tag('div');
742
              $xh->add_attribute("class", "float-right lazyload");
743
              $xh->add_attribute("title", "Ships from " . getCountry($row["Country"]));
744
              $xh->add_attribute("data-toggle", "tooltip");
745
              $xh->add_attribute("data-placement", "right");
746
              $xh->add_attribute("data-delay", "200");
747
              $xh->add_attribute("src",PIXEL);
748
              $xh->add_attribute("data-src", timeStampUrl("images/flags/" . $row["Country"] . ".png"));
749
              $xh->add_attribute("alt", getCountry($row["Country"]) . " Flag");
750
              $xh->single_tag('img');
751
            $xh->close(); // div
752
            $xh->close(); // div
753
            $xh->close(); // div
59 - 754
 
127 - 755
            $xh->close(); // div
59 - 756
        }
757
 
127 - 758
        $xh->close(); // div
759
 
760
        $xh->add_attribute("class", "py-2 text-right");
761
        $xh->tag('div');
762
        $xh->add_attribute("class", "py-2 font-italic");
763
        $xh->tag('p', "Prices retrieved on " . gmdate("Y-m-d H:i") . " UTC<br>Daily exchange rates update");
764
        $xh->close(); // div
765
 
766
        $html = $xh->flush();
65 - 767
    }
768
    else {
127 - 769
        $html = printNoResultsWarning();
59 - 770
    }
771
 
127 - 772
    //error_log(print_r($html, 1));
5 - 773
 
127 - 774
    return $html;
59 - 775
}
776
 
66 - 777
function printResultHeader() {
127 - 778
    $xh = new Html;
779
    $xh->init($_SESSION["htmlIndent"]);
780
    $xh->add_attribute("class", "navbar bg-dark mt-2 pb-0");
781
    $xh->tag('nav');
782
    $str = "";
113 - 783
    if ($_SESSION["lowestPrice"]["New"] > 0) {
784
        $str .= 'New from ' . print_monetary($_SESSION["lowestPrice"]["New"], $_SESSION["buyer"]["Currency"]);
785
    }
786
    if ($_SESSION["lowestPrice"]["New"] > 0 && $_SESSION["lowestPrice"]["Used"] > 0) {
787
        $str .= '<br>';
788
    }
789
    if ($_SESSION["lowestPrice"]["Used"] > 0) {
790
        $str .= 'Used from ' . print_monetary($_SESSION["lowestPrice"]["Used"], $_SESSION["buyer"]["Currency"]);
791
    }
127 - 792
    $xh->add_attribute("class", "mr-3");
793
    $xh->tag('span', $str);
794
    $xh->add_attribute("class", "nav nav-tabs ml-3");
795
    $xh->tag('ul');
796
    $xh->add_attribute("class", "nav-item border-0");
797
    $xh->tag('li');
798
    $xh->add_attribute("id", "detailTab");
799
    $xh->add_attribute("class", "nav-link active bg-white");
800
    $xh->add_attribute("href", "#detailFilter");
801
    $xh->tag('a');
802
    $xh->tag('span', "Filter");
803
    $xh->add_attribute("id", "detailTabArrow");
804
    $xh->tag('span');
805
    $xh->add_attribute("class", "material-icons material-text");
806
    $xh->tag('i', "expand_more");
807
    $xh->close(); // span
808
    $xh->close(); // a
809
    $xh->close(); // li
810
    $xh->close(); // ul
811
    $xh->add_attribute("class", "ml-auto");
812
    $xh->tag('span');
107 - 813
    if ($_SESSION["currentLayout"] == 'CardView') {
127 - 814
        $xh->add_attribute("id", "resultViewToggle");
134 - 815
        $xh->add_attribute("name", "submitBtn");
127 - 816
        $xh->add_attribute("value", "TableView");
817
        $xh->add_attribute("type", "submit");
818
        $xh->add_attribute("class", "btn btn-sm btn-rounded filterButton btn-info p-0 m-0 active");
819
        $xh->add_attribute("data-toggle", "tooltip");
820
        $xh->add_attribute("title", "Table View");
821
        $xh->add_attribute("aria-label", "Switch to Table View");
822
        $xh->tag('button');
823
        $xh->add_attribute("class", "material-icons md-36");
824
        $xh->tag('i', "view_list");
825
        $xh->close(); // button
107 - 826
    } else {
127 - 827
        $xh->add_attribute("id", "resultViewToggle");
134 - 828
        $xh->add_attribute("name", "submitBtn");
127 - 829
        $xh->add_attribute("value", "CardView");
830
        $xh->add_attribute("type", "submit");
831
        $xh->add_attribute("class", "btn btn-sm btn-rounded filterButton btn-info p-0 m-0 active");
832
        $xh->add_attribute("data-toggle", "tooltip");
833
        $xh->add_attribute("title", "Card View");
834
        $xh->add_attribute("aria-label", "Switch To Card View");
835
        $xh->tag('button');
836
        $xh->add_attribute("class", "material-icons md-36");
837
        $xh->tag('i', "view_module");
838
        $xh->close(); // button
107 - 839
    }
127 - 840
    $xh->close(); // span
66 - 841
 
127 - 842
    $xh->add_attribute("class", "navbar-text float-right ml-3");
843
    $xh->tag('span');
844
    $xh->tag('span', "Showing ");
845
    $xh->add_attribute("class", "d-block d-md-none");
846
    $xh->tag('span', "<br>");
847
    $xh->tag('span', count(array_filter($_SESSION["resultArr"], function ($entry) { return ($entry['Show'] === true); })) . ' of ' . count($_SESSION["resultArr"]));
848
    $xh->close(); // span
849
 
850
    $xh->close(); // nav
851
    $xh->add_attribute("class", "tab-content mb-3");
852
    $xh->tag('div');
853
    $xh->add_attribute("id", "detailFilter");
854
    $xh->add_attribute("class", "container tab-pane");
855
    $xh->tag('div');
856
    $xh->brnl();
857
    $xh->insert_code(detailResultHeader());
858
    $xh->close(); // div
859
    $xh->close(); // div
860
 
861
    $html = $xh->flush();
862
    //error_log(print_r($html, 1));
863
 
864
    return $html;
66 - 865
}
866
 
65 - 867
// print summary/header on top of listing table
66 - 868
function detailResultHeader() {
127 - 869
    $xh = new Html;
870
    $xh->init($_SESSION["htmlIndent"]);
66 - 871
 
127 - 872
    $xh->add_attribute("id", "detailFilterForm");
873
    $xh->tag('form');
874
    $xh->insert_code(inputSessionTab());
875
    $xh->insert_code(inputNonce());
876
    $xh->add_attribute("class", "card-group");
877
    $xh->tag('div');
66 - 878
 
879
    // Condition
880
    if (isset($_SESSION['AdditionalFilterCounters']['Condition'])) {
127 - 881
        $xh->add_attribute("class", "card m-2");
882
        $xh->tag('div');
883
        $xh->add_attribute("class", "card-header font-weight-bold");
884
        $xh->tag('div', "Condition");
885
        $xh->add_attribute("class", "card-body");
886
        $xh->tag('div');
887
 
66 - 888
        $cnt = count($_SESSION['AdditionalFilterCounters']['Condition']);
889
        foreach($_SESSION['AdditionalFilters']['Condition'] as $key => $value) {
127 - 890
            $xh->add_attribute("class", "form-check");
891
            $xh->tag('div');
892
            $xh->add_attribute("class", "form-check-label");
893
            $xh->tag('label');
894
            $xh->add_attribute("name", "filterCondition[]");
895
            $xh->add_attribute("type", "checkbox");
896
            $xh->add_attribute("value", $key);
897
            $xh->add_attribute("class", "form-check-input");
898
            if ($value) $xh->add_attribute("checked", "");
899
            if ($cnt < 1) $xh->add_attribute("disabled", "");
900
            $xh->single_tag('input');
901
            $xh->tag('span', $key);
902
            $xh->add_attribute("class", "badge badge-pill badge-dark ml-2");
903
            $xh->tag('span', $_SESSION['AdditionalFilterCounters']['Condition'][$key]);
904
            $xh->close(); // label
905
            $xh->close(); // div
66 - 906
        }
127 - 907
 
908
        $xh->close(); // div
909
        $xh->close(); // div
13 - 910
    }
66 - 911
 
912
    // Media Type
913
    if (isset($_SESSION['AdditionalFilterCounters']['MediaType'])) {
127 - 914
        $xh->add_attribute("class", "card m-2");
915
        $xh->tag('div');
916
        $xh->add_attribute("class", "card-header font-weight-bold");
917
        $xh->tag('div', "Media Type");
918
        $xh->add_attribute("class", "card-body");
919
        $xh->tag('div');
920
 
66 - 921
        $cnt = count($_SESSION['AdditionalFilterCounters']['MediaType']);
922
        foreach($_SESSION['AdditionalFilters']['MediaType'] as $key => $value) {
127 - 923
            $xh->add_attribute("class", "form-check");
924
            $xh->tag('div');
925
            $xh->add_attribute("class", "form-check-label");
926
            $xh->tag('label');
927
            $xh->add_attribute("name", "filterMediaType[]");
928
            $xh->add_attribute("type", "checkbox");
929
            $xh->add_attribute("value", $key);
930
            $xh->add_attribute("class", "form-check-input");
931
            if ($value) $xh->add_attribute("checked", "");
932
            if ($cnt < 1) $xh->add_attribute("disabled", "");
933
            $xh->single_tag('input');
934
            $xh->add_attribute("class",getMediaIconClass($key, "material-text"));
935
            $xh->tag('i', getMediaIconAlias($key));
936
            $xh->tag('span', getMediaIconText($key));
937
            $xh->add_attribute("class", "badge badge-pill badge-dark ml-2");
938
            $xh->tag('span', $_SESSION['AdditionalFilterCounters']['MediaType'][$key]);
939
            $xh->close(); // label
940
            $xh->close(); // div
66 - 941
        }
127 - 942
 
943
        $xh->close(); // div
944
        $xh->close(); // div
65 - 945
    }
59 - 946
 
66 - 947
    // Merchant
948
    if (isset($_SESSION['AdditionalFilterCounters']['Merchant'])) {
127 - 949
        $xh->add_attribute("class", "card m-2");
950
        $xh->tag('div');
951
        $xh->add_attribute("class", "card-header font-weight-bold");
952
        $xh->tag('div', "Merchant");
953
        $xh->add_attribute("class", "card-body");
954
        $xh->tag('div');
955
 
66 - 956
        $cnt = count($_SESSION['AdditionalFilterCounters']['Merchant']);
957
        foreach($_SESSION['AdditionalFilters']['Merchant'] as $key => $value) {
127 - 958
            $xh->add_attribute("class", "form-check");
959
            $xh->tag('div');
960
            $xh->add_attribute("class", "form-check-label");
961
            $xh->tag('label');
962
            $xh->add_attribute("name", "filterMerchant[]");
963
            $xh->add_attribute("type", "checkbox");
964
            $xh->add_attribute("value", $key);
965
            $xh->add_attribute("class", "form-check-input");
966
            if ($value) $xh->add_attribute("checked", "");
967
            if ($cnt < 1) $xh->add_attribute("disabled", "");
968
            $xh->single_tag('input');
969
            $xh->tag('span', $key);
970
            $xh->add_attribute("class", "badge badge-pill badge-dark ml-2");
971
            $xh->tag('span', $_SESSION['AdditionalFilterCounters']['Merchant'][$key]);
972
            $xh->close(); // label
973
            $xh->close(); // div
66 - 974
        }
127 - 975
 
976
        $xh->close(); // div
977
        $xh->close(); // div
66 - 978
    }
1 - 979
 
66 - 980
    // Shipping From
981
    if (isset($_SESSION['AdditionalFilterCounters']['ShippingFrom'])) {
127 - 982
        $xh->add_attribute("class", "card m-2");
983
        $xh->tag('div');
984
        $xh->add_attribute("class", "card-header font-weight-bold");
985
        $xh->tag('div', "Shipping From");
986
        $xh->add_attribute("class", "card-body");
987
        $xh->tag('div');
988
 
66 - 989
        $cnt = count($_SESSION['AdditionalFilterCounters']['ShippingFrom']);
990
        foreach($_SESSION['AdditionalFilters']['ShippingFrom'] as $key => $value) {
127 - 991
            $xh->add_attribute("class", "form-check");
992
            $xh->tag('div');
993
            $xh->add_attribute("class", "form-check-label");
994
            $xh->tag('label');
995
 
996
            $xh->add_attribute("name", "filterShipFrom[]");
997
            $xh->add_attribute("type", "checkbox");
998
            $xh->add_attribute("value", $key);
999
            $xh->add_attribute("class", "form-check-input");
1000
            if ($value) $xh->add_attribute("checked", "");
1001
            if ($cnt < 1) $xh->add_attribute("disabled", "");
1002
            $xh->single_tag('input');
1003
 
1004
            $xh->add_attribute("class", "img-fluid lazyload");
1005
            $xh->add_attribute("title", "Ships from " . getCountry($key));
1006
            $xh->add_attribute("data-toggle", "tooltip");
1007
            $xh->add_attribute("data-delay", "200");
1008
            $xh->add_attribute("src",PIXEL);
1009
            $xh->add_attribute("data-src", timeStampUrl("images/flags/" . $key . ".png"));
1010
            $xh->add_attribute("alt", getCountry($key) . " Flag");
1011
            $xh->single_tag('img');
1012
 
1013
            $xh->add_attribute("class", "badge badge-pill badge-dark ml-2");
1014
            $xh->tag('span', $_SESSION['AdditionalFilterCounters']['ShippingFrom'][$key]);
1015
 
1016
            $xh->close(); // label
1017
            $xh->close(); // div
66 - 1018
        }
127 - 1019
 
1020
        $xh->close(); // div
1021
        $xh->close(); // div
66 - 1022
    }
1023
 
127 - 1024
    $xh->close(); // div
1025
    $xh->add_attribute("class", "p-2");
1026
    $xh->tag('div');
1027
    $xh->add_attribute("type", "submit");
134 - 1028
    $xh->add_attribute("id", "detailTabSubmit");
127 - 1029
    $xh->add_attribute("class", "btn btn-success detailFilterButton");
134 - 1030
    $xh->add_attribute("name", "submitBtn");
127 - 1031
    $xh->add_attribute("value", "Apply");
1032
    $xh->tag('button', "Apply");
1033
    $xh->add_attribute("type", "submit");
134 - 1034
    $xh->add_attribute("id", "detailTabReset");
127 - 1035
    $xh->add_attribute("class", "btn btn-danger detailFilterButton");
134 - 1036
    $xh->add_attribute("name", "submitBtn");
127 - 1037
    $xh->add_attribute("value", "Reset");
1038
    $xh->tag('button', "Reset");
1039
    $xh->close(); // div
1040
    $xh->close(); // form
66 - 1041
 
127 - 1042
    $html = $xh->flush();
1043
    //error_log(print_r($html, 1));
1044
 
1045
    return $html;
5 - 1046
}
1 - 1047
 
65 - 1048
// compare price for sort low to high
1049
function compare_price($a, $b) {
1050
    return strnatcmp($a['ConvertedTotalPrice'], $b['ConvertedTotalPrice']);
5 - 1051
}
13 - 1052
 
65 - 1053
// print monetary values with correct symbol and thousands/decimal delimiters
1054
function print_monetary($num, $curr) {
1055
    if ($curr == "USD") {
1056
        return ("$" . number_format($num, 2, '.', ','));
1057
    }
1058
    else if ($curr == "CAD") {
1059
        return ("C $" . number_format($num, 2, '.', ','));
1060
    }
1061
    else if ($curr == "EUR") {
1062
        return (number_format($num, 2, ',', '.') . "&euro;");
1063
    }
1064
    else if ($curr == "GBP") {
1065
        return ("&pound;" . number_format($num, 2, '.', ','));
1066
    }
1067
    else if ($curr == "AUD") {
1068
        return ("AU $" . number_format($num, 2, '.', ','));
1069
    }
1 - 1070
 
65 - 1071
    return ($curr . " " . number_format($num, 2, '.', ','));
5 - 1072
}
1 - 1073
 
65 - 1074
// find lowest used / new prices
66 - 1075
function findLowestCondition($condition) {
65 - 1076
    foreach ($_SESSION["resultArr"] as $row) {
1077
        if (!$row["Show"]) {
1078
            continue;
1079
        }
1 - 1080
 
66 - 1081
        if ($condition == $row["Condition"]) {
65 - 1082
            return ($row["ConvertedTotalPrice"]);
1083
        }
1084
    }
5 - 1085
 
65 - 1086
    return (0);
5 - 1087
}
1088
 
65 - 1089
// find lowest cd, record, digital and book prices
66 - 1090
function findLowestMediaType($mediaType) {
65 - 1091
    foreach ($_SESSION["resultArr"] as $row) {
1092
        if (!$row["Show"]) {
1093
            continue;
1094
        }
20 - 1095
 
66 - 1096
        if ($mediaType == $row["MediaType"]) {
65 - 1097
            return ($row["ConvertedTotalPrice"]);
1098
        }
1099
    }
20 - 1100
 
65 - 1101
    return (0);
20 - 1102
}
1103
 
65 - 1104
// find lowest non-zero double value in array
1105
function minNotNull(Array $values) {
1106
    return min(array_diff(array_map('doubleval', $values) , array(
1107
 
1108
    )));
13 - 1109
}
11 - 1110
 
65 - 1111
// apply exchange rates
1112
function applyExchangeRates($arr) {
1113
    foreach ($arr as & $value) {
1114
        $value["ConvertedPrice"] = $value["Price"];
1115
        $value["ConvertedShippingCost"] = $value["ShippingCost"];
1 - 1116
 
65 - 1117
        if ($_SESSION["buyer"]["Currency"] != $value["Currency"]) {
1118
            $value["ConvertedPrice"] = number_format($value["Price"] / getExchangeRate($_SESSION["buyer"]["Currency"], $value["Currency"]) , 2, '.', '');
1119
        }
1 - 1120
 
65 - 1121
        if ($_SESSION["buyer"]["Currency"] != $value["ShippingCurrency"]) {
1122
            $value["ConvertedShippingCost"] = number_format($value["ShippingCost"] / getExchangeRate($_SESSION["buyer"]["Currency"], $value["ShippingCurrency"]) , 2, '.', '');
1123
        }
1 - 1124
 
65 - 1125
        $value["ConvertedTotalPrice"] = number_format($value["ConvertedPrice"] + $value["ConvertedShippingCost"], 2, '.', '');
1126
    }
5 - 1127
 
65 - 1128
    return ($arr);
5 - 1129
}
1130
 
36 - 1131
// sanitize user input
65 - 1132
function sanitizeInput($data) {
1133
    $data = trim(preg_replace('/[\t\n\r\s]+/', ' ', $data));
1134
    $data = stripslashes($data);
1135
    $data = htmlspecialchars($data);
1136
    return $data;
5 - 1137
}
1 - 1138
 
52 - 1139
// sanitize user input (plus delete apostrophe)
1140
function sanitizeInput2($data) {
65 - 1141
    $data = trim(preg_replace('/[\t\n\r\s\']+/', ' ', $data));
1142
    $data = stripslashes($data);
1143
    $data = htmlspecialchars($data, ENT_QUOTES | ENT_HTML5);
1144
    return $data;
52 - 1145
}
1146
 
14 - 1147
// convert certain utf-8 characters to ascii
1148
function cleanString($str) {
1149
    $utf8 = array(
65 - 1150
        '/[áàâãªä]/u' => 'a',
1151
        '/[ÁÀÂÃÄ]/u' => 'A',
1152
        '/[ÍÌÎÏ]/u' => 'I',
1153
        '/[íìîï]/u' => 'i',
1154
        '/[éèêë]/u' => 'e',
1155
        '/[ÉÈÊË]/u' => 'E',
1156
        '/[óòôõºö]/u' => 'o',
1157
        '/[ÓÒÔÕÖ]/u' => 'O',
1158
        '/[úùûü]/u' => 'u',
1159
        '/[ÚÙÛÜ]/u' => 'U',
1160
        '/ç/' => 'c',
1161
        '/Ç/' => 'C',
1162
        '/ñ/' => 'n',
1163
        '/Ñ/' => 'N',
1164
        '/–/' => '-', // UTF-8 hyphen to "normal" hyphen
1165
        '/[’‘‹›‚]/u' => ' ', // Literally a single quote
1166
        '/[“”«»„]/u' => ' ', // Double quote
1167
        '/ /' => ' ', // nonbreaking space (equiv. to 0x160)
66 - 1168
 
14 - 1169
    );
1170
 
65 - 1171
    return preg_replace(array_keys($utf8) , array_values($utf8) , $str);
14 - 1172
}
1173
 
1174
// Clean the search string
1175
function searchFriendlyString($str) {
1176
    $str = strip_tags($str);
1177
    $str = stripslashes($str);
1178
    $str = cleanString($str);
65 - 1179
    $str = str_replace(array(
1180
        "[",
1181
        "]",
1182
        "<",
1183
        ">",
1184
        "(",
1185
        ")",
1186
        " - ",
1187
        " & ",
1188
        " / "
1189
    ) , " ", $str); // eliminate single '-', '&', '/' and brackets
1190
    $str = trim(preg_replace('/[\t\n\r\s]+/', ' ', $str)); // delete extra whitespaces
14 - 1191
    return ucwords($str);
1192
}
1193
 
65 - 1194
// get a SESSION value, return empty string if not set
1195
function getSV($var) {
1196
    if (!isset($_SESSION[$var])) {
1197
        return ('');
1198
    }
1 - 1199
 
65 - 1200
    return ($_SESSION[$var]);
5 - 1201
}
1202
 
65 - 1203
// initialize a SESSION value if not set
1204
function initSV($var, $value) {
1205
    if (!isset($_SESSION[$var])) {
1206
        $_SESSION[$var] = $value;
1207
    }
5 - 1208
}
1 - 1209
 
65 - 1210
// initialize sessions variables
1211
function initSessionVariables() {
1212
    initSV("resultArr", []);
1213
    initSV("barcode", array(
1214
        "Type" => "",
1215
        "Value" => ""
1216
    ));
1217
    initSV("buyer", array(
1218
        "Country" => "United States",
1219
        "Currency" => "USD",
1220
        "Zip" => ""
1221
    ));
1222
    initSV("filterCondition", array(
1223
        "New" => true,
1224
        "Used" => true
1225
    ));
1226
    initSV("filterMediaType", array(
1227
        "CD" => true,
1228
        "Record" => true,
1229
        "Digital" => true,
1230
        "Book" => true
1231
    ));
1232
    initSV("currentLayout", "TableView");
1233
    initSV("lowestPrice", array(
1234
        "Used" => 0.00,
1235
        "New" => 0.00,
1236
        "CD" => 0.00,
1237
        "Record" => 0.00,
1238
        "Digital" => 0.00,
1239
        "Book" => "0.00",
1240
        "All" => 0.00
1241
    ));
5 - 1242
}
1243
 
14 - 1244
function md5SearchTerm() {
1245
    $data = array();
1246
    $data['cond'] = $_SESSION['filterCondition'];
1247
    $data['type'] = $_SESSION['filterMediaType'];
17 - 1248
    $data['buyer'] = $_SESSION['buyer'];
65 - 1249
    $data['term'] = array(
1250
        $_SESSION['searchTerm']
1251
    );
14 - 1252
 
65 - 1253
    return (md5(json_encode($data)));
14 - 1254
}
1255
 
65 - 1256
// check POST value, return true if set and false if not
1257
function checkPV($var) {
1258
    if (isset($_POST[$var])) {
1259
        return (true);
1260
    }
1 - 1261
 
65 - 1262
    return (false);
5 - 1263
}
1264
 
65 - 1265
// get POST or GET value, return empty if not set
1266
function getPGV($var) {
1267
    if (isset($_POST[$var])) {
1268
        return ($_POST[$var]);
1269
    }
1270
    else if (isset($_GET[$var])) {
1271
        return ($_GET[$var]);
1272
    }
14 - 1273
 
65 - 1274
    return ("");
14 - 1275
}
1276
 
65 - 1277
function saveSearchResult() {
1278
    $conn = MySessionHandler::getDBSessionId();
13 - 1279
 
65 - 1280
    $access = mysqli_real_escape_string($conn, time());
1281
    // BUGBUG
1282
    //  country
1283
    //  currency
1284
    $zip = mysqli_real_escape_string($conn, $_SESSION['buyer']['Zip']);
1285
    $condNew = $_SESSION['filterCondition']['New'] ? 'Y' : 'N';
1286
    $condUsed = $_SESSION['filterCondition']['Used'] ? 'Y' : 'N';
1287
    $mediaCD = $_SESSION['filterMediaType']['CD'] ? 'Y' : 'N';
1288
    $mediaRecord = $_SESSION['filterMediaType']['Record'] ? 'Y' : 'N';
1289
    $mediaDigital = $_SESSION['filterMediaType']['Digital'] ? 'Y' : 'N';
1290
    $mediaBook = $_SESSION['filterMediaType']['Book'] ? 'Y' : 'N';
1291
    $data = mysqli_real_escape_string($conn, $_SESSION['searchTerm']);
1292
    $lowNew = floatval($_SESSION['lowestPrice']['New']);
1293
    $lowUsed = floatval($_SESSION['lowestPrice']['Used']);
116 - 1294
    $lowCD = floatval($_SESSION['lowestPrice']['CD']);
1295
    $lowRecord = floatval($_SESSION['lowestPrice']['Record']);
65 - 1296
    $lowDigital = floatval($_SESSION['lowestPrice']['Digital']);
1297
    $lowBook = floatval($_SESSION['lowestPrice']['Book']);
1298
    $count = count($_SESSION['resultArr']);
1299
    $userId = (empty($_SESSION['sessData']['userID']) ? 'NULL' : $_SESSION['sessData']['userID']);
96 - 1300
    $ip = inet_pton($_SERVER['REMOTE_ADDR']);
8 - 1301
 
65 - 1302
    $sql = "INSERT
20 - 1303
                INTO searches
116 - 1304
                (sessId, access, ip, zip, condNew, condUsed, mediaCD, mediaRecord, mediaDigital, mediaBook, data, lowNew, lowUsed, lowCD, lowRecord, lowDigital, lowBook, count, userId)
1305
                VALUES ('" . session_id() . "', '$access', '$ip', '$zip', '$condNew', '$condUsed', '$mediaCD', '$mediaRecord', '$mediaDigital', '$mediaBook', '$data', $lowNew, $lowUsed, $lowCD, $lowRecord, $lowDigital, $lowBook, $count, $userId)";
8 - 1306
 
65 - 1307
    if (!($result = mysqli_query($conn, $sql))) {
1308
        error_log("MySQL Write Searches Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1309
    }
13 - 1310
 
129 - 1311
 
1312
    return(mysqli_insert_id($conn));
65 - 1313
}
13 - 1314
 
17 - 1315
function getUrl($url, $userAgent = null) {
1316
    $ch = curl_init();
1317
 
1318
    // Set request header with language and charset
1319
    $header = array(
1320
        "Accept-Language: en-US,en;q=0.5",
1321
        "Accept-Charset: UTF-8,*;q=0.5"
1322
    );
1323
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
1324
 
1325
    // Set optional user-agent
1326
    if ($userAgent) {
1327
        curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
1328
    }
1329
 
1330
    curl_setopt($ch, CURLOPT_ENCODING, "gzip,deflate");
1331
    curl_setopt($ch, CURLOPT_AUTOREFERER, true);
1332
    curl_setopt($ch, CURLOPT_HEADER, 0);
84 - 1333
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
1334
    curl_setopt($ch, CURLOPT_TIMEOUT, 15);
17 - 1335
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
1336
    curl_setopt($ch, CURLOPT_URL, $url);
1337
    $response = curl_exec($ch);
1338
    if ($response === false) {
20 - 1339
        error_log('Curl Request Error: ' . curl_error($ch) . ' (' . curl_errno($ch) . ')');
1340
        error_log('Url: ' . $url);
17 - 1341
        $response = '';
1342
    }
23 - 1343
 
17 - 1344
    curl_close($ch);
1345
 
1346
    return $response;
1347
}
1348
 
129 - 1349
function getMultiUrl($urls, $userAgent = null) {
1350
    $multi = curl_multi_init();
1351
    $channels = [];
1352
    $response = [];
1353
    // Set request header with language and charset
1354
    $header = array(
1355
        "Accept-Language: en-US,en;q=0.5",
1356
        "Accept-Charset: UTF-8,*;q=0.5"
1357
    );
1358
 
1359
    // Loop through the URLs, create curl-handles
1360
    // and attach the handles to our multi-request
1361
    foreach ($urls as $url) {
1362
        $ch = curl_init();
1363
 
1364
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
1365
 
1366
        // Set optional user-agent
1367
        if ($userAgent) {
1368
            curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
1369
        }
1370
 
1371
        curl_setopt($ch, CURLOPT_ENCODING, "gzip,deflate");
1372
        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
1373
        curl_setopt($ch, CURLOPT_HEADER, 0);
1374
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
1375
        curl_setopt($ch, CURLOPT_TIMEOUT, 15);
1376
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
1377
        curl_setopt($ch, CURLOPT_URL, $url);
1378
 
1379
        curl_multi_add_handle($multi, $ch);
1380
 
1381
        $channels[$url] = $ch;
1382
    }
1383
 
1384
    // While we're still active, execute curl
1385
    $active = null;
1386
    do {
1387
        $mrc = curl_multi_exec($multi, $active);
1388
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
1389
 
1390
    while ($active && $mrc == CURLM_OK) {
1391
        // Wait for activity on any curl-connection
1392
        if (curl_multi_select($multi) == -1) {
1393
            continue;
1394
        }
1395
 
1396
        // Continue to exec until curl is ready to
1397
        // give us more data
1398
        do {
1399
            $mrc = curl_multi_exec($multi, $active);
1400
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
1401
    }
1402
 
1403
    // Loop through the channels and retrieve the received
1404
    // content, then remove the handle from the multi-handle
1405
    foreach ($channels as $url => $channel) {
1406
        $response[$url] = curl_multi_getcontent($channel);
1407
        if ($response[$url] === false) {
1408
            error_log('Curl Request Error: ' . curl_error($channel) . ' (' . curl_errno($channel) . ')');
1409
            error_log('Url: ' . $url);
1410
            $response[$url] = '';
1411
        }
1412
        curl_multi_remove_handle($multi, $channel);
1413
    }
1414
 
1415
    // Close the multi-handle and return our results
1416
    curl_multi_close($multi);
1417
 
1418
    return($response);
1419
}
1420
 
20 - 1421
// Retrieve search history for current session id
14 - 1422
function getSearchHistory() {
127 - 1423
    $xh = new Html;
1424
    $xh->init($_SESSION["htmlIndent"]);
1425
 
38 - 1426
    $sql = "select data, max(access) from searches where sessId = '" . session_id() . "'";
1427
    if (!empty($_SESSION['sessData']['userID'])) {
1428
        $sql .= " or userID = '" . $_SESSION['sessData']['userID'] . "'";
1429
    }
1430
    $sql .= " group by data order by max(access) desc, data limit 0,30;";
14 - 1431
    $conn = MySessionHandler::getDBSessionId();
1432
 
20 - 1433
    if ($result = mysqli_query($conn, $sql)) {
1434
        if (mysqli_num_rows($result) > 0) {
65 - 1435
            while ($row = mysqli_fetch_assoc($result)) {
127 - 1436
                $xh->tag("option", $row["data"]);
20 - 1437
            }
14 - 1438
        }
1439
    }
65 - 1440
    else if (mysqli_errno($conn)) {
1441
        error_log("MySQL Read Searches SQL: " . $sql);
1442
        error_log("MySQL Read Searches Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1443
    }
14 - 1444
 
127 - 1445
    $html = $xh->flush();
1446
    //error_log(print_r($html, 1));
1447
 
1448
    return $html;
14 - 1449
}
1450
 
41 - 1451
// Retrieve coupons codes
1452
function getCouponCodes() {
1453
    $lastAdvertiser = "";
1454
 
127 - 1455
    $xh = new Html;
1456
    $xh->init($_SESSION["htmlIndent"]);
1457
 
41 - 1458
    if (!isLoggedIn()) {
127 - 1459
        $xh->add_attribute("class", "container bg-warning text-center py-3");
1460
        $xh->tag('div');
1461
            $xh->add_attribute("class", "display-6");
1462
            $xh->tag('p');
1463
                $xh->add_attribute("class", "material-icons");
1464
                $xh->tag('i', "error_outline");
1465
                $xh->tag('span', " Please login to your Find Cheap Music account in order to see the coupons.");
1466
            $xh->close(); // p
1467
        $xh->close(); // div
1468
 
1469
        $html = $xh->flush();
1470
       //error_log(print_r($html, 1));
1471
 
1472
        return $html;
41 - 1473
    }
1474
 
65 - 1475
    $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 - 1476
    $conn = MySessionHandler::getDBSessionId();
1477
 
1478
    if ($result = mysqli_query($conn, $sql)) {
1479
        if (mysqli_num_rows($result) > 0) {
127 - 1480
            $xh->add_attribute("class", "container py-4 border bg-light");
134 - 1481
            $xh->add_attribute("id", "couponList");
127 - 1482
            $xh->tag('div');
65 - 1483
            while ($row = mysqli_fetch_assoc($result)) {
1484
                if ($row["advertiser"] != $lastAdvertiser) {
41 - 1485
                    if (!empty($lastAdvertiser)) {
127 - 1486
                        $xh->close(); // ul
41 - 1487
                    }
127 - 1488
                    $xh->add_attribute("class", "text-center mt-3 mb-1");
1489
                    $xh->tag('h2', $row["advertiser"]);
1490
                    $xh->add_attribute("class", "list-group");
1491
                    $xh->tag('ul');
41 - 1492
                    $lastAdvertiser = $row["advertiser"];
1493
                }
51 - 1494
                if (!empty($row["url"])) {
127 - 1495
                    $xh->add_attribute("class", "list-group-item");
1496
                    $xh->tag('li');
134 - 1497
                        $xh->add_attribute("class", "btn btn-link text-left coupon-link");
127 - 1498
                        $xh->add_attribute("target", "_blank");
1499
                        $xh->add_attribute("href", htmlentities($row["url"]));
1500
                        $xh->add_attribute("rel", "nofollow noreferrer noopener");
134 - 1501
                        $xh->add_attribute("data-advertiser", $row["advertiser"]);
127 - 1502
                        $xh->tag('a');
1503
                            $str = '<strong>' . $row["description"] . '</strong> until ' . $row["enddate"];
1504
                            if (!empty($row["couponcode"])) {
1505
                                $str .= ' (Use Coupon Code "' . $row["couponcode"] . '")';
1506
                            }
1507
                            if (!empty($row["pixel"])) {
1508
                                $xh->add_attribute("class", "border-0 lazyload");
1509
                                $xh->add_attribute("src",PIXEL);
1510
                                $xh->add_attribute("data-src", htmlentities($row["pixel"]));
1511
                                $xh->add_attribute("width", "1");
1512
                                $xh->add_attribute("height", "1");
1513
                                $xh->add_attribute("alt", $row["advertiser"] . " Coupon");
1514
                                $xh->single_tag('img');
1515
                            }
1516
                            $xh->tag('span', $str);
1517
                        $xh->close(); // a
1518
                    $xh->close(); // li
41 - 1519
                }
1520
            }
127 - 1521
 
1522
            if (!empty($lastAdvertiser)) {
1523
                $xh->close(); // ul
1524
            }
134 - 1525
 
1526
    $xh->add_attribute("nonce", base64_encode($_SESSION["nonce"]));
1527
    $xh->tag('script');
1528
        $str  = trim('document.addEventListener("DOMContentLoaded", function() {');
1529
        $str .= trim('    document.getElementById("couponList").addEventListener("click", function(event) {');
1530
        $str .= trim('        e = event.target.closest("a");');
1531
        $str .= trim('        if (e && e.classList.contains("coupon-link")) {');
1532
        $str .= trim('            window.dataLayer.push({ "event" : "trackEvent", "eventCategory" : "Coupon", "eventAction" : "Click", "eventLabel" : e.getAttribute("data-advertiser")});');
1533
        $str .= trim('        }');
1534
        $str .= trim('    });');
1535
        $str .= trim('});');
1536
    $xh->insert_code($str);
1537
    $xh->close(); // script
1538
 
127 - 1539
            $xh->close(); // div
41 - 1540
        }
65 - 1541
    }
1542
    else if (mysqli_errno($conn)) {
127 - 1543
        $xh->add_attribute("class", "container bg-info text-center py-3");
1544
        $xh->tag('div');
1545
            $xh->add_attribute("class", "display-6");
1546
            $xh->tag('p');
1547
                $xh->add_attribute("class", "material-icons");
1548
                $xh->tag('i', "loyalty");
1549
                $xh->tag('span', " No Coupons available at the moment...");
1550
            $xh->close(); // p
1551
        $xh->close(); // div
41 - 1552
    }
1553
 
127 - 1554
    $html = $xh->flush();
1555
    //error_log(print_r($html, 1));
1556
 
1557
    return $html;
41 - 1558
}
1559
 
14 - 1560
// Delete left over progressbar files older than 2 days
1561
function cleanupPbFiles() {
84 - 1562
    $files = glob("../MyFiles/tmp/pb*.txt");
65 - 1563
    $now = time();
14 - 1564
    foreach ($files as $file) {
1565
        if (is_file($file)) {
1566
            if ($now - filemtime($file) >= 60 * 60 * 24 * 2) { // 2 days and older
1567
                unlink($file);
1568
            }
65 - 1569
        }
14 - 1570
    }
1571
}
1572
 
1573
// Update progressbar file for a session
129 - 1574
function updatePbFile($flag = false, $desc = null) {
1575
    static $max_pb = 10; // max progressbar steps
22 - 1576
    static $current = 0;
129 - 1577
    static $lastTime = 0;
1578
    static $startTime = 0;
1579
    static $timers = [];
23 - 1580
 
22 - 1581
    if ($flag) {
129 - 1582
        if ($desc == "Start") {
1583
            $current = 0;
1584
            $timers = [];
1585
            $startTime = $lastTime = microtime(true);
1586
        } else if (strpos($desc, "End:") === 0) {
1587
            $nowTime = microtime(true);
1588
            $timers["Total"] = intval(($nowTime - $startTime) * 1000);
1589
            $pieces = explode(":", $desc);
1590
            savePbTimers($timers, $pieces[1]);
1591
        }
65 - 1592
    }
1593
    else {
22 - 1594
        ++$current;
129 - 1595
        $nowTime = microtime(true);
1596
        $diffTime = $nowTime - $lastTime;
1597
        $lastTime = $nowTime;
1598
        $timers[$desc] = intval($diffTime * 1000);
1599
   }
22 - 1600
 
1601
    if ($current > $max_pb) {
1602
        error_log("max_pb $max_pb is too small, current step is $current. Adjust tools.php (updatePbFile).");
1603
        $max_pb = $current;
1604
    }
65 - 1605
    $filename = session_id() . "_" . MySessionHandler::getSessionTab();
14 - 1606
    $arr_content = array();
1607
 
20 - 1608
    $percent = intval($current / $max_pb * 100);
14 - 1609
 
1610
    $arr_content['percent'] = $percent;
1611
    $arr_content['message'] = $current . " search(es) processed.";
84 - 1612
    $file = "../MyFiles/tmp/pb_" . $filename . ".txt";
14 - 1613
 
77 - 1614
    if ($percent >= 100) {
1615
        @unlink($file);
1616
    } else {
1617
        file_put_contents($file, json_encode($arr_content));
1618
    }
14 - 1619
}
20 - 1620
 
1621
// Linkshare / CJ Affiliate csv dump
1622
function ls_cj_csv($fields) {
1623
    static $fh = null;
1624
    $delimiter = ',';
1625
    $enclosure = '"';
1626
    $mysql_null = false;
1627
 
1628
    if (!$fh) {
1629
        $fh = fopen("ls_cj.csv", "a+");
1630
    }
1631
 
1632
    $delimiter_esc = preg_quote($delimiter, '/');
1633
    $enclosure_esc = preg_quote($enclosure, '/');
1634
 
1635
    $output = array();
1636
    foreach ($fields as $field) {
1637
        if ($field === null && $mysql_null) {
1638
            $output[] = 'NULL';
1639
            continue;
1640
        }
1641
 
65 - 1642
        $output[] = preg_match("/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field) ? ($enclosure . str_replace($enclosure, $enclosure . $enclosure, $field) . $enclosure) : $field;
20 - 1643
    }
1644
 
1645
    fwrite($fh, join($delimiter, $output) . "\n");
1646
}
35 - 1647
 
1648
// Login in check
1649
function isLoggedIn() {
65 - 1650
    return (!empty($_SESSION['sessData']['userLoggedIn']) && !empty($_SESSION['sessData']['userID'])) ? true : false;
35 - 1651
}
1652
 
1653
// unset all login system session data
1654
function unsetSessData() {
1655
    unset($_SESSION['sessData']['userLoggedIn']);
1656
    unset($_SESSION['sessData']['userID']);
1657
    unset($_SESSION['sessData']['loginType']);
36 - 1658
}
1659
 
1660
// get user image name
1661
function getUserImage($userData) {
1662
    if (empty($userData) || empty($userData['picture'])) {
109 - 1663
        return 'login/assets/images/default.png';
36 - 1664
    }
38 - 1665
 
36 - 1666
    $httpPos = strpos($userData['picture'], 'http');
1667
    if ($httpPos === false) {
65 - 1668
        return 'login/' . UPLOAD_PATH . 'profile_picture/' . $userData['picture'];
36 - 1669
    }
1670
 
1671
    return $userData['picture'];
38 - 1672
}
39 - 1673
 
1674
function startsWith($haystack, $needle) {
1675
    return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
1676
}
1677
 
1678
function endsWith($haystack, $needle) {
1679
    return substr_compare($haystack, $needle, -strlen($needle)) === 0;
45 - 1680
}
50 - 1681
 
1682
function displayBarcode($barcode) {
1683
    $barcode = trim(preg_replace("/[^0-9]/", "", $barcode));
1684
    $barcodeType = clsLibGTIN::GTINCheck($barcode, false, 1);
1685
 
1686
    if ($barcodeType == "UPC" && strlen($barcode) == 12) {
1687
        return substr($barcode, 0, 1) . "-" . substr($barcode, 1, 5) . "-" . substr($barcode, 6, 5) . "-" . substr($barcode, 11, 1);
65 - 1688
    }
1689
    else if (($barcodeType == "EAN" || $barcodeType == "ISBN") && strlen($barcode) == 13) {
50 - 1690
        return substr($barcode, 0, 1) . "-" . substr($barcode, 1, 6) . "-" . substr($barcode, 7, 6);
65 - 1691
    }
1692
    else if ($barcodeType == "EAN" && strlen($barcode) == 14) {
50 - 1693
        return substr($barcode, 0, 1) . "-" . substr($barcode, 1, 2) . "-" . substr($barcode, 3, 5) . "-" . substr($barcode, 8, 5) . "-" . substr($barcode, 13, 1);
65 - 1694
    }
1695
    else {
50 - 1696
        return $barcode;
1697
    }
52 - 1698
}
93 - 1699
 
1700
// fuzzy search to verify titles are relevant
1701
function verifyResultArr() {
1702
    require_once ('php/Fuse/Bitap/Bitap.php');
1703
    require_once ('php/Fuse/Bitap/matched_indices.php');
1704
    require_once ('php/Fuse/Bitap/pattern_alphabet.php');
1705
    require_once ('php/Fuse/Bitap/regex_search.php');
1706
    require_once ('php/Fuse/Bitap/score.php');
1707
    require_once ('php/Fuse/Bitap/search.php');
1708
    require_once ('php/Fuse/Helpers/deep_value.php');
1709
    require_once ('php/Fuse/Helpers/is_list.php');
1710
    require_once ('php/Fuse/Fuse.php');
1711
 
1712
    if (!empty($_SESSION["barcode"]["Value"]) || empty($_SESSION["resultArr"])) {
1713
        return;
1714
    }
1715
 
1716
    $options = [
1717
      'shouldSort' => false,
1718
    //  'tokenize' => true,
1719
    //  'matchAllTokens' => true,
1720
    //  'findAllMatches' => true,
1721
      'includeScore' => true,
1722
      'includeMatches' => true,
1723
      'threshold' => 0.6,
1724
      'location' => 0,
1725
      'distance' => 100,
1726
      'minMatchCharLength' => 5,
1727
      'keys' => [ "Title" ]
1728
    ];
1729
 
1730
    $fuse = new Fuse($_SESSION["resultArr"], $options);
1731
    $result = $fuse->search($_SESSION["searchTerm"]);
1732
 
1733
    $_SESSION["resultArr"] = [];
1734
    foreach($result as $r) {
97 - 1735
        $r['item']['score'] = (!empty($r['score']) ? $r['score'] : 0);
1736
        $r['item']['indices'] = (!empty($r['matches'][0]['indices']) ? $r['matches'][0]['indices'] : []);
93 - 1737
        $_SESSION['resultArr'][] = $r['item'];
1738
    }
1739
 
1740
    /* debug start
1741
    $lines = [];
1742
    foreach($_SESSION['resultArr'] as $r) {
1743
        $p = 0;
1744
        $t = '';
1745
        foreach($r['indices'] as $ind) {
1746
            if ($p < $ind[0]) {
1747
                $t .= substr($r['Title'], $p, $ind[0] - $p);
1748
            }
1749
            $t .= "<b>" . substr($r['Title'], $ind[0], $ind[1] - $ind[0] + 1) . "</b>";
1750
            $p = $ind[1] + 1;
1751
        }
1752
        if ($p < strlen($r['Title'])) {
1753
            $t .= substr($r['Title'], $p);
1754
        }
1755
        $lines[] = array ('score' => $r['score'], 'title' => $t);
1756
    }
1757
 
1758
    usort($lines, 'compare_score');
1759
    echo "<p>";
1760
    foreach($lines as $l) {
1761
        echo $l['score'] . ": " . $l['title'] . "<br/>";
1762
    }
1763
    echo "</p>";
1764
    debug end */
1765
}
1766
 
1767
// compare score for sort low to high
1768
function compare_score($a, $b) {
1769
    return ($a['score'] > $b['score']);
1770
}
96 - 1771
 
1772
function my_error_log($msg) {
1773
    error_log("[" . date("d-M-Y H:m:s") . "] " . $msg . PHP_EOL, 3, $_SERVER['DOCUMENT_ROOT'] . "/../MyFiles/logs/my_php_error.log");
1774
}
99 - 1775
 
129 - 1776
function savePbTimers($timers, $id) {
1777
    $conn = MySessionHandler::getDBSessionId();
1778
 
1779
    $sql = "INSERT
1780
                INTO searchPerformance
1781
                (id, Discogs, eBay_New, Linkshare, CJ_Affiliate, Walmart, iTunes, Amazon_API, Amazon_Scrape, Impact, eBay_Used, Total)
1782
                VALUES ($id, " . $timers['Discogs'] . ",
1783
" . $timers['eBay New'] . ",
1784
" . $timers['Linkshare'] . ",
1785
" . $timers['CJ Affiliate'] . ",
1786
" . $timers['Walmart'] . ",
1787
" . $timers['iTunes'] . ",
1788
" . $timers['Amazon API'] . ",
1789
" . $timers['Amazon Scrape'] . ",
1790
" . $timers['Impact'] . ",
1791
" . $timers['eBay Used'] . ",
1792
" . $timers['Total'] . ")";
1793
 
1794
    if (!($result = mysqli_query($conn, $sql))) {
1795
        error_log("MySQL Write SearchPerformance Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1796
    }
1797
 
1798
    return $result;
1799
}
1800
 
99 - 1801
function saveSearchCache($vendor, $query, $subquery, $text) {
1802
    $conn = MySessionHandler::getDBSessionId();
1803
 
1804
    $created = mysqli_real_escape_string($conn, time());
1805
    $v = mysqli_real_escape_string($conn, $vendor);
1806
    $q = mysqli_real_escape_string($conn, $query);
1807
    $s = mysqli_real_escape_string($conn, $subquery);
1808
    $r = base64_encode(gzencode($text));
1809
 
1810
    $sql = "INSERT
1811
                INTO searchCache
1812
                (created, vendor, query, subquery, result)
110 - 1813
                VALUES ('$created', '$v', '$q', '$s', '$r')
1814
                ON DUPLICATE KEY UPDATE result = '$r'";
99 - 1815
 
1816
    if (!($result = mysqli_query($conn, $sql))) {
1817
        error_log("MySQL Write SearchCache Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1818
    }
1819
 
1820
    return $result;
1821
}
1822
 
1823
 
1824
function expireSearchCache() {
1825
    $conn = MySessionHandler::getDBSessionId();
1826
    $t = MySessionHandler::getDBExpirationTime();
1827
 
1828
    $expired = mysqli_real_escape_string($conn, time() - $t);
1829
 
1830
    $sql = "DELETE
1831
                FROM searchCache
1832
                WHERE created < $expired";
1833
 
1834
    if (!($result = mysqli_query($conn, $sql))) {
1835
        error_log("MySQL Delete SearchCache Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1836
    }
1837
}
1838
 
1839
function getSearchCache($vendor, $query, $subquery) {
1840
    $conn = MySessionHandler::getDBSessionId();
1841
 
1842
    $v = mysqli_real_escape_string($conn, $vendor);
1843
    $q = mysqli_real_escape_string($conn, $query);
1844
    $s = mysqli_real_escape_string($conn, $subquery);
1845
    $sql = "select result from searchCache where vendor = '$v' and query = '$q' and subquery = '$s'";
1846
 
1847
    if ($result = mysqli_query($conn, $sql)) {
1848
        if (mysqli_num_rows($result) == 1) {
1849
            if ($row = mysqli_fetch_assoc($result)) {
1850
                return gzdecode(base64_decode($row["result"]));
1851
            }
1852
        }
1853
    }
1854
    else if (mysqli_errno($conn)) {
1855
        error_log("MySQL Read SearchCache SQL: " . $sql);
1856
        error_log("MySQL Read SearchCache Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1857
    }
1858
 
1859
    return false;
104 - 1860
}
107 - 1861
 
1862
 
1863
function getGeoLocation() {
1864
    if (!empty($_SESSION['buyer']['Zip']) || empty($_SERVER['REMOTE_ADDR'])) {
1865
        return;
1866
    }
1867
 
1868
    $conn = MySessionHandler::getDBSessionId();
1869
    $ip = inet_pton($_SERVER['REMOTE_ADDR']);
1870
 
1871
    $sql = "select zip from geoLocation where ip = '$ip'";
1872
 
1873
    if ($result = mysqli_query($conn, $sql)) {
1874
        if (mysqli_num_rows($result) == 1) {
1875
            if ($row = mysqli_fetch_assoc($result)) {
1876
                $_SESSION['buyer']['Zip'] = $row["zip"];
1877
                return;
1878
            }
1879
        }
1880
    }
1881
    else if (mysqli_errno($conn)) {
1882
        error_log("MySQL Read geoLocation SQL: " . $sql);
1883
        error_log("MySQL Read geoLocation Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1884
    }
1885
 
1886
    $vendors = Vendors::getInstance();
1887
    $config = $vendors->getVendor(Vendors::IPAPI);
1888
    $key = $config['KEY'];
1889
 
1890
    $loc = file_get_contents("http://api.ipapi.com/api/" . $_SERVER['REMOTE_ADDR'] . "?access_key=" . $key);
1891
    if ($loc == false) {
1892
        return;
1893
    }
1894
 
1895
    $json = json_decode($loc);
1896
    if (!empty($json->error)) {
1897
        error_log("geoLocation Error: " . $json->error->info . " (" . $json->error->code . " | " . $json->error->type . ")");
1898
        return;
1899
    }
1900
 
1901
    $created = mysqli_real_escape_string($conn, time());
1902
    $countryCode = mysqli_real_escape_string($conn, $json->{'country_code'});
1903
    $zip = mysqli_real_escape_string($conn, $json->zip);
1904
    $language = mysqli_real_escape_string($conn, $json->location->languages[0]->code);
1905
    $is_eu = mysqli_real_escape_string($conn, $json->location->{'is_eu'} ? '1' : '0');
1906
 
1907
    $sql = "INSERT
1908
                INTO geoLocation
1909
                (ip, created, countryCode, zip, language, is_eu)
1910
                VALUES ('$ip', $created, '$countryCode', '$zip', '$language', '$is_eu')";
1911
 
1912
    if (!($result = mysqli_query($conn, $sql))) {
1913
        error_log("MySQL Write geoLocation Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
1914
    }
1915
}
1916
 
1917
function timeStampUrl($file) {
121 - 1918
    if (@file_exists($file)) {
109 - 1919
        return $file . "?" . filemtime($file);
1920
    }
127 - 1921
 
109 - 1922
    return $file;
108 - 1923
}