Subversion Repositories cheapmusic

Rev

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