Subversion Repositories cheapmusic

Rev

Rev 52 | Rev 55 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

<?php
include_once('php/clsLibGTIN.php');
include_once('php/exchangeRates.php');
include_once('php/countryCodes.php');
include_once('php/constants.php');
include_once('php/ebay.php');
include_once('php/discogs.php');
include_once('php/linkshare.php');
include_once('php/cjaffiliate.php');
include_once('php/walmart.php');
include_once('php/itunes.php');

error_reporting(E_ALL);

  // search
function performSearch() {
    $currentMd5SearchTerm = md5SearchTerm();
    if ($currentMd5SearchTerm == $_SESSION['md5LastSearch']) {
        return;
    }
    $_SESSION['md5LastSearch'] = $currentMd5SearchTerm;

    updatePbFile(true);

        $_SESSION["currentView"] = 'All';
        $_SESSION["barcode"]["Type"] = clsLibGTIN::GTINCheck($_SESSION["searchTerm"], false, 1);
        $_SESSION["barcode"]["Value"] = clsLibGTIN::GTINCheck($_SESSION["searchTerm"]);
        $_SESSION["resultArr"] = [];
        $_SESSION["resultArr"] = searchAll($_SESSION["searchTerm"]);
    updatePbFile();

        $_SESSION["resultArr"] = applySearchFilter($_SESSION["resultArr"]);
    updatePbFile();

//echo "<pre>";print_r($_SESSION["resultArr"]);echo "</pre>";

        $_SESSION["lowestPrice"]["Used"] = findLowestType("Used");
        $_SESSION["lowestPrice"]["New"] = findLowestType("New");
        $_SESSION["lowestPrice"]["CD"] = findLowestCategory("CD");
        $_SESSION["lowestPrice"]["Record"] = findLowestCategory("Record");
        $_SESSION["lowestPrice"]["Digital"] = findLowestCategory("Digital");
        $_SESSION["lowestPrice"]["Book"] = findLowestCategory("Book");
        $_SESSION["lowestPrice"]["All"] = 0.00;
        if (array_sum($_SESSION["lowestPrice"]) > 0) {
                $_SESSION["lowestPrice"]["All"] = minNotNull($_SESSION["lowestPrice"]);
        }
    updatePbFile();

        saveSearchResult();
    updatePbFile();

    findDiscogsMaster($_SESSION["searchTerm"], !empty($_SESSION['sessData']['userLoggedIn']));
    updatePbFile();
}

function resetSessionVars() {
    $_SESSION["searchTerm"] = '';
    $_SESSION["discogsTitle"] = '';
    $_SESSION["discogsArtist"] = '';
    $_SESSION['md5LastSearch'] = '';
        $_SESSION["currentView"] = 'All';
        $_SESSION["barcode"]["Type"] = '';
        $_SESSION["barcode"]["Value"] = '';

        $_SESSION["resultArr"] = [];

        $_SESSION["lowestPrice"]["Used"] = 0.00;
        $_SESSION["lowestPrice"]["New"] = 0.00;
        $_SESSION["lowestPrice"]["CD"] = 0.00;
        $_SESSION["lowestPrice"]["Record"] = 0.00;
        $_SESSION["lowestPrice"]["Digital"] = 0.00;
        $_SESSION["lowestPrice"]["Book"] = 0.00;
        $_SESSION["lowestPrice"]["All"] = 0.00;
}

  // search for items on all sites
function searchAll($searchKey)
{
        $arr = [];

        if ($_SESSION["filterCondition"]["New"]) {
                $arr = get_vendor($arr, 'get_ebay', $searchKey, constant("NEW"));
        }
    updatePbFile();
        if ($_SESSION["filterCondition"]["New"]) {
                $arr = get_vendor($arr, 'get_linkshare', $searchKey, constant("NEW"));
        }
    updatePbFile();
        if ($_SESSION["filterCondition"]["New"]) {
                $arr = get_vendor($arr, 'get_cjaffiliate', $searchKey, constant("NEW"));
        }
    updatePbFile();
        if ($_SESSION["filterCondition"]["New"]) {
                $arr = get_vendor($arr, 'get_walmart', $searchKey, constant("NEW"));
        }
    updatePbFile();
        if ($_SESSION["filterCondition"]["New"]) {
                $arr = get_vendor($arr, 'get_itunes', $searchKey, constant("NEW"));
        }
    updatePbFile();

        if ($_SESSION["filterCondition"]["Used"]) {
                $arr = get_vendor($arr, 'get_ebay', $searchKey, constant("USED"));
        }
    updatePbFile();

//echo "<pre>";print_r($arr);echo "</pre";


        $arr = applyExchangeRates($arr);
        usort($arr, 'compare_price');
    updatePbFile();

        return $arr;
}

// Search and merge
function get_vendor($arr, $func, $searchKey, $condition) {
        $arrTemp = $func($searchKey, $condition);
    return array_merge($arrTemp, $arr);
}

  // check search filters
