/**
* Gets price filter menu that appears on left hand side of shop-front website
*
* @return string
*/
public static function getPriceMenu() {
// Initialise string holding HTML for the price range filter menu's content
$strContent = "";
// Before we do anything, check if the data requested is cached. If it is then just
// set the cached HTML as the content of the menu
$objCache = new cachePrices();
if ($objCache->load($_SERVER['REQUEST_URI'])) $strContent = $objCache->strContent;
// Else generate a new menu
else {
// Only show price range menu when we're at least at a level 1 category
if (category::getLevel() >= 1) {
global $objDB;
global $arrUrlPart;
// If there is an active price range filter, display a notice saying so and provide an
// option to remove the filter
if ($arrActivePR = self::getPriceRangeFromUrl()) {
$intFrom = $arrActivePR[0];
$intTo = $arrActivePR[1];
$strHref = "/";
foreach ($arrUrlPart as $intKey => $strUrlPart) {
if (substr($strUrlPart, 0, 6) != "price-") $strHref.= $strUrlPart . "/";
}
$strContent.= "Filtering by products priced between <strong>£$intFrom - £$intTo</strong>\n" .
"<br /><br style=\"line-height: 5px\" />\n" .
"<p class=\"menuItem\"><img src=\"/img/menuItemArrow.gif\" /> <a href=\"$strHref\">Show all price ranges</a></p>\n";
}
// Else display a list of appropriate price range options
else {
$objCategory = new category(category::getIdFromUrl());
$objCategory->loadChildCats($objCategory->idCategory, category::getLevel());
// Get the total number of products being displayed
$intProducts = category::getNumProducts($objCategory->idCategory);
// Only show price range menu when there are more than 10 being displayed
if ($intProducts > 10) {
// Get all the individual prices
$strSQL = "SELECT intPrice FROM product
WHERE idCategory IN ($objCategory->idCategory";
if (count($objCategory->arrChildCat) > 0) {
$strSQL.= ", " . implode(", ", $objCategory->arrChildCat) . ")";
}
else $strSQL.= ")";
$idBrand = brand::getIdFromUrl();
if ($idBrand > 0) $strSQL.= " AND idBrand = " . $idBrand;
$strSQL.= " ORDER BY intPrice ASC";
$objResult = $objDB->query($strSQL);
// Calculate desired number of items per price range
if ($intProducts <= 30) $intDesired = round($intProducts / 3);
elseif (($intProducts > 30) && ($intProducts <= 40)) $intDesired = round($intProducts / 4);
elseif (($intProducts > 40) && ($intProducts <= 50)) $intDesired = round($intProducts / 5);
elseif ($intProducts > 50) $intDesired = round($intProducts / 6);
$arrPR = array(); // Initialise array that will hold price range data
$intRecord = 0; // Initialise counter for current record in loop
$intPR = 0; // Initialise counter for current price range
while ($objRow = $objResult->fetch_object()) {
$intRecord++;
// Set rule for calculating how much to increase/decrease price range
// start/end values by to find the appropriate one
if ($objRow->intPrice <= 5000) $intRule = 500;
elseif (($objRow->intPrice > 5000) && ($objRow->intPrice <= 10000)) $intRule = 1000;
elseif (($objRow->intPrice > 10000) && ($objRow->intPrice <= 30000)) $intRule = 5000;
elseif (($objRow->intPrice > 30000) && ($objRow->intPrice <= 100000)) $intRule = 10000;
elseif ($objRow->intPrice > 100000) $intRule = 50000;
// Set the current price range's start figure if not done already
if (!isset($arrPR[$intPR]["intFrom"])) {
// If this is the first record, we need to calculate it
if ($intRecord == 1) {
// Set start value to 0
$intFrom = 0;
// Keep incrementing by the rule amount until the start value overtakes
// the current price in the loop
while ($intFrom <= $objRow->intPrice) $intFrom = $intFrom + $intRule;
// Then decrement once by the rule amount to give the final start figure
$arrPR[$intPR]["intFrom"] = $intFrom - $intRule;
}
// Else the start figure is set to the end figure of the previous price range
else $arrPR[$intPR]["intFrom"] = $arrPR[$intPR - 1]["intTo"];
}
// Set the current price range's end figure if not done already
if (!isset($arrPR[$intPR]["intTo"])) {
// Set the end value to the start value
$intTo = $arrPR[$intPR]["intFrom"];
// Keep incrementing by the rule amount until the end value overtakes
// the current price in the loop and then you've got the desired value
while ($intTo <= $objRow->intPrice) $intTo = $intTo + $intRule;
$arrPR[$intPR]["intTo"] = $intTo;
}
// If the current price is less than or equal to the end value, increment
// the products counter for the current price range
if ($objRow->intPrice <= $arrPR[$intPR]["intTo"]) $arrPR[$intPR]["intProducts"]++;
// Else we need to increment the end value by the rule amount until the
// current price is less than or equal to it
else {
while ($objRow->intPrice > $arrPR[$intPR]["intTo"]) {
$arrPR[$intPR]["intTo"] = $arrPR[$intPR]["intTo"] + $intRule;
}
// And then increment the products counter for the current price range
$arrPR[$intPR]["intProducts"]++;
}
// If we've filled the current price range with the desired amount of
// products, then move onto the next one
if ($arrPR[$intPR]["intProducts"] >= $intDesired) $intPR++;
}
// The number of products figure for each price range is going to probably
// be close to the correct amount but not exact due to the way I've coded
// this (not wonderfully). As a short term quick fix I decided to loop
// through each price range and run a query to find the correct amount of
// products that should be displayed as a result of activating the price
// range filter
for ($i = 0; $i < count($arrPR); $i++) {
$strSQL = "SELECT COUNT(idProduct) AS intProducts FROM product
WHERE idCategory IN ($objCategory->idCategory";
if (count($objCategory->arrChildCat) > 0) {
$strSQL.= ", " . implode(", ", $objCategory->arrChildCat) . ")";
}
else $strSQL.= ")";
$idBrand = brand::getIdFromUrl();
if ($idBrand > 0) $strSQL.= " AND idBrand = " . $idBrand;
$strSQL.= " AND intPrice >= " . $arrPR[$i]["intFrom"] . "
AND intPrice <= " . $arrPR[$i]["intTo"];
$objResult = $objDB->query($strSQL);
if ($objResult->num_rows > 0) {
$objRow = $objResult->fetch_object();
$arrPR[$i]["intProducts"] = $objRow->intProducts;
}
else $arrPR[$i]["intProducts"] = 0;
}
// Create the menu links HTML
for ($i = 0; $i < count($arrPR); $i++) {
$strHref = "/";
foreach ($arrUrlPart as $intKey => $strUrlPart) {
if (substr($strUrlPart, 0, 5) == "page-") $strPageUrlPart = $strUrlPart;
else $strHref.= $strUrlPart . "/";
}
$strHref.= "price-" . ($arrPR[$i]["intFrom"] / 100) . "-" . ($arrPR[$i]["intTo"] / 100) . "/";
if (strlen($strPageUrlPart) > 0) $strHref.= $strPageUrlPart . "/";
$strFrom = "£" . ($arrPR[$i]["intFrom"] / 100);
$strTo = "£" . ($arrPR[$i]["intTo"] / 100);
if ($arrPR[$i]["intProducts"] > 0) {
$strContent.= "<p class=\"menuItem\"><img src=\"/img/menuItemArrow.gif\" /> <a href=\"$strHref\">$strFrom - $strTo</a> (" . $arrPR[$i]["intProducts"] . ")</p>\n";
}
}
}
}
}
// Because this data wasn't cached, we add it to the cache table
$objCache->strUrl = $_SERVER['REQUEST_URI'];
$objCache->strContent = $strContent;
$objCache->add();
}
// If content has been set load the content into a left menu template and return it
// otherwise it means there are no products being displayed, in which case this menu isn't
// required at all.
if (strlen($strContent) > 0) {
$strHTML = funcFile::read(TMPL_ROOT . "leftMenu.tmpl");
$strHTML = str_replace("<#strTitle>", "Browse by price", $strHTML);
$strHTML = str_replace("<#strContent>", $strContent, $strHTML);
return $strHTML;
}
}