Rev 113 | Rev 120 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?phpuse Fuse\Fuse;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');include_once ('php/amazon.php');include_once ('php/amazon_scrape.php');include_once ('php/impact.php');include_once ('php/sessions_db.php');error_reporting(E_ALL);// meta descriptionfunction metaDescription($page) {switch ($page) {case "terms":$metaText = "By visiting our site and/or purchasing something from us, you engage in our Service and agree to be bound by these terms and conditions.";break;case "privacy":$metaText = "In our User Privacy Notice, we have compiled all essential information about our handling of your personal data and your corresponding rights for you.";break;case "help":$metaText = "The help page explains the basic functionality of the search page with its various sections of supporting information.";break;case "wishlist":$metaText = "Maintain a wishlist at FindCheapMusic to keep track of your favorite music albums or to receive price drop alerts right to your email. Free login required.";break;case "coupons":$metaText = "Weekly updated coupons and special offers from various music online stores. When they are gone, they are gone. Free login required.";break;case "priceMonitor":$metaText = "Explore your personal price monitor results. Results will be updated at user-defined intervals and published via email. Free login required.";break;case "random":$metaText = "See several completely random music album suggestions.";break;default:$metaText = "Search dozens of online stores at once for low-priced or hard to find Compact Discs, Vinyl Records, MP3s, Music Sheets and Music related books.";break;}return ('<meta name="description" content="' . $metaText . '">');}// searchfunction performSearch() {$currentMd5SearchTerm = md5SearchTerm();if ($currentMd5SearchTerm == $_SESSION['md5LastSearch']) {return;}$_SESSION['md5LastSearch'] = $currentMd5SearchTerm;$_SESSION["barcode"]["Type"] = clsLibGTIN::GTINCheck($_SESSION["searchTerm"], false, 1);$_SESSION["barcode"]["Value"] = clsLibGTIN::GTINCheck($_SESSION["searchTerm"]);updatePbFile(true);getGeoLocation();updatePbFile(true);findDiscogsMaster($_SESSION["searchTerm"]);updatePbFile();$_SESSION["currentLayout"] = 'TableView';$_SESSION["resultArr"] = [];expireSearchCache();$_SESSION["resultArr"] = searchAll($_SESSION["searchTerm"]);verifyResultArr();updatePbFile();$_SESSION["resultArr"] = applySearchFilter($_SESSION["resultArr"]);updatePbFile();//echo "<pre>";print_r($_SESSION["resultArr"]);echo "</pre>";$_SESSION["lowestPrice"]["Used"] = findLowestCondition("Used");$_SESSION["lowestPrice"]["New"] = findLowestCondition("New");$_SESSION["lowestPrice"]["CD"] = findLowestMediaType("CD");$_SESSION["lowestPrice"]["Record"] = findLowestMediaType("Record");$_SESSION["lowestPrice"]["Digital"] = findLowestMediaType("Digital");$_SESSION["lowestPrice"]["Book"] = findLowestMediaType("Book");$_SESSION["lowestPrice"]["All"] = 0.00;if (array_sum($_SESSION["lowestPrice"]) > 0) {$_SESSION["lowestPrice"]["All"] = minNotNull($_SESSION["lowestPrice"]);}updatePbFile();saveSearchResult();updatePbFile();}function resetSessionVars() {$_SESSION["searchTerm"] = '';$_SESSION["discogsTitle"] = '';$_SESSION["discogsArtist"] = '';$_SESSION['md5LastSearch'] = '';$_SESSION["currentLayout"] = 'TableView';$_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 sitesfunction searchAll($searchKey, $batchFlag = false) {$arr = [];if ($_SESSION["filterCondition"]["New"]) {$arr = get_vendor($arr, 'get_ebay', $searchKey, constant("NEW"));}if (!$batchFlag) { updatePbFile(); }if ($_SESSION["filterCondition"]["New"]) {$arr = get_vendor($arr, 'get_linkshare', $searchKey, constant("NEW"));}if (!$batchFlag) { updatePbFile(); }if ($_SESSION["filterCondition"]["New"]) {$arr = get_vendor($arr, 'get_cjaffiliate', $searchKey, constant("NEW"));}if (!$batchFlag) { updatePbFile(); }if ($_SESSION["filterCondition"]["New"]) {$arr = get_vendor($arr, 'get_walmart', $searchKey, constant("NEW"));}if (!$batchFlag) { updatePbFile(); }if ($_SESSION["filterCondition"]["New"]) {$arr = get_vendor($arr, 'get_itunes', $searchKey, constant("NEW"));}if (!$batchFlag) { updatePbFile(); }$cntArr = count($arr);$arr = get_vendor($arr, 'get_amazon', $searchKey, constant("NEW"));if ($cntArr == count($arr)) {$arr = get_vendor($arr, 'get_amazon_scrape', $searchKey, constant("NEW"));}if (!$batchFlag) { updatePbFile(); }$arr = get_vendor($arr, 'get_impact', $searchKey, constant("NEW"));if (!$batchFlag) { updatePbFile(); }if ($_SESSION["filterCondition"]["Used"]) {$arr = get_vendor($arr, 'get_ebay', $searchKey, constant("USED"));}if (!$batchFlag) { updatePbFile(); }//echo "<pre>";print_r($arr);echo "</pre";$arr = applyExchangeRates($arr);usort($arr, 'compare_price');if (!$batchFlag) { updatePbFile(); }return $arr;}// Search and mergefunction get_vendor($arr, $func, $searchKey, $condition) {$arrTemp = $func($searchKey, $condition);return array_merge($arrTemp, $arr);}// check search filtersfunction 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 filtersfunction applySearchFilter($arr) {unset($_SESSION['AdditionalFilterCounters']);unset($_SESSION['AdditionalFilters']);foreach ($arr as $key => $row) {if (!$_SESSION["filterMediaType"][$row["MediaType"]] || !$_SESSION["filterCondition"][$row["Condition"]]) {unset($arr[$key]);} else {if (isset($_SESSION['AdditionalFilterCounters']['Condition']['All'])) {$_SESSION['AdditionalFilterCounters']['Condition']['All']++;} else {$_SESSION['AdditionalFilterCounters']['Condition']['All'] = 1;}if (isset($_SESSION['AdditionalFilterCounters']['Merchant'][$row['Merchant']])) {$_SESSION['AdditionalFilterCounters']['Merchant'][$row['Merchant']]++;} else {$_SESSION['AdditionalFilterCounters']['Merchant'][$row['Merchant']] = 1;$_SESSION['AdditionalFilters']['Merchant'][$row['Merchant']] = true;}if (!empty($row['SellerName'])) {if (isset($_SESSION['AdditionalFilterCounters']['Seller'][$row['SellerName']])) {$_SESSION['AdditionalFilterCounters']['Seller'][$row['SellerName']]++;} else {$_SESSION['AdditionalFilterCounters']['Seller'][$row['SellerName']] = 1;$_SESSION['AdditionalFilters']['Seller'][$row['SellerName']] = true;}}if (isset($_SESSION['AdditionalFilterCounters']['Condition'][$row['Condition']])) {$_SESSION['AdditionalFilterCounters']['Condition'][$row['Condition']]++;} else {$_SESSION['AdditionalFilterCounters']['Condition'][$row['Condition']] = 1;$_SESSION['AdditionalFilters']['Condition'][$row['Condition']] = true;}if (isset($_SESSION['AdditionalFilterCounters']['MediaType'][$row['MediaType']])) {$_SESSION['AdditionalFilterCounters']['MediaType'][$row['MediaType']]++;} else {$_SESSION['AdditionalFilterCounters']['MediaType'][$row['MediaType']] = 1;$_SESSION['AdditionalFilters']['MediaType'][$row['MediaType']] = true;}if (isset($_SESSION['AdditionalFilterCounters']['DetailCondition'][$row['DetailCondition']])) {$_SESSION['AdditionalFilterCounters']['DetailCondition'][$row['DetailCondition']]++;} else {$_SESSION['AdditionalFilterCounters']['DetailCondition'][$row['DetailCondition']] = 1;$_SESSION['AdditionalFilters']['DetailCondition'][$row['DetailCondition']] = true;}if (isset($_SESSION['AdditionalFilterCounters']['ShippingFrom'][$row['Country']])) {$_SESSION['AdditionalFilterCounters']['ShippingFrom'][$row['Country']]++;} else {$_SESSION['AdditionalFilterCounters']['ShippingFrom'][$row['Country']] = 1;$_SESSION['AdditionalFilters']['ShippingFrom'][$row['Country']] = true;}}}if (isset($_SESSION['AdditionalFilters']['Merchant'])) {ksort($_SESSION['AdditionalFilters']['Merchant'], SORT_NATURAL | SORT_FLAG_CASE);}if (isset($_SESSION['AdditionalFilters']['Seller'])) {ksort($_SESSION['AdditionalFilters']['Seller'], SORT_NATURAL | SORT_FLAG_CASE);}if (isset($_SESSION['AdditionalFilters']['Condition'])) {ksort($_SESSION['AdditionalFilters']['Condition'], SORT_NATURAL | SORT_FLAG_CASE);}if (isset($_SESSION['AdditionalFilters']['DetailCondition'])) {ksort($_SESSION['AdditionalFilters']['DetailCondition'], SORT_NATURAL | SORT_FLAG_CASE);}if (isset($_SESSION['AdditionalFilters']['ShippingFrom'])) {ksort($_SESSION['AdditionalFilters']['ShippingFrom'], SORT_NATURAL | SORT_FLAG_CASE);}if (isset($_SESSION['AdditionalFilters']['MediaType'])) {ksort($_SESSION['AdditionalFilters']['MediaType'], SORT_NATURAL | SORT_FLAG_CASE);}return $arr;}// filter view result table $_SESSION["resultArr"] for detailed filter selectionfunction detailFilterResults($selArr) {if (!empty($selArr['filterCondition'])) {foreach($_SESSION['AdditionalFilters']['Condition'] as $key => $value) {$_SESSION['AdditionalFilters']['Condition'][$key] = false;}if (!is_array($selArr['filterCondition'])) { $selArr['filterCondition'] = [ $selArr['filterCondition'] ];}foreach($selArr['filterCondition'] as $value) {$_SESSION['AdditionalFilters']['Condition'][$value] = true;}} else {$selArr['filterCondition'] = [];if (!empty($_SESSION['AdditionalFilters']['Condition'])) {foreach($_SESSION['AdditionalFilters']['Condition'] as $key => $value) {if ($value) {$selArr['filterCondition'][] = $key;}}}}if (!empty($selArr['filterMediaType'])) {foreach($_SESSION['AdditionalFilters']['MediaType'] as $key => $value) {$_SESSION['AdditionalFilters']['MediaType'][$key] = false;}if (!is_array($selArr['filterMediaType'])) { $selArr['filterMediaType'] = [ $selArr['filterMediaType'] ];}foreach($selArr['filterMediaType'] as $value) {$_SESSION['AdditionalFilters']['MediaType'][$value] = true;}} else {$selArr['filterMediaType'] = [];if (!empty($_SESSION['AdditionalFilters']['MediaType'])) {foreach($_SESSION['AdditionalFilters']['MediaType'] as $key => $value) {if ($value) {$selArr['filterMediaType'][] = $key;}}}}if (!empty($selArr['filterShipFrom'])) {foreach($_SESSION['AdditionalFilters']['ShippingFrom'] as $key => $value) {$_SESSION['AdditionalFilters']['ShippingFrom'][$key] = false;}if (!is_array($selArr['filterShipFrom'])) { $selArr['filterShipFrom'] = [ $selArr['filterShipFrom'] ];}foreach($selArr['filterShipFrom'] as $value) {$_SESSION['AdditionalFilters']['ShippingFrom'][$value] = true;}} else {$selArr['filterShipFrom'] = [];if (!empty($_SESSION['AdditionalFilters']['ShippingFrom'])) {foreach($_SESSION['AdditionalFilters']['ShippingFrom'] as $key => $value) {if ($value) {$selArr['filterShipFrom'][] = $key;}}}}if (!empty($selArr['filterMerchant'])) {foreach($_SESSION['AdditionalFilters']['Merchant'] as $key => $value) {$_SESSION['AdditionalFilters']['Merchant'][$key] = false;}if (!is_array($selArr['filterMerchant'])) { $selArr['filterMerchant'] = [ $selArr['filterMerchant'] ];}foreach($selArr['filterMerchant'] as $value) {$_SESSION['AdditionalFilters']['Merchant'][$value] = true;}} else {$selArr['filterMerchant'] = [];if (!empty($_SESSION['AdditionalFilters']['Merchant'])) {foreach($_SESSION['AdditionalFilters']['Merchant'] as $key => $value) {if ($value) {$selArr['filterMerchant'][] = $key;}}}}foreach ($_SESSION["resultArr"] as & $row) {$row["Show"] = true;if (!in_array($row["Condition"], $selArr['filterCondition']) ||!in_array($row["MediaType"], $selArr['filterMediaType']) ||!in_array($row["Merchant"], $selArr['filterMerchant']) ||!in_array($row["Country"], $selArr['filterShipFrom'])) {$row["Show"] = false;}}}function resetDetailFilter() {if (isset($_SESSION['AdditionalFilters']['Merchant'])) {foreach($_SESSION['AdditionalFilters']['Merchant'] as $key => $field) {$_SESSION['AdditionalFilters']['Merchant'][$key] = true;}}if (isset($_SESSION['AdditionalFilters']['Seller'])) {foreach($_SESSION['AdditionalFilters']['Seller'] as $key => $field) {$_SESSION['AdditionalFilters']['Seller'][$key] = true;}}if (isset($_SESSION['AdditionalFilters']['Condition'])) {foreach($_SESSION['AdditionalFilters']['Condition'] as $key => $field) {$_SESSION['AdditionalFilters']['Condition'][$key] = true;}}if (isset($_SESSION['AdditionalFilters']['DetailCondition'])) {foreach($_SESSION['AdditionalFilters']['DetailCondition'] as $key => $field) {$_SESSION['AdditionalFilters']['DetailCondition'][$key] = true;}}if (isset($_SESSION['AdditionalFilters']['ShippingFrom'])) {foreach($_SESSION['AdditionalFilters']['ShippingFrom'] as $key => $field) {$_SESSION['AdditionalFilters']['ShippingFrom'][$key] = true;}}if (isset($_SESSION['AdditionalFilters']['MediaType'])) {foreach($_SESSION['AdditionalFilters']['MediaType'] as $key => $field) {$_SESSION['AdditionalFilters']['MediaType'][$key] = true;}}foreach ($_SESSION["resultArr"] as & $row) {$row["Show"] = true;}}// print result table or card deckfunction printResult() {if ($_SESSION["currentLayout"] == 'TableView') {return buildTable($_SESSION["resultArr"]);}else /* CardView */ {return buildCardDeck($_SESSION["resultArr"]);}}// build HTML table from arrayfunction buildTable($arr) {global $mediaTypeTextArr;global $mediaTypeIconArr;global $buyItNowTooltip;$str = "";if (count($arr) > 0) {$str .= "<div class=\"table\">"; // bugbug responsive?$str .= "<table class=\"table table-striped table-condensed table-hover small bg-info\">";$str .= "<thead class=\"thead-dark table-header-sticky\"><tr><th>Image</th><th class=\"text-left\">Title / Merchant</th><th>Condition</th><th class=\"hide-small\">Price</th><th class=\"hide-small\">S/H</th><th>Total</th><th class=\"hide-extra-small\"></th></tr></thead>";$str .= "<tbody>";foreach ($arr as $row) {if (!$row["Show"]) {continue;}$href = "href=\"" . $row["URL"] . "\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" onclick=\"saveTransfer('" . $row["URL"] . "'); return true;\"";$title = $row["Title"];if (mb_strlen($row["Title"], 'UTF-8') > MAXTITLELENGTH) {$title = mb_substr($row["Title"], 0, MAXTITLELENGTH, 'UTF-8') . '...';}$str .= "<tr>";// Image$str .= "<td><a " . $href . " data-toggle=\"tooltip\" title=\"" . $buyItNowTooltip . "\"><img class=\"img-fluid lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . $row["Image"] . "\" alt=\"Item Image\"></a></td>";// Title / Merchant$str .= "<td class=\"text-left\"><span class=\"font-weight-bold\"><a class=\"bg-info\" " . $href . " data-toggle=\"tooltip\" title=\"" . $buyItNowTooltip . "\">" . $title . "</a></span>";$str .= "<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>";$mediaTypeIcon = 'media-icon ' . $mediaTypeIconArr[$row["MediaType"]];$tooltip = $mediaTypeTextArr[$row["MediaType"]];$str .= "<span class=\"font-weight-bold\">" . $row["DetailCondition"] . "</span>";$str .= "<br/><br/>";$str .= "<i class=\"" . $mediaTypeIcon . "\" 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/>≈ " . 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["ShippingEstimated"]) {$str .= "*";}}if ($row["ShippingCost"] > 0.00 && $row["ShippingCurrency"] != $_SESSION["buyer"]["Currency"]) {$str .= "<br/>≈ " . 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 lazyload\" title=\"Ships from " . getCountry($row["Country"]) . "\" data-toggle=\"tooltip\" data-placement=\"right\" data-delay=\"200\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . timeStampUrl("images/flags/" . $row["Country"] . ".png") . "\" alt=\"" . getCountry($row["Country"]) . " Flag\"></td>";// Total Price$str .= "<td class=\"font-weight-bolder\">" . print_monetary($row["ConvertedTotalPrice"], $_SESSION["buyer"]["Currency"]) . "</td>";// Linkif ($row["Merchant"] == "iTunes") {if ($row["MediaType"] == "Digital") {$badge = timeStampUrl("images/US-UK_Apple_Music_Badge_RGB.svg");}else {$badge = timeStampUrl("images/US_UK_Apple_Books_Badge_Get_RGB_071818.svg");}$linkImage = "<a class=\"btn\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><img class=\"lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . $badge . "\" alt=\"iTunes Badge\"></a>";} else if (strpos($row["Merchant"], "eBay") !== false) {$linkImage = "<a class=\"btn\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><img class=\"lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . timeStampUrl("images/ebay-right-now.gif") . "\" alt=\"iTunes Badge\"></a>";} else if (strpos($row["Merchant"], "Amazon") !== false) {$linkImage = "<a class=\"btn\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><img class=\"lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . timeStampUrl("images/amazon-buy3.gif") . "\" alt=\"iTunes Badge\"></a>";} else {$linkImage = "<a class=\"btn btn-danger\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><i class=\"fas fa-shopping-cart btn-shop\"></i></a>";}$str .= "<td class=\"hide-extra-small text-center\">" . $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>";$str .= "</div>";}else {$str = printNoResultsWarning();}return ($str);}// build HTML card deck from arrayfunction buildCardDeck($arr) {global $mediaTypeTextArr;global $mediaTypeIconArr;global $buyItNowTooltip;$str = "";if (count($arr) > 0) {$str .= "<div class=\"card-deck small\">";foreach ($arr as $row) {if (!$row["Show"]) {continue;}$href = "href=\"" . $row["URL"] . "\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" onclick=\"saveTransfer('" . $row["URL"] . "'); return true;\"";$title = $row["Title"];if (mb_strlen($row["Title"], 'UTF-8') > MAXTITLELENGTH) {$title = mb_substr($row["Title"], 0, MAXTITLELENGTH, 'UTF-8') . '...';}$str .= "<div class=\"card m-2 shadow mx-auto result-card\">";// Image$str .= "<a class=\"p-0 m-0 bg-light text-center result-image\" " . $href . " data-toggle=\"tooltip\" title=\"" . $buyItNowTooltip . "\"><img class=\"p-0 m-0 responsive-image lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . $row["Image"] . "\" alt=\"Item Image\"></a>";$str .= "<div class=\"card-body bg-light d-flex flex-column\">";// Title / Merchant$str .= "<p class=\"card-title font-weight-bold\"><a " . $href . " data-toggle=\"tooltip\" title=\"" . $buyItNowTooltip . "\">" . $title . "</a></p>";$str .= "<div class=\"card-text mt-auto\"><span class=\"font-weight-bold\">" . $row["Merchant"] . "</span>";$str .= "<br>";// Condition / MediaType$mediaTypeIcon = 'media-icon ' . $mediaTypeIconArr[$row["MediaType"]];$tooltip = $mediaTypeTextArr[$row["MediaType"]];$str .= $row["DetailCondition"];$str .= "<i class=\"float-right " . $mediaTypeIcon . "\" title=\"" . $tooltip . "\" data-toggle=\"tooltip\" data-placement=\"right\" data-delay=\"200\"></i>";$str .= "<br>";// Total Price$str .= "<span class=\"font-weight-bolder\">" . print_monetary($row["ConvertedTotalPrice"], $_SESSION["buyer"]["Currency"]) . "</span>";$str .= "</div>";$str .= "</div>";// Link / Ships from Flag$str .= "<div class=\"card-footer bg-dark\">";$str .= "<div class=\"row\">";$str .= "<div class=\"col-9\">";if ($row["Merchant"] == "iTunes") {if ($row["MediaType"] == "Digital") {$badge = timeStampUrl("images/US-UK_Apple_Music_Badge_RGB.svg");}else {$badge = timeStampUrl("images/US_UK_Apple_Books_Badge_Get_RGB_071818.svg");}$linkImage = "<a class=\"btn p-0 m-0\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><img class=\"img-fluid p-0 m-0 lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . $badge . "\" alt=\"iTunes Badge\"></a>";} else if (strpos($row["Merchant"], "eBay") !== false) {$linkImage = "<a class=\"btn p-0 m-0\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><img class=\"img-fluid p-0 m-0 lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . timeStampUrl("images/ebay-right-now.gif") . "\" alt=\"iTunes Badge\"></a>";} else if (strpos($row["Merchant"], "Amazon") !== false) {$linkImage = "<a class=\"btn p-0 m-0\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><img class=\"img-fluid p-0 m-0 lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . timeStampUrl("images/amazon-buy3.gif") . "\" alt=\"iTunes Badge\"></a>";}else {$linkImage = "<a class=\"btn btn-danger m-0\" title=\"" . $buyItNowTooltip . "\" aria-label=\"Go to store\" data-toggle=\"tooltip\" role=\"button\" " . $href . "><i class=\"fas fa-shopping-cart\"></i></a>";}$str .= $linkImage;$str .= "</div>";$str .= "<div class=\"col-3\">";$str .= "<img class=\"float-right lazyload\" title=\"Ships from " . getCountry($row["Country"]) . "\" data-toggle=\"tooltip\" data-placement=\"right\" data-delay=\"200\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . timeStampUrl("images/flags/" . $row["Country"] . ".png") . "\" alt=\"" . getCountry($row["Country"]) . " Flag\">";$str .= "</div>";$str .= "</div>";$str .= "</div>";$str .= "</div>";}$str .= "</div>";$str .= "<div class=\"py-2 text-right\"><p class=\"font-italic\">Prices retrieved on " . gmdate("Y-m-d H:i") . " UTC<br>Daily exchange rates update</p></div>";}else {$str = printNoResultsWarning();}return ($str);}// print directions when no results are foundfunction printNoResultsWarning() {$str = "<div class=\"text-center bg-warning p-3 rounded\">";$str .= "<p class=\"display-5 font-weight-bold\">Your search returned no store offers</p>";$str .= "<p>You may want to try the following:</p>";$str .= "<ul><li>Check the spelling</li><li>Try using fewer words</li><li>Try using artist and title if you used a barcode; some albums have been released under various barcodes</li></ul>";$str .= "</div>";return $str;}function printResultHeader() {$str = '';$str .= '<nav class="navbar bg-black mt-2 pb-0">';$str .= '<span class="mr-3">';if ($_SESSION["lowestPrice"]["New"] > 0) {$str .= 'New from ' . print_monetary($_SESSION["lowestPrice"]["New"], $_SESSION["buyer"]["Currency"]);}if ($_SESSION["lowestPrice"]["New"] > 0 && $_SESSION["lowestPrice"]["Used"] > 0) {$str .= '<br>';}if ($_SESSION["lowestPrice"]["Used"] > 0) {$str .= 'Used from ' . print_monetary($_SESSION["lowestPrice"]["Used"], $_SESSION["buyer"]["Currency"]);}$str .= '</span>';$str .= '<ul class="nav nav-tabs ml-3">';$str .= ' <li class="nav-item border-0">';$str .= ' <a id="detailTab" class="nav-link active bg-white" href="#detailFilter">Filter <span id="detailTabArrow"><i class="fas fa-caret-down"></i></span></a>';$str .= ' </li>';$str .= '</ul>';$str .= '<span class="ml-auto">';if ($_SESSION["currentLayout"] == 'CardView') {$str .= ' <button name="submit" value="TableView" type="submit" class="btn btn-sm filterButtonSmall btn-primary active"';$str .= ' data-toggle="tooltip" title="Table View" aria-label="Results Table View" onclick="$(this).tooltip(\'hide\');"><span class="display-6 font-weight-bolder"><i class="fas fa-th-list"></i></span></button>';} else {$str .= ' <button name="submit" value="CardView" aria-label="Results Card View" type="submit" class="btn btn-sm filterButtonSmall btn-primary active"';$str .= ' data-toggle="tooltip" title="Card View" onclick="$(this).tooltip(\'hide\');"><span class="display-6 font-weight-bolder"><i class="fas fa-th-large"></i></span></button>';}$str .= '</span>';$str .= '<span class="navbar-text text-white float-right ml-3">Showing ' . count(array_filter($_SESSION["resultArr"], function ($entry) { return ($entry['Show'] === true); })) . ' of ' . count($_SESSION["resultArr"]) . '</span>';$str .= '</nav>';$str .= '<div class="tab-content mb-3 bg-white">';$str .= ' <div id="detailFilter" class="container tab-pane bg-white"><br>';$str .= detailResultHeader();$str .= ' </div>';$str .= '</div>';return $str;}// print summary/header on top of listing tablefunction detailResultHeader() {global $mediaTypeTextArr;global $mediaTypeIconArr;$str = '';$str .= ' <form id="detailFilterForm">';$str .= ' <input type="hidden" name="sessionTab" value="' . MySessionHandler::getSessionTab() . '">';$str .= ' <div class="">';$str .= ' <div class="card-group">';$str .= '';// Conditionif (isset($_SESSION['AdditionalFilterCounters']['Condition'])) {$str .= ' <div class="card m-2">';$str .= ' <div class="card-header font-weight-bold">Condition</div>';$str .= ' <div class="card-body">';$cnt = count($_SESSION['AdditionalFilterCounters']['Condition']);foreach($_SESSION['AdditionalFilters']['Condition'] as $key => $value) {$str .= ' <div class="form-check">';$str .= ' <label class="form-check-label">';$str .= ' <input name="filterCondition[]" type="checkbox" value="' . $key . '" class="form-check-input"';$str .= ($value ? " checked" : "");$str .= ($cnt > 2 ? "" : " disabled");$str .= '>' . $key . '<span class="badge badge-pill badge-dark ml-2">' . $_SESSION['AdditionalFilterCounters']['Condition'][$key] . '</span>';$str .= ' </label>';$str .= ' </div>';}$str .= ' </div>';$str .= ' </div>';}// Media Typeif (isset($_SESSION['AdditionalFilterCounters']['MediaType'])) {$str .= ' <div class="card m-2">';$str .= ' <div class="card-header font-weight-bold">Media Type</div>';$str .= ' <div class="card-body">';$cnt = count($_SESSION['AdditionalFilterCounters']['MediaType']);foreach($_SESSION['AdditionalFilters']['MediaType'] as $key => $value) {$str .= ' <div class="form-check">';$str .= ' <label class="form-check-label">';$str .= ' <input name="filterMediaType[]" type="checkbox" value="' . $key . '" class="form-check-input"';$str .= ($value ? " checked" : "");$str .= ($cnt > 1 ? "" : " disabled");$str .= '><i class="' . $mediaTypeIconArr[$key] . '"></i> ' . $mediaTypeTextArr[$key];$str .= '<span class="badge badge-pill badge-dark ml-2">' . $_SESSION['AdditionalFilterCounters']['MediaType'][$key] . '</span>';$str .= ' </label>';$str .= ' </div>';}$str .= ' </div>';$str .= ' </div>';}// Merchantif (isset($_SESSION['AdditionalFilterCounters']['Merchant'])) {$str .= ' <div class="card m-2">';$str .= ' <div class="card-header font-weight-bold">Merchant</div>';$str .= ' <div class="card-body">';$cnt = count($_SESSION['AdditionalFilterCounters']['Merchant']);foreach($_SESSION['AdditionalFilters']['Merchant'] as $key => $value) {$str .= ' <div class="form-check">';$str .= ' <label class="form-check-label">';$str .= ' <input name="filterMerchant[]" type="checkbox" value="' . $key . '" class="form-check-input"';$str .= ($value ? " checked" : "");$str .= ($cnt > 1 ? "" : " disabled");$str .= '>' . $key . '<span class="badge badge-pill badge-dark ml-2">' . $_SESSION['AdditionalFilterCounters']['Merchant'][$key] . '</span>';$str .= ' </label>';$str .= ' </div>';}$str .= ' </div>';$str .= ' </div>';}// Shipping Fromif (isset($_SESSION['AdditionalFilterCounters']['ShippingFrom'])) {$str .= ' <div class="card m-2">';$str .= ' <div class="card-header font-weight-bold">Shipping From</div>';$str .= ' <div class="card-body">';$cnt = count($_SESSION['AdditionalFilterCounters']['ShippingFrom']);foreach($_SESSION['AdditionalFilters']['ShippingFrom'] as $key => $value) {$str .= ' <div class="form-check">';$str .= ' <label class="form-check-label">';$str .= ' <input name="filterShipFrom[]" type="checkbox" value="' . $key . '" class="form-check-input"';$str .= ($value ? " checked" : "");$str .= ($cnt > 1 ? "" : " disabled");$str .= '><img class="img-fluid lazyload" title="Ships from ' . getCountry($key) . '" data-toggle="tooltip" data-delay="200" src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="' . timeStampUrl("images/flags/" . $key . ".png") . '" alt="' . getCountry($key) . ' Flag"><span class="badge badge-pill badge-dark ml-2">' . $_SESSION['AdditionalFilterCounters']['ShippingFrom'][$key] . '</span>';$str .= ' </label>';$str .= ' </div>';}$str .= ' </div>';$str .= ' </div>';}$str .= ' </div>';$str .= ' </div>';$str .= '';$str .= ' <div class="p-2">';$str .= ' <button type="submit" class="btn btn-success detailFilterButton" name="submit" value="Apply">Apply</button>';$str .= ' <button type="submit" class="btn btn-danger detailFilterButton" name="submit" value="Reset">Reset</button>';$str .= ' </div>';$str .= ' </form>';return $str;}// compare price for sort low to highfunction compare_price($a, $b) {return strnatcmp($a['ConvertedTotalPrice'], $b['ConvertedTotalPrice']);}// print monetary values with correct symbol and thousands/decimal delimitersfunction 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, ',', '.') . "€");}else if ($curr == "GBP") {return ("£" . number_format($num, 2, '.', ','));}else if ($curr == "AUD") {return ("AU $" . number_format($num, 2, '.', ','));}return ($curr . " " . number_format($num, 2, '.', ','));}// find lowest used / new pricesfunction findLowestCondition($condition) {foreach ($_SESSION["resultArr"] as $row) {if (!$row["Show"]) {continue;}if ($condition == $row["Condition"]) {return ($row["ConvertedTotalPrice"]);}}return (0);}// find lowest cd, record, digital and book pricesfunction findLowestMediaType($mediaType) {foreach ($_SESSION["resultArr"] as $row) {if (!$row["Show"]) {continue;}if ($mediaType == $row["MediaType"]) {return ($row["ConvertedTotalPrice"]);}}return (0);}// find lowest non-zero double value in arrayfunction minNotNull(Array $values) {return min(array_diff(array_map('doubleval', $values) , array(0)));}// apply exchange ratesfunction 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 inputfunction 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 asciifunction 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 stringfunction 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 whitespacesreturn ucwords($str);}// get a SESSION value, return empty string if not setfunction getSV($var) {if (!isset($_SESSION[$var])) {return ('');}return ($_SESSION[$var]);}// initialize a SESSION value if not setfunction initSV($var, $value) {if (!isset($_SESSION[$var])) {$_SESSION[$var] = $value;}}// initialize sessions variablesfunction 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("currentLayout", "TableView");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 notfunction checkPV($var) {if (isset($_POST[$var])) {return (true);}return (false);}// get POST or GET value, return empty if not setfunction getPGV($var) {if (isset($_POST[$var])) {return ($_POST[$var]);}else if (isset($_GET[$var])) {return ($_GET[$var]);}return ("");}// print search filter modal with current selectionfunction printSearchFilterModal() {global $mediaTypeTextArr;global $mediaTypeIconArr;$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 .= ' <p class="modal-title display-5">Search Filters</p>';$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="filterCondition[]" 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="filterCondition[]" 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="filterMediaType[]" type="checkbox" class="form-check-input" value="CD"' . ($_SESSION["filterMediaType"]["CD"] ? " checked" : "") . '><i class="' . $mediaTypeIconArr["CD"] . '"></i> ' . $mediaTypeTextArr["CD"];$str .= ' </label>';$str .= ' </div>';$str .= ' <div class="form-check">';$str .= ' <label class="form-check-label">';$str .= ' <input name="filterMediaType[]" type="checkbox" class="form-check-input" value="Record"' . ($_SESSION["filterMediaType"]["Record"] ? " checked" : "") . '><i class="' . $mediaTypeIconArr["Record"] . '"></i> ' . $mediaTypeTextArr["Record"];$str .= ' </label>';$str .= ' </div>';$str .= ' <div class="form-check">';$str .= ' <label class="form-check-label">';$str .= ' <input name="filterMediaType[]" type="checkbox" class="form-check-input" value="Digital"' . ($_SESSION["filterMediaType"]["Digital"] ? " checked" : "") . '><i class="' . $mediaTypeIconArr["Digital"] . '"></i> ' . $mediaTypeTextArr["Digital"];$str .= ' </label>';$str .= ' </div>';$str .= ' <div class="form-check">';$str .= ' <label class="form-check-label">';$str .= ' <input name="filterMediaType[]" type="checkbox" class="form-check-input" value="Book"' . ($_SESSION["filterMediaType"]["Book"] ? " checked" : "") . '><i class="' . $mediaTypeIconArr["Book"] . '"></i> ' . $mediaTypeTextArr["Book"];$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 modalfunction printSearchInfoModal() {global $mediaTypeTextArr;global $mediaTypeIconArr;$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 .= ' <p class="modal-title display-5">Search Tips</p>';$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 text-dark">';/*$str .= ' <div class="shadow p-4 mb-4 bg-white">';$str .= ' <p class="display-5"><i class="fas fa-filter"></i> Filter</p>';$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="' . $mediaTypeIconArr["CD"] . '"></i> "' . $mediaTypeTextArr["CD"] . '", <i class="' . $mediaTypeIconArr["Record"] . '"></i> "' . $mediaTypeTextArr["Record"] . '", <i class="' . $mediaTypeIconArr["Digital"] . '"></i> "' . $mediaTypeTextArr["Digital"] . '" and / or <i class="' . $mediaTypeIconArr["Book"] . '"></i> "' . $mediaTypeTextArr["Book"] . '". The standard is to search for all types.</p>';$str .= ' </div>';$str .= ' <div class="shadow p-4 mb-4 bg-white">';$str .= ' <p class="display-5"><i class="fas fa-shipping-fast"></i> Shipping To</p>';$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 .= ' <p class="display-5"><i class="fas fa-search"></i> Search Keywords</p>';$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. See our <a href="https://blog.findcheapmusic.com/2020/03/music-cd-barcodes-and-identifiers.html" target="_blank" rel="noopener noreferrer">blog post</a> for more information about music barcodes.</p>';$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. You can later narrow your search further down, if necessary.</p>';$str .= ' <p><span class="font-italic">The search algorithm prefers the barcode number whenever available. Since some albums have been released under various barcodes, try searching again for artist and title should the barcode search come up empty.</span></p>';$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']);$ip = inet_pton($_SERVER['REMOTE_ADDR']);$sql = "INSERTINTO searches(sessId, access, ip, zip, condNew, condUsed, mediaCD, mediaRecord, mediaDigital, mediaBook, data, lowNew, lowUsed, lowDigital, lowBook, count, userId)VALUES ('" . session_id() . "', '$access', '$ip', '$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-agentif ($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_CONNECTTIMEOUT, 5);curl_setopt($ch, CURLOPT_TIMEOUT, 15);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 idfunction 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 codesfunction getCouponCodes() {$str = "";$lastAdvertiser = "";if (!isLoggedIn()) {return ('<div class="container bg-warning text-center py-3"><p class="display-6"><i class="fas fa-bookmark"></i> Please login to your Find Cheap Music account in order to see the coupons.</p></div>');}$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';$conn = MySessionHandler::getDBSessionId();if ($result = mysqli_query($conn, $sql)) {if (mysqli_num_rows($result) > 0) {$str .= "<div class=\"container py-4 bg-secondary border\">";while ($row = mysqli_fetch_assoc($result)) {if ($row["advertiser"] != $lastAdvertiser) {if (!empty($lastAdvertiser)) {$str .= "</ul>";}$str .= "<h2 class=\"bg-primary text-center mt-3 mb-1\">" . $row["advertiser"] . "</h2>";$str .= "<ul class=\"list-group\">";$lastAdvertiser = $row["advertiser"];}if (!empty($row["url"])) {$str .= "<li class=\"list-group-item\"><a class=\"btn btn-link text-left\" target=\"_blank\" href=\"";$str .= $row["url"];$str .= "\" rel=\"nofollow noreferrer noopener\">";$str .= "<strong>" . $row["description"] . "</strong> until " . $row["enddate"];if (!empty($row["couponcode"])) {$str .= " (Use Coupon Code \"" . $row["couponcode"] . "\")";}$str .= "</a>";if (!empty($row["pixel"])) {$str .= "<img class=\"lazyload\" src=\"data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=\" data-src=\"" . $row["pixel"] . "\" width=\"1\" height=\"1\" class=\"border-0\" alt=\"" . $row["advertiser"] . " Coupon\"/>";}$str .= "</li>";}}$str .= "</ul>";$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 daysfunction cleanupPbFiles() {$files = glob("../MyFiles/tmp/pb*.txt");$now = time();foreach ($files as $file) {if (is_file($file)) {if ($now - filemtime($file) >= 60 * 60 * 24 * 2) { // 2 days and olderunlink($file);}}}}// Update progressbar file for a sessionfunction updatePbFile($flag = false) {static $max_pb = 15; // max progressbar stepsstatic $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 = "../MyFiles/tmp/pb_" . $filename . ".txt";if ($percent >= 100) {@unlink($file);} else {file_put_contents($file, json_encode($arr_content));}}// Linkshare / CJ Affiliate csv dumpfunction 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 checkfunction isLoggedIn() {return (!empty($_SESSION['sessData']['userLoggedIn']) && !empty($_SESSION['sessData']['userID'])) ? true : false;}// unset all login system session datafunction unsetSessData() {unset($_SESSION['sessData']['userLoggedIn']);unset($_SESSION['sessData']['userID']);unset($_SESSION['sessData']['loginType']);}// get user image namefunction getUserImage($userData) {if (empty($userData) || empty($userData['picture'])) {return 'login/assets/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;}}// fuzzy search to verify titles are relevantfunction verifyResultArr() {require_once ('php/Fuse/Bitap/Bitap.php');require_once ('php/Fuse/Bitap/matched_indices.php');require_once ('php/Fuse/Bitap/pattern_alphabet.php');require_once ('php/Fuse/Bitap/regex_search.php');require_once ('php/Fuse/Bitap/score.php');require_once ('php/Fuse/Bitap/search.php');require_once ('php/Fuse/Helpers/deep_value.php');require_once ('php/Fuse/Helpers/is_list.php');require_once ('php/Fuse/Fuse.php');if (!empty($_SESSION["barcode"]["Value"]) || empty($_SESSION["resultArr"])) {return;}$options = ['shouldSort' => false,// 'tokenize' => true,// 'matchAllTokens' => true,// 'findAllMatches' => true,'includeScore' => true,'includeMatches' => true,'threshold' => 0.6,'location' => 0,'distance' => 100,'minMatchCharLength' => 5,'keys' => [ "Title" ]];$fuse = new Fuse($_SESSION["resultArr"], $options);$result = $fuse->search($_SESSION["searchTerm"]);$_SESSION["resultArr"] = [];foreach($result as $r) {$r['item']['score'] = (!empty($r['score']) ? $r['score'] : 0);$r['item']['indices'] = (!empty($r['matches'][0]['indices']) ? $r['matches'][0]['indices'] : []);$_SESSION['resultArr'][] = $r['item'];}/* debug start$lines = [];foreach($_SESSION['resultArr'] as $r) {$p = 0;$t = '';foreach($r['indices'] as $ind) {if ($p < $ind[0]) {$t .= substr($r['Title'], $p, $ind[0] - $p);}$t .= "<b>" . substr($r['Title'], $ind[0], $ind[1] - $ind[0] + 1) . "</b>";$p = $ind[1] + 1;}if ($p < strlen($r['Title'])) {$t .= substr($r['Title'], $p);}$lines[] = array ('score' => $r['score'], 'title' => $t);}usort($lines, 'compare_score');echo "<p>";foreach($lines as $l) {echo $l['score'] . ": " . $l['title'] . "<br/>";}echo "</p>";debug end */}// compare score for sort low to highfunction compare_score($a, $b) {return ($a['score'] > $b['score']);}function my_error_log($msg) {error_log("[" . date("d-M-Y H:m:s") . "] " . $msg . PHP_EOL, 3, $_SERVER['DOCUMENT_ROOT'] . "/../MyFiles/logs/my_php_error.log");}function saveSearchCache($vendor, $query, $subquery, $text) {$conn = MySessionHandler::getDBSessionId();$created = mysqli_real_escape_string($conn, time());$v = mysqli_real_escape_string($conn, $vendor);$q = mysqli_real_escape_string($conn, $query);$s = mysqli_real_escape_string($conn, $subquery);$r = base64_encode(gzencode($text));$sql = "INSERTINTO searchCache(created, vendor, query, subquery, result)VALUES ('$created', '$v', '$q', '$s', '$r')ON DUPLICATE KEY UPDATE result = '$r'";if (!($result = mysqli_query($conn, $sql))) {error_log("MySQL Write SearchCache Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");}return $result;}function expireSearchCache() {$conn = MySessionHandler::getDBSessionId();$t = MySessionHandler::getDBExpirationTime();$expired = mysqli_real_escape_string($conn, time() - $t);$sql = "DELETEFROM searchCacheWHERE created < $expired";if (!($result = mysqli_query($conn, $sql))) {error_log("MySQL Delete SearchCache Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");}}function getSearchCache($vendor, $query, $subquery) {$conn = MySessionHandler::getDBSessionId();$v = mysqli_real_escape_string($conn, $vendor);$q = mysqli_real_escape_string($conn, $query);$s = mysqli_real_escape_string($conn, $subquery);$sql = "select result from searchCache where vendor = '$v' and query = '$q' and subquery = '$s'";if ($result = mysqli_query($conn, $sql)) {if (mysqli_num_rows($result) == 1) {if ($row = mysqli_fetch_assoc($result)) {return gzdecode(base64_decode($row["result"]));}}}else if (mysqli_errno($conn)) {error_log("MySQL Read SearchCache SQL: " . $sql);error_log("MySQL Read SearchCache Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");}return false;}function getGeoLocation() {if (!empty($_SESSION['buyer']['Zip']) || empty($_SERVER['REMOTE_ADDR'])) {return;}$conn = MySessionHandler::getDBSessionId();$ip = inet_pton($_SERVER['REMOTE_ADDR']);$sql = "select zip from geoLocation where ip = '$ip'";if ($result = mysqli_query($conn, $sql)) {if (mysqli_num_rows($result) == 1) {if ($row = mysqli_fetch_assoc($result)) {$_SESSION['buyer']['Zip'] = $row["zip"];return;}}}else if (mysqli_errno($conn)) {error_log("MySQL Read geoLocation SQL: " . $sql);error_log("MySQL Read geoLocation Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");}$vendors = Vendors::getInstance();$config = $vendors->getVendor(Vendors::IPAPI);$key = $config['KEY'];$loc = file_get_contents("http://api.ipapi.com/api/" . $_SERVER['REMOTE_ADDR'] . "?access_key=" . $key);if ($loc == false) {return;}$json = json_decode($loc);if (!empty($json->error)) {error_log("geoLocation Error: " . $json->error->info . " (" . $json->error->code . " | " . $json->error->type . ")");return;}$created = mysqli_real_escape_string($conn, time());$countryCode = mysqli_real_escape_string($conn, $json->{'country_code'});$zip = mysqli_real_escape_string($conn, $json->zip);$language = mysqli_real_escape_string($conn, $json->location->languages[0]->code);$is_eu = mysqli_real_escape_string($conn, $json->location->{'is_eu'} ? '1' : '0');$sql = "INSERTINTO geoLocation(ip, created, countryCode, zip, language, is_eu)VALUES ('$ip', $created, '$countryCode', '$zip', '$language', '$is_eu')";if (!($result = mysqli_query($conn, $sql))) {error_log("MySQL Write geoLocation Error: " . mysqli_error($conn) . " (" . mysqli_errno($conn) . ")");}}function timeStampUrl($file) {if (file_exists($file)) {return $file . "?" . filemtime($file);}return $file;}