function checkSearchFilters() {
    $_SESSION["filterWarnings"] = "";
    $filterOk = true;

        if (!$_SESSION["filterCondition"]["New"] && !$_SESSION["filterCondition"]["Used"]) {
                $_SESSION["filterWarnings"] .= '<div class="alert alert-danger"><i class="fas fa-filter mr-1"></i> Please select at least one Condition (New or Used)</div>';
                $filterOk = false;
        }

        if (!$_SESSION["filterMediaType"]["CD"] && !$_SESSION["filterMediaType"]["Record"] && !$_SESSION["filterMediaType"]["Digital"] && !$_SESSION["filterMediaType"]["Book"]) {
                $_SESSION["filterWarnings"] .= '<div class="alert alert-danger"><i class="fas fa-filter mr-1"></i> Please select at least one Media Type (CD, Record, Digital or Book)</div>';
                $filterOk = false;
        }

        return($filterOk);
}

// delete results from array that do not match the search filters
function applySearchFilter($arr) {
        foreach ($arr as $key => $row) {
                if (($row["Category"] == 'CD' && !$_SESSION["filterMediaType"]["CD"]) ||
                    ($row["Category"] == 'Record' && !$_SESSION["filterMediaType"]["Record"]) ||
                    ($row["Category"] == 'Digital' && !$_SESSION["filterMediaType"]["Digital"]) ||
                    ($row["Category"] == 'Book' && !$_SESSION["filterMediaType"]["Book"]) ||
                    ($row["Type"] == 'NEW' && !$_SESSION["filterCondition"]["New"]) ||
                    ($row["Type"] == 'USED' && !$_SESSION["filterCondition"]["Used"])) {
            unset($arr[$key]);
                }
        }

    return $arr;
}

  // filter view result table $_SESSION["resultArr"] for All, New, Used, Digital, or Book
function filterResults()
{
        foreach ($_SESSION["resultArr"] as &$row) {
                if ($_SESSION["currentView"] == 'All') {
                        $row["Show"] = true;
                } else {
                        $row["Show"] = ($_SESSION["currentView"] == $row["Type"] || $_SESSION["currentView"] == $row["Category"]);
                }
        }
}

  // build HTML table from array
