Skip to content

Commit

Permalink
A more efficient means of selecting the random featured product
Browse files Browse the repository at this point in the history
Works by selecting all product IDs that are featured and then choosing randomly from within that result set, completely removing recursive calls yet getting a valid result on the first try every time in most cases.

Since only the product IDs are fetched, memory overhead should be minimal even in the unlikely scenario that a store has thousands of featured products.

Efficiency could be optimized even further with an index on the `featured` column.
  • Loading branch information
briansandall committed Sep 16, 2016
1 parent 3d78c95 commit 3c4a7dc
Showing 1 changed file with 54 additions and 56 deletions.
110 changes: 54 additions & 56 deletions classes/gui.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -1093,77 +1093,75 @@ private function _displayPopularProducts() {
}

/**
* Display random products box
* Display featured products box
*/
private function _displayRandomProduct($p=0) {
private function _displayRandomProduct() {

if(!$GLOBALS['smarty']->templateExists('templates/box.featured.php')) return false;

foreach ($GLOBALS['hooks']->load('class.gui.display_random_product_pre') as $hook) include $hook;

$where = $GLOBALS['catalogue']->outOfStockWhere(array('status' => '1', 'featured' => '1'));
// SQL below used to replace RAND which is a monster on resources over 100 products
$query = 'SELECT * FROM `'.$GLOBALS['config']->get('config', 'dbprefix').'CubeCart_inventory` JOIN (SELECT CEIL(RAND() * (SELECT MAX(`product_id`) FROM `'.$GLOBALS['config']->get('config', 'dbprefix').'CubeCart_inventory`)) AS `product_id`) AS `r` USING (`product_id`) WHERE '.$where;
$random_product = $GLOBALS['db']->misc($query, false);

if ($random_product) {

$category_data = $GLOBALS['catalogue']->getCategoryStatusByProductID($random_product[0]['product_id']);
$category_status = false;
if (is_array($category_data)) {
foreach ($category_data as $trash => $data) {
if ($data['status'] == 1 && $data['primary'] == 1) {
$category_status = true;
$query = 'SELECT `product_id` FROM `'.$GLOBALS['config']->get('config', 'dbprefix').'CubeCart_inventory` WHERE '.$where;
$featured_products = $GLOBALS['db']->misc($query, false);
$n = ($featured_products ? count($featured_products) : 0);
if ($n > 0) {
$random_product = false;
$tries = 0;
while (!$random_product && $tries < 15) {
$random_id = $featured_products[mt_rand(0, $n - 1)]['product_id'];
$category_data = $GLOBALS['catalogue']->getCategoryStatusByProductID($random_id);
$category_status = false;
if (is_array($category_data)) {
foreach ($category_data as $trash => $data) {
if ($data['status'] == 1 && $data['primary'] == 1) {
$category_status = true;
break;
}
}
}
}
if (!$category_status) {
if ($p<15) {
$p++;
$this->_displayRandomProduct($p);
if ($category_status) {
$random_product = $GLOBALS['db']->select('CubeCart_inventory', false, array('product_id' => $random_id), false, 1);
}
} else {
++$tries;
}
}

$image = $this->getProductImage($random_product[0]['product_id']);
$product = $random_product[0];

$GLOBALS['language']->translateProduct($product);

$product['image'] = $image;

$product['ctrl_sale'] = (!$GLOBALS['tax']->salePrice($product['price'], $product['sale_price']) || !$GLOBALS['config']->get('config', 'catalogue_sale_mode')) ? false : true;


$GLOBALS['catalogue']->getProductPrice($product);
$sale = $GLOBALS['tax']->salePrice($product['price'], $product['sale_price']);
$product['price_unformatted'] = $product['price'];
$product['sale_price_unformatted'] = ($sale) ? $product['sale_price'] : null;
$product['price'] = $GLOBALS['tax']->priceFormat($product['price']);
$product['sale_price'] = ($sale) ? $GLOBALS['tax']->priceFormat($product['sale_price']) : null;

$product['ctrl_purchase'] = true;
if ($product['use_stock_level']) {
// Get Stock Level
$stock_level = $GLOBALS['catalogue']->getProductStock($product['product_id']);
if ((int)$stock_level <= 0) {
// Out of Stock
if (!$GLOBALS['config']->get('config', 'basket_out_of_stock_purchase')) {
// Not Allowed
$product['ctrl_purchase'] = false;
}
if ($random_product) {
$image = $this->getProductImage($random_product[0]['product_id']);
$product = $random_product[0];

$GLOBALS['language']->translateProduct($product);

$product['image'] = $image;

$product['ctrl_sale'] = (!$GLOBALS['tax']->salePrice($product['price'], $product['sale_price']) || !$GLOBALS['config']->get('config', 'catalogue_sale_mode')) ? false : true;

$GLOBALS['catalogue']->getProductPrice($product);
$sale = $GLOBALS['tax']->salePrice($product['price'], $product['sale_price']);
$product['price_unformatted'] = $product['price'];
$product['sale_price_unformatted'] = ($sale) ? $product['sale_price'] : null;
$product['price'] = $GLOBALS['tax']->priceFormat($product['price']);
$product['sale_price'] = ($sale) ? $GLOBALS['tax']->priceFormat($product['sale_price']) : null;

$product['ctrl_purchase'] = true;
if ($product['use_stock_level']) {
// Get Stock Level
$stock_level = $GLOBALS['catalogue']->getProductStock($product['product_id']);
if ((int)$stock_level <= 0) {
// Out of Stock
if (!$GLOBALS['config']->get('config', 'basket_out_of_stock_purchase')) {
// Not Allowed
$product['ctrl_purchase'] = false;
}
}
$product['url'] = $GLOBALS['seo']->buildURL('prod', $product['product_id']);
foreach ($GLOBALS['hooks']->load('class.gui.display_random_product') as $hook) include $hook;
$GLOBALS['smarty']->assign('featured', $product);
$content = $GLOBALS['smarty']->fetch('templates/box.featured.php');
$GLOBALS['smarty']->assign('RANDOM_PROD', $content);
}
} elseif ($p<20) { // Math to generate random product might give a product_id that doesn't exist or doen't meet WHERE criteria
$p++;
$this->_displayRandomProduct($p);
$product['url'] = $GLOBALS['seo']->buildURL('prod', $product['product_id']);
foreach ($GLOBALS['hooks']->load('class.gui.display_random_product') as $hook) include $hook;
$GLOBALS['smarty']->assign('featured', $product);
$content = $GLOBALS['smarty']->fetch('templates/box.featured.php');
$GLOBALS['smarty']->assign('RANDOM_PROD', $content);
}
if($random_product) return $product;
}

/**
Expand Down

0 comments on commit 3c4a7dc

Please sign in to comment.