function buildTable()
{
        $str = "<div>";

    if (count($_SESSION["resultArr"]) > 0) {
        $str .= "<table class=\"table table-striped table-condensed small\">";
            $str .= "<thead class=\"thead-dark sticky-top\"><tr><th>Image</th><th class=\"text-left\">Title / Merchant</th><th>Condition</th><th class=\"hide-small\">Price</th><th class=\"hide-small\">S/H</th><th>Total</th><th class=\"hide-extra-small\"></th></tr></thead>";
        $str .= "<tbody>";

        foreach ($_SESSION["resultArr"] as $row) {
                if (!$row["Show"]) {
                        continue;
                }

            $href = "href=\"" . $row["URL"] . "\" target=\"_blank\" onclick=\"saveTransfer('" . $row["URL"] . "'); return true;\"";

                $str .= "<tr>";

            // Image
                $str .= "<td><a " . $href . " data-toggle=\"tooltip\" title=\"Buy It Now\"><img class=\"img-fluid tn-image\" src=\"" . $row["Image"] . "\" alt=\"Item Image\"></a></td>";

            // Title / Merchant
                $str .= "<td class=\"text-left\"><span class=\"font-weight-bold\"><a " . $href . " data-toggle=\"tooltip\" title=\"Buy It Now\">" . $row["Title"] . "</a></span><br/><br/>";
                $str .= "<span class=\"font-weight-bold\">" . $row["Merchant"] . "</span>";
                if ($row["FeedbackScore"] != -1) {
                        $str .= "<span class=\"hide-extra-small\"><br/>" . $row["SellerName"] . " (" . number_format($row["FeedbackScore"], 0, "", ",") . " / " . $row["FeedbackPercent"] . "%)</span>";
                } else if (!empty($row["SellerName"])) {
                        $str .= "<span class=\"hide-extra-small\"><br/>" . $row["SellerName"] . "</span>";
                }
                if (!empty($row["TimeLeft"])) {
                $str .= "<br>" . $row["TimeLeft"];
                }
                $str .= "</td>";

            // Condition
                $str .= "<td>";
                $categoryIcon = "category-icon ";
                $tooltip = "";
                switch ($row["Category"]) {
                        case "CD":
                                $categoryIcon .= "fas fa-compact-disc category-icon-silver";
                                $tooltip = "Compact Disc";
                                break;

                        case "Record":
                                $categoryIcon .= "fas fa-dot-circle";
                                $tooltip = "Vinyl Record";
                                break;

                        case "Digital":
                                $categoryIcon .= "fas fa-download";
                                $tooltip = "Digital Download";
                                break;

                        case "Book":
                                $categoryIcon .= "fas fa-book-open";
                                $tooltip = "Book / Sheet Music";
                                break;
                }
                $str .= "<span class=\"font-weight-bold\">" . $row["Condition"] . "</span>";
                $str .= "<br/><br/>";
                $str .= "<i class=\"" . $categoryIcon . "\" title=\"" . $tooltip . "\" data-toggle=\"tooltip\" data-placement=\"right\" data-delay=\"200\"></i>";
                $str .= "</td>";

            // Price
                $str .= "<td class=\"hide-small\">" . print_monetary($row["Price"], $row["Currency"]);
                if ($row["Currency"] != $_SESSION["buyer"]["Currency"]) {
                        $str .= "<br/>&asymp; " . print_monetary($row["ConvertedPrice"], $_SESSION["buyer"]["Currency"]);
                }
                if ($row["BestOffer"] == "true") {
                    $str .= "<br>Best Offer Accepted";
                }
                $str .= "</td>";

            // Shipping and Handling Cost
                $str .= "<td class=\"hide-small\">";
                if ($row["ShippingCost"] == 0.00) {
                        $str .= "Free Shipping";
                } else {
                        $str .= print_monetary($row["ShippingCost"], $row["ShippingCurrency"]);
                }
                if ($row["ShippingCost"] > 0.00 && $row["ShippingCurrency"] != $_SESSION["buyer"]["Currency"]) {
                        $str .= "<br/>&asymp; " . print_monetary($row["ConvertedShippingCost"], $_SESSION["buyer"]["Currency"]);
                }
            if ($row["HandlingTime"] > 0) {
                $str .= "<br>Handling Time " . $row["HandlingTime"] . " day" . ($row["HandlingTime"] > 1 ? "s" : "");
            }
            if ($row["ShippingCost"] > 0.00 && $row["FreeShippingCap"] > 0) {
                $str .= "<br>Free Shipping over " . print_monetary($row["FreeShippingCap"], $_SESSION["buyer"]["Currency"]);
            }
                $str .= "<br/><img class=\"img-fluid\" title=\"Ships from " . getCountry($row["Country"]) . "\" data-toggle=\"tooltip\" data-placement=\"right\" data-delay=\"200\" src=\"/images/flags/" . $row["Country"] . ".png\" alt=\"" . getCountry($row["Country"]) . " Flag\"></td>";

            // Total Price
                $str .= "<td class=\"font-weight-bolder\">" . print_monetary($row["ConvertedTotalPrice"], $_SESSION["buyer"]["Currency"]) . "</td>";

            // Link
            if ($row["Merchant"] == "iTunes") {
                if ($row["Category"] == "Digital") {
                    $badge = "images/US-UK_Apple_Music_Badge_RGB.svg";
                } else {
                    $badge = "images/US_UK_Apple_Books_Badge_Get_RGB_071818.svg";
                }
                $linkImage = "<a class=\"btn\" role=\"button\" " . $href . "><img src=\"" . $badge . "\" alt=\"iTunes Badge\"></a>";
            } else {
                $linkImage = "<a class=\"btn btn-danger\" role=\"button\" " . $href . "><i class=\"fas fa-shopping-cart btn-shop\"></i><span class=\"hide-small\"><br>Buy It Now</span></a>";
            }
                $str .= "<td class=\"hide-extra-small\">" . $linkImage . "</td>";

                $str .= "</tr>";
        }

        $str .= "</tbody>";
        $str .= "<tfoot class=\"text-right\"><tr><td class=\"font-italic\" colspan=\"7\">Prices retrieved on " . gmdate("Y-m-d H:i") . " UTC<br>Daily exchange rates update</td></tr></tfoot>";
        $str .= "</table>";
    } else {
        $str .= "<div class=\"text-center bg-warning p2 rounded\">";
        $str .= "<p class=\"display-5\">Your search returned no results</p>";
        $str .= "<p>You may want to try the following:</p>";
        $str .= "<dl><li>Check the spelling</li><li>Try using fewer words</li><li>Check the search filter if you used one</li></dl>";
        $str .= "</div>";
    }

        $str .= "</div>";

        return ($str);
}

  // print summary/header on top of listing table
function printTableHeader() {
    $str = '<div class="d-flex flex-wrap justify-content-center p-2">';
        $str .= '    <button name="submit" value="All" type="' . getButtonType("All") . '" class="btn filterButton mx-2 ' . getBackgroundColor("All") . '"';
        if ($_SESSION["lowestPrice"]["All"] <= 0) {
                $str .= ' disabled';
        }
        $str .= '><span class="display-6 font-weight-bolder">All</span><span class="display-7"> from</span><br><span class="display-6 font-weight-bolder">' . print_monetary($_SESSION["lowestPrice"]["All"], $_SESSION["buyer"]["Currency"]) . '</span>';
        $str .= '    </button>';
    $str .= '    <button name="submit" value="New" type="' . getButtonType("New") . '" class="btn filterButton mx-2 ' . getBackgroundColor("New") . '"';
        if ($_SESSION["lowestPrice"]["New"] <= 0) {
                $str .= ' disabled';
        }
        $str .= '><span class="display-6 font-weight-bolder">New</span><span class="display-7"> from</span><br><span class="display-6 font-weight-bolder">' . print_monetary($_SESSION["lowestPrice"]["New"], $_SESSION["buyer"]["Currency"]) . '</span>';
        $str .= '    </button>';
    $str .= '    <button name="submit" value="Used" type="' . getButtonType("Used") . '" class="btn filterButton mx-2 ' . getBackgroundColor("Used") . '"';
        if ($_SESSION["lowestPrice"]["Used"] <= 0) {
        $str .= ' disabled';
        }
    $str .= '><span class="display-6 font-weight-bolder">Used</span><span class="display-7"> from</span><br><span class="display-6 font-weight-bolder">' . print_monetary($_SESSION["lowestPrice"]["Used"], $_SESSION["buyer"]["Currency"]) . '</span>';
        $str .= '    </button>';
    $str .= '    <button name="submit" value="Digital" type="' . getButtonType("Digital") . '" class="btn filterButton mx-2 ' . getBackgroundColor("Digital"). '"';
    if ($_SESSION["lowestPrice"]["Digital"] <= 0) {
        $str .= ' disabled';
    }
    $str .= '><span class="display-6 font-weight-bolder">Digital</span><span class="display-7"> from</span><br><span class="display-6 font-weight-bolder">' . print_monetary($_SESSION["lowestPrice"]["Digital"], $_SESSION["buyer"]["Currency"]) . '</span>';
        $str .= '    </button>';
        $str .= '    <button name="submit" value="Book" type="' . getButtonType("Book") . '" class="btn filterButton mx-2 ' . getBackgroundColor("Book") . '"';
        if ($_SESSION["lowestPrice"]["Book"] <= 0) {
                $str .= ' disabled';
        }
        $str .= '><span class="display-6 font-weight-bolder">Books</span><span class="display-7"> from</span><br><span class="display-6 font-weight-bolder">' . print_monetary($_SESSION["lowestPrice"]["Book"], $_SESSION["buyer"]["Currency"]) . '</span>';
        $str .= '    </button>';
    $str .= '</div>';

        return $str;
}

  // get top button background color
function getBackgroundColor($sel)
{
        if ($_SESSION["currentView"] == $sel) {
                return ("btn-primary active");
        }

        return ("btn-primary text-dark");
}

  // get top button type
function getButtonType($sel)
{
        if ($_SESSION["currentView"] == $sel) {
                return ("button");
        }

        return ("submit");
}

  // compare price for sort low to high
function compare_price($a, $b)
{
        return strnatcmp($a['ConvertedTotalPrice'], $b['ConvertedTotalPrice']);
}

  // print monetary values with correct symbol and thousands/decimal delimiters
function print_monetary($num, $curr)
{
        if ($curr == "USD") {
                return ("$" . number_format($num, 2, '.', ','));
        } else if ($curr == "CAD") {
                return ("C $" . number_format($num, 2, '.', ','));
        } else if ($curr == "EUR") {
                return (number_format($num, 2, ',', '.') . "&euro;");
        } else if ($curr == "GBP") {
                return ("&pound;" . number_format($num, 2, '.', ','));
        } else if ($curr == "AUD") {
                return ("AU $" . number_format($num, 2, '.', ','));
        }

        return ($curr . " " . number_format($num, 2, '.', ','));
}

  // find lowest used / new prices
function findLowestType($type)
{
        foreach ($_SESSION["resultArr"] as $row) {
                if (!$row["Show"]) {
                        continue;
                }

                if ($type == $row["Type"]) {
                        return ($row["ConvertedTotalPrice"]);
                }
        }

        return (0);
}

  // find lowest cd, record, digital and book prices
function findLowestCategory($category)
{
        foreach ($_SESSION["resultArr"] as $row) {
                if (!$row["Show"]) {
                        continue;
                }

                if ($category == $row["Category"]) {
                        return ($row["ConvertedTotalPrice"]);
                }
        }

        return (0);
}

  // find lowest non-zero double value in array
function minNotNull(Array $values)
{
        return min(array_diff(array_map('doubleval', $values), array(0)));
}

  // apply exchange rates
function applyExchangeRates($arr)
{
        foreach ($arr as &$value) {
                $value["ConvertedPrice"] = $value["Price"];
                $value["ConvertedShippingCost"] = $value["ShippingCost"];

                if ($_SESSION["buyer"]["Currency"] != $value["Currency"]) {
                        $value["ConvertedPrice"] = number_format($value["Price"] / getExchangeRate($_SESSION["buyer"]["Currency"], $value["Currency"]), 2, '.', '');
                }

                if ($_SESSION["buyer"]["Currency"] != $value["ShippingCurrency"]) {
                        $value["ConvertedShippingCost"] = number_format($value["ShippingCost"] / getExchangeRate($_SESSION["buyer"]["Currency"], $value["ShippingCurrency"]), 2, '.', '');
                }

                $value["ConvertedTotalPrice"] = number_format($value["ConvertedPrice"] + $value["ConvertedShippingCost"], 2, '.', '');
        }

        return ($arr);
}

// sanitize user input
function sanitizeInput($data)
{
        $data = trim(preg_replace('/[\t\n\r\s]+/', ' ', $data));
        $data = stripslashes($data);
        $data = htmlspecialchars($data);
        return $data;
}

// sanitize user input (plus delete apostrophe)
function sanitizeInput2($data) {
        $data = trim(preg_replace('/[\t\n\r\s\']+/', ' ', $data));
        $data = stripslashes($data);
        $data = htmlspecialchars($data, ENT_QUOTES | ENT_HTML5);
        return $data;
}

// convert certain utf-8 characters to ascii
function cleanString($str) {
    $utf8 = array(
        '/[áàâãªä]/u'   =>   'a',
        '/[ÁÀÂÃÄ]/u'    =>   'A',
        '/[ÍÌÎÏ]/u'     =>   'I',
        '/[íìîï]/u'     =>   'i',
        '/[éèêë]/u'     =>   'e',
        '/[ÉÈÊË]/u'     =>   'E',
        '/[óòôõºö]/u'   =>   'o',
        '/[ÓÒÔÕÖ]/u'    =>   'O',
        '/[úùûü]/u'     =>   'u',
        '/[ÚÙÛÜ]/u'     =>   'U',
        '/ç/'           =>   'c',
        '/Ç/'           =>   'C',
        '/ñ/'           =>   'n',
        '/Ñ/'           =>   'N',
        '/–/'           =>   '-', // UTF-8 hyphen to "normal" hyphen
        '/[’‘‹›‚]/u'    =>   ' ', // Literally a single quote
        '/[“”«»„]/u'    =>   ' ', // Double quote
        '/ /'           =>   ' ', // nonbreaking space (equiv. to 0x160)
    );

    return preg_replace(array_keys($utf8), array_values($utf8), $str);
}

// Clean the search string
function searchFriendlyString($str) {
    $str = strip_tags($str);
    $str = stripslashes($str);
    $str = cleanString($str);
    $str = str_replace(array("[", "]", "<", ">", "(", ")", " - ", " & "," / "), " ", $str);    // eliminate single '-', '&', '/' and brackets
    $str = trim(preg_replace('/[\t\n\r\s]+/', ' ', $str));          // delete extra whitespaces
    return ucwords($str);
}

  // get a SESSION value, return empty string if not set
function getSV($var)
{
        if (!isset($_SESSION[$var])) {
                return ('');
        }

        return ($_SESSION[$var]);
}

  // initialize a SESSION value if not set
function initSV($var, $value)
{
        if (!isset($_SESSION[$var])) {
                $_SESSION[$var] = $value;
        }
}

  // initialize sessions variables
function initSessionVariables()
{
        initSV("resultArr", []);
        initSV("barcode", array("Type" => "", "Value" => ""));
        initSV("buyer", array("Country" => "United States", "Currency" => "USD", "Zip" => ""));
        initSV("filterCondition", array("New" => true, "Used" => true));
        initSV("filterMediaType", array("CD" => true, "Record" => true, "Digital" => true, "Book" => true));
        initSV("currentView", "All");
        initSV("lowestPrice", array("Used" => 0.00, "New" => 0.00, "CD" => 0.00, "Record" => 0.00, "Digital" => 0.00, "Book" => "0.00", "All" => 0.00));
        initSV("filterWarnings", "");
        initSV("md5LastSearch", "");
}

function md5SearchTerm() {
    $data = array();
    $data['cond'] = $_SESSION['filterCondition'];
    $data['type'] = $_SESSION['filterMediaType'];
    $data['buyer'] = $_SESSION['buyer'];
    $data['term'] = array($_SESSION['searchTerm']);

    return(md5(json_encode($data)));
}

  // check POST value, return true if set and false if not
function checkPV($var)
{
        if (isset($_POST[$var])) {
                return (true);
        }

        return (false);
}

  // get POST or GET value, return empty if not set
function getPGV($var)
{
        if (isset($_POST[$var])) {
                return ($_POST[$var]);
        } else if (isset($_GET[$var])) {
                return ($_GET[$var]);
        }

        return ("");
}

// print search filter modal with current selection
function printSearchFilterModal()
{
        $str = '';
        $str .= '<div class="modal fade" id="filterModal">';
        $str .= '    <div class="modal-dialog">';
        $str .= '        <div class="modal-content">';
        $str .= '';
        $str .= '            <div class="modal-header bg-primary">';
        $str .= '                <h4 class="modal-title">Search Filters</h4>';
        $str .= '            </div>';
        $str .= '';
        $str .= '            <form method="post" action="/index.php" onsubmit="progressBar(\'Applying Modified Search Filter...\');">';
    $str .= '                <input type="hidden" name="sessionTab" value="' . MySessionHandler::getSessionTab() . '">';
        $str .= '                <div class="modal-body">';
        $str .= '                    <div class="card-group">';
        $str .= '';
        $str .= '                        <div class="card m-2">';
        $str .= '                            <div class="card-header font-weight-bold">Condition</div>';
        $str .= '                            <div class="card-body">';
        $str .= '                                <div class="form-check">';
        $str .= '                                    <label class="form-check-label">';
        $str .= '                                        <input name="filterConditionNew" type="checkbox" class="form-check-input" value="New"' . ($_SESSION["filterCondition"]["New"] ? " checked" : "") . '>New';
        $str .= '                                    </label>';
        $str .= '                                </div>';
        $str .= '                                <div class="form-check">';
        $str .= '                                    <label class="form-check-label">';
        $str .= '                                        <input name="filterConditionUsed" type="checkbox" class="form-check-input" value="Used"' . ($_SESSION["filterCondition"]["Used"] ? " checked" : "") . '>Used';
        $str .= '                                    </label>';
        $str .= '                                </div>';
        $str .= '                            </div>';
        $str .= '                        </div>';
        $str .= '';
        $str .= '                        <div class="card m-2">';
        $str .= '                            <div class="card-header font-weight-bold">Media Type</div>';
        $str .= '                            <div class="card-body">';
        $str .= '                                <div class="form-check">';
        $str .= '                                    <label class="form-check-label">';
        $str .= '                                        <input name="filterMediaTypeCD" type="checkbox" class="form-check-input" value="CD"' . ($_SESSION["filterMediaType"]["CD"] ? " checked" : "") . '><i class="fas fa-compact-disc category-icon-silver"></i> Compact Disc';
        $str .= '                                    </label>';
        $str .= '                                </div>';
        $str .= '                                <div class="form-check">';
        $str .= '                                    <label class="form-check-label">';
        $str .= '                                        <input name="filterMediaTypeRecord" type="checkbox" class="form-check-input" value="Record"' . ($_SESSION["filterMediaType"]["Record"] ? " checked" : "") . '><i class="fas fa-dot-circle"></i> Vinyl Record';
        $str .= '                                    </label>';
        $str .= '                                </div>';
        $str .= '                                <div class="form-check">';
        $str .= '                                    <label class="form-check-label">';
        $str .= '                                        <input name="filterMediaTypeDigital" type="checkbox" class="form-check-input" value="Digital"' . ($_SESSION["filterMediaType"]["Digital"] ? " checked" : "") . '><i class="fas fa-download"></i> Digital';
        $str .= '                                    </label>';
        $str .= '                                </div>';
        $str .= '                                <div class="form-check">';
        $str .= '                                    <label class="form-check-label">';
        $str .= '                                        <input name="filterMediaTypeBook" type="checkbox" class="form-check-input" value="Books"' . ($_SESSION["filterMediaType"]["Book"] ? " checked" : "") . '><i class="fas fa-book-open"></i> Books / Sheet Music';
        $str .= '                                    </label>';
        $str .= '                                </div>';
        $str .= '                            </div>';
        $str .= '                        </div>';
        $str .= '                    </div>';
        $str .= '                </div>';
        $str .= '';
        $str .= '                <div class="modal-footer bg-primary">';
        $str .= '                        <input id="tempSearchTerm" type="hidden" name="searchTerm" value="">';
        $str .= '                    <button type="submit" class="btn btn-success" name="submit" value="Save" onclick="document.getElementById(\'tempSearchTerm\').value = document.getElementById(\'searchTerm\').value;$(\'#filterModal\').modal(\'hide\');">Save</button>';
        $str .= '                    <button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>';
        $str .= '                </div>';
        $str .= '            </form>';
        $str .= '        </div>';
        $str .= '    </div>';
        $str .= '</div>';

        return ($str);
}

// print search info modal
function printSearchInfoModal()
{
        $str = '';
        $str .= '<div class="modal fade" id="searchInfoModal">';
        $str .= '    <div class="modal-dialog">';
        $str .= '        <div class="modal-content">';
        $str .= '';
        $str .= '            <div class="modal-header bg-primary">';
        $str .= '                <h4 class="modal-title">Search Tips</h4>';
        $str .= '                <button type="button" class="close" data-dismiss="modal"><i class="fas fa-window-close btn-dismiss"></i></button>';
        $str .= '            </div>';
        $str .= '';
        $str .= '            <div class="modal-body bg-light">';
        $str .= '              <div class="shadow p-4 mb-4 bg-white">';
        $str .= '                <h4><i class="fas fa-filter"></i> Filter</h4>';
        $str .= '                <p><span class=font-weight-bold>Condition:</span>';
        $str .= '                    <br>Select "New" and / or "Used". The standard is to search for both.</p>';
        $str .= '                <p><span class=font-weight-bold>Media Type:</span>';
        $str .= '                    <br>Select <i class="fas fa-compact-disc category-icon-silver"></i> "CD", <i class="fas fa-dot-circle"></i> "Vinyl Record", <i class="fas fa-download"></i> "Digital" and / or <i class="fas fa-book-open"></i> "Book / Sheet Music". The standard is to search for all types.</p>';
        $str .= '              </div>';
        $str .= '              <div class="shadow p-4 mb-4 bg-white">';
        $str .= '                <h4><i class="fas fa-shipping-fast"></i> Shipping To</h4>';
        $str .= '                <p><span class=font-weight-bold>Country / Currency:</span>';
        $str .= '                    <br>At this time only "United States" / "USD" are supported. The exchange rates are updated daily.</p>';
        $str .= '                <p><span class=font-weight-bold>Zip Code:</span>';
        $str .= '                    <br>Enter your postal code to get the accurate shipping cost for items listed using a shipping rate table.</p>';
        $str .= '              </div>';
        $str .= '              <div class="shadow p-4 bg-white">';
        $str .= '                <h4><i class="fas fa-search"></i> Search Keywords</h4>';
        $str .= '                <p><span class=font-weight-bold>Barcode:</span>';
        $str .= '                    <br>The 12 or 13 digit barcode, normally located on the back, offers the best chance to find a specific album.</p>';
        $str .= '                <p><span class=font-weight-bold>Artist and Title:</span>';
        $str .= '                    <br>The full name of the album, including artist and title, will usually lead to a specific album.</p>';
        $str .= '                <p><span class=font-weight-bold>Just Artist or Title:</span>';
        $str .= '                    <br>Searches for artist or title alone will bring up multiple albums.</p>';
        $str .= '              </div>';
        $str .= '            </div>';
        $str .= '            <div class="modal-footer bg-primary">';
        $str .= '                <button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>';
        $str .= '            </div>';
        $str .= '        </div>';
        $str .= '    </div>';
        $str .= '</div>';

        return ($str);
}

        function saveSearchResult() {
        $conn = MySessionHandler::getDBSessionId();

        $access = mysqli_real_escape_string($conn, time());
        // BUGBUG
        //  country
        //  currency
        $zip = mysqli_real_escape_string($conn, $_SESSION['buyer']['Zip']);
        $condNew = $_SESSION['filterCondition']['New'] ? 'Y' : 'N';
        $condUsed = $_SESSION['filterCondition']['Used'] ? 'Y' : 'N';
        $mediaCD = $_SESSION['filterMediaType']['CD'] ? 'Y' : 'N';
        $mediaRecord = $_SESSION['filterMediaType']['Record'] ? 'Y' : 'N';
        $mediaDigital = $_SESSION['filterMediaType']['Digital'] ? 'Y' : 'N';
        $mediaBook = $_SESSION['filterMediaType']['Book'] ? 'Y' : 'N';
        $data = mysqli_real_escape_string($conn, $_SESSION['searchTerm']);
        $lowNew = floatval($_SESSION['lowestPrice']['New']);
        $lowUsed = floatval($_SESSION['lowestPrice']['Used']);
        $lowDigital = floatval($_SESSION['lowestPrice']['Digital']);
        $lowBook = floatval($_SESSION['lowestPrice']['Book']);
        $count = count($_SESSION['resultArr']);
        $userId = (empty($_SESSION['sessData']['userID']) ? 'NULL' : $_SESSION['sessData']['userID']);

        $sql = "INSERT
                INTO searches
                (sessId, access, zip, condNew, condUsed, mediaCD, mediaRecord, mediaDigital, mediaBook, data, lowNew, lowUsed, lowDigital, lowBook, count, userId)
                VALUES ('" . session_id() . "', '$access', '$zip', '$condNew', '$condUsed', '$mediaCD', '$mediaRecord', '$mediaDigital', '$mediaBook', '$data', $lowNew, $lowUsed, $lowDigital, $lowBook, $count, $userId)";

        if (!($result = mysqli_query($conn, $sql))) {
            error_log("MySQL Write Searches Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
        }

        return $result;
        }

function getUrl($url, $userAgent = null) {
    $ch = curl_init();

    // Set request header with language and charset
    $header = array(
        "Accept-Language: en-US,en;q=0.5",
        "Accept-Charset: UTF-8,*;q=0.5"
    );
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

    // Set optional user-agent
    if ($userAgent) {
        curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
    }

    curl_setopt($ch, CURLOPT_ENCODING, "gzip,deflate");
    curl_setopt($ch, CURLOPT_AUTOREFERER, true);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_URL, $url);
    $response = curl_exec($ch);
    if ($response === false) {
        error_log('Curl Request Error: ' . curl_error($ch) . ' (' . curl_errno($ch) . ')');
        error_log('Url: ' . $url);
        $response = '';
    }

    curl_close($ch);

    return $response;
}

// Retrieve search history for current session id
function getSearchHistory() {
    $str = "";
    $sql = "select data, max(access) from searches where sessId = '" . session_id() . "'";
    if (!empty($_SESSION['sessData']['userID'])) {
        $sql .= " or userID = '" . $_SESSION['sessData']['userID'] . "'";
    }
    $sql .= " group by data order by max(access) desc, data limit 0,30;";
    $conn = MySessionHandler::getDBSessionId();

    if ($result = mysqli_query($conn, $sql)) {
        if (mysqli_num_rows($result) > 0) {
            while($row = mysqli_fetch_assoc($result)) {
                $str .= "<option>" . $row["data"] . "</option>";
            }
        }
    } else if (mysqli_errno($conn)) {
       error_log("MySQL Read Searches SQL: " . $sql);
       error_log("MySQL Read Searches Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");
    }

    return $str;
}

// Retrieve coupons codes
function getCouponCodes() {
    $str = "";
    $lastAdvertiser = "";

    if (!isLoggedIn()) {
        return ("<h2>Please login to your Find Cheap Music account in order to see the coupons.</h2>");
    }

    $sql = 'select distinct advertiser, date_format(enddate, "%M %e, %Y") as enddate, description, couponcode, url, pixel from coupons where DATE(NOW()) between startdate and enddate order by advertiser, id';
    $conn = MySessionHandler::getDBSessionId();

    if ($result = mysqli_query($conn, $sql)) {
        if (mysqli_num_rows($result) > 0) {
            $str .= "<div class=\"container py-4\">";
            while($row = mysqli_fetch_assoc($result)) {
                if($row["advertiser"] != $lastAdvertiser) {
                    if (!empty($lastAdvertiser)) {
                        $str .= "</div>";
                    }
                    $str .= "<h3 class=\"bg-primary text-center mt-3 mb-1\">" . $row["advertiser"] . "</h3>";
                    $str .= "<div class=\"d-flex flex-column\">";
                    $lastAdvertiser = $row["advertiser"];
                }
                if (!empty($row["url"])) {
                    $str .= "<a class=\"btn bg-info align-items-center text-white text-left py-0 my-1\" target=\"_blank\" href=\"";
                    $str .= $row["url"];
                    $str .= "\">";
                    $str .= $row["description"] . " until " . $row["enddate"];
                    if (!empty($row["couponcode"])) {
                        $str .= " (Use Coupon Code \"" . $row["couponcode"] . "\")";
                    }
                    $str .= "</a>";
                    if (!empty($row["pixel"])) {
                        $str .= "<img src=\"" . $row["pixel"] . "\" width=\"1\" height=\"1\" class=\"border-0\"/>";
                    }
                }
            }
            $str .= "</div>";
            $str .= "</div>";
        }
    } else if (mysqli_errno($conn)) {
        $str .= "<h2>No Coupons available at the moment...</h2>";
    }

    return $str;
}

// Delete left over progressbar files older than 2 days
function cleanupPbFiles() {
    $files = glob("../tmp/pb*.txt");
    $now   = time();
    foreach ($files as $file) {
        if (is_file($file)) {
            if ($now - filemtime($file) >= 60 * 60 * 24 * 2) { // 2 days and older
                unlink($file);
            }
         }
    }
}

// Update progressbar file for a session
function updatePbFile($flag = false) {
    static $max_pb = 12; // max progressbar steps
    static $current = 0;

    if ($flag) {
        $current = 0;
    } else {
        ++$current;
    }

    if ($current > $max_pb) {
        error_log("max_pb $max_pb is too small, current step is $current. Adjust tools.php (updatePbFile).");
        $max_pb = $current;
    }
    $filename = session_id()  . "_" . MySessionHandler::getSessionTab();
    $arr_content = array();

    $percent = intval($current / $max_pb * 100);

    $arr_content['percent'] = $percent;
    $arr_content['message'] = $current . " search(es) processed.";

    file_put_contents("../tmp/pb_" . $filename . ".txt", json_encode($arr_content));
}

// Linkshare / CJ Affiliate csv dump
function ls_cj_csv($fields) {
    static $fh = null;
    $delimiter = ',';
    $enclosure = '"';
    $mysql_null = false;

    if (!$fh) {
        $fh = fopen("ls_cj.csv", "a+");
    }

    $delimiter_esc = preg_quote($delimiter, '/');
    $enclosure_esc = preg_quote($enclosure, '/');

    $output = array();
    foreach ($fields as $field) {
        if ($field === null && $mysql_null) {
            $output[] = 'NULL';
            continue;
        }

        $output[] = preg_match("/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field) ? (
            $enclosure . str_replace($enclosure, $enclosure . $enclosure, $field) . $enclosure
        ) : $field;
    }

    fwrite($fh, join($delimiter, $output) . "\n");
}

// Login in check
function isLoggedIn() {
    return (!empty($_SESSION['sessData']['userLoggedIn']) && !empty($_SESSION['sessData']['userID']))?true:false;
}

// unset all login system session data
function unsetSessData() {
    unset($_SESSION['sessData']['userLoggedIn']);
    unset($_SESSION['sessData']['userID']);
    unset($_SESSION['sessData']['loginType']);
}

// get user image name
function getUserImage($userData) {
    if (empty($userData) || empty($userData['picture'])) {
        return 'login/images/default.png';
    }

    $httpPos = strpos($userData['picture'], 'http');
    if ($httpPos === false) {
        return 'login/' . UPLOAD_PATH . 'profile_picture/'.$userData['picture'];
    }

    return $userData['picture'];
}

function startsWith($haystack, $needle) {
    return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
}

function endsWith($haystack, $needle) {
    return substr_compare($haystack, $needle, -strlen($needle)) === 0;
}

function displayBarcode($barcode) {
    $barcode = trim(preg_replace("/[^0-9]/", "", $barcode));
    $barcodeType = clsLibGTIN::GTINCheck($barcode, false, 1);

    if ($barcodeType == "UPC" && strlen($barcode) == 12) {
        return substr($barcode, 0, 1) . "-" . substr($barcode, 1, 5) . "-" . substr($barcode, 6, 5) . "-" . substr($barcode, 11, 1);
    } else if (($barcodeType == "EAN" || $barcodeType == "ISBN") && strlen($barcode) == 13) {
        return substr($barcode, 0, 1) . "-" . substr($barcode, 1, 6) . "-" . substr($barcode, 7, 6);
    } else if ($barcodeType == "EAN" && strlen($barcode) == 14) {
        return substr($barcode, 0, 1) . "-" . substr($barcode, 1, 2) . "-" . substr($barcode, 3, 5) . "-" . substr($barcode, 8, 5) . "-" . substr($barcode, 13, 1);
    } else {
        return $barcode;
    }
}