Jump to content

Creating a page to show all Online Only products


Recommended Posts



I'm looking to create a page that shows all products that are marked as 'Online Only'. I thought I might be able to clone and adapt the PricesDrop controller but have not had much luck. Does anyone have any ideas as to how I can do this?


Edit: I'm using





Edited by martbean (see edit history)
Link to comment
Share on other sites



Yeah, that'd work, but maybe I should explain what I'm trying to do. We need certain products to show an icon over the image and for them to be available to view in one place (as well as in their usual categories). I figured the simplest approach would be to repurpose the Online Only flag as it's a simple tick for the admins and it's easy to identify the products when outputting them.


However, it'd be better if admins don't have to remember to add each product to the Online Only category *and* tick the box. I'm happy to just use categories and I tried that route originally but couldn't work out how to identify the products.


So, is there a way of telling if a product belongs to a certain category? It'd need to work even when viewing a different category that also contains the product.





Link to comment
Share on other sites

  • 4 weeks later...

I've finally got back on to this and got it working so thought I'd share in case anyone needs to do the same in the future. I'm writing this from memory so hopefully it's accurate:


(Note: I'm new to Prestashop so please let me know if I've done anything massively wrong!)

  1. Make a copy of /controllers/front/PricesDropController.php and name it OnlineOnlyController.php
  2. Change the class name to OnlineOnlyControllerCore, edit $php_self and the template name.
  3. Make a copy of prices-drop.tpl with the same name entered above.
  4. In the Back Office, go to Preferences > SEO & URLS and add a new page. "onlineonly" should be in the Page dropdown so select it and enter the Rewritten URL (eg. "online-only")
  5. Save the page then clear the cache!
  6. The new page should be accessible from /online-only but currently showing specials.
  7. Create an override Product class and add a new method called something like getOnlineOnlyProducts. I just adapted getPricesDrop (code below)
  8. Change the new controller to call the getOnlineOnlyProducts method and that should be it.
class Product extends ProductCore
	public static function getOnlineOnlyProducts($id_lang, $page_number = 0, $nb_products = 10, $count = false, $order_by = null, $order_way = null, Context $context = null, $random = false)
		if (!$context)
			$context = Context::getContext();

		$front = true;
		if (!in_array($context->controller->controller_type, array('front', 'modulefront')))
			$front = false;

		if ($page_number < 0) $page_number = 0;
		if ($nb_products < 1) $nb_products = 10;
		if (empty($order_by) || $order_by == 'position') $order_by = 'date_add';
		if (empty($order_way)) $order_way = 'DESC';
		if ($order_by == 'id_product' || $order_by == 'price' || $order_by == 'date_add' || $order_by == 'date_upd')
			$order_by_prefix = 'p';
		elseif ($order_by == 'name')
			$order_by_prefix = 'pl';
		if (!Validate::isOrderBy($order_by) || !Validate::isOrderWay($order_way))

		$sql_groups = '';
		if (Group::isFeatureActive())
			$groups = FrontController::getCurrentCustomerGroups();
			$sql_groups = 'AND p.`id_product` IN (
				SELECT cp.`id_product`
				FROM `'._DB_PREFIX_.'category_group` cg
				LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_category` = cg.`id_category`)
				WHERE cg.`id_group` '.(count($groups) ? 'IN ('.implode(',', $groups).')' : '= 1').'

		if (strpos($order_by, '.') > 0)
			$order_by = explode('.', $order_by);
			$order_by_prefix = $order_by[0];
			$order_by = $order_by[1];

		if ($count)
			$sql = 'SELECT COUNT(p.`id_product`) AS nb
					FROM `'._DB_PREFIX_.'product` p
					'.Shop::addSqlAssociation('product', 'p').'
					WHERE product_shop.`active` = 1
					AND product_shop.`online_only` = 1
					'.($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : '').'
			return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);

		$sql = new DbQuery();
			'p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`,
			pl.`meta_keywords`, pl.`meta_title`, pl.`name`, pl.`available_now`, pl.`available_later`, MAX(image_shop.`id_image`) id_image, il.`legend`, m.`name` AS manufacturer_name,
			product_shop.`date_add` > "'.date('Y-m-d', strtotime('-'.(Configuration::get('PS_NB_DAYS_NEW_PRODUCT') ? (int)Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY')).'" as new'.(Combination::isFeatureActive() ? ', MAX(product_attribute_shop.minimal_quantity) AS product_attribute_minimal_quantity' : '')

		$sql->from('product', 'p');
		$sql->join(Shop::addSqlAssociation('product', 'p'));
		$sql->leftJoin('product_lang', 'pl', '
			p.`id_product` = pl.`id_product`
			AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl')
		$sql->leftJoin('image', 'i', 'i.`id_product` = p.`id_product`');
		$sql->join(Shop::addSqlAssociation('image', 'i', false, 'image_shop.cover=1'));
		$sql->leftJoin('image_lang', 'il', 'i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang);
		$sql->leftJoin('manufacturer', 'm', 'm.`id_manufacturer` = p.`id_manufacturer`');

		$sql->where('product_shop.`active` = 1');
		if ($front)
			$sql->where('product_shop.`visibility` IN ("both", "catalog")');
		$sql->where('product_shop.`online_only` = 1');
		if (Group::isFeatureActive())
			$sql->join('JOIN '._DB_PREFIX_.'category_product cp ON (cp.id_product = p.id_product)');
			$sql->join('JOIN '._DB_PREFIX_.'category_group cg ON (cg.id_category = cp.id_category)');
			$sql->where('cg.`id_group` '.(count($groups) ? 'IN ('.implode(',', $groups).')' : '= 1'));

		if ($random) {
		} else {
			$sql->orderBy((isset($order_by_prefix) ? pSQL($order_by_prefix).'.' : '').'`'.pSQL($order_by).'` '.pSQL($order_way));
		$sql->limit($nb_products, $page_number * $nb_products);

		if (Combination::isFeatureActive())
			$sql->select('MAX(product_attribute_shop.id_product_attribute) id_product_attribute');
			$sql->leftOuterJoin('product_attribute', 'pa', 'p.`id_product` = pa.`id_product`');
			$sql->join(Shop::addSqlAssociation('product_attribute', 'pa', false, 'product_attribute_shop.default_on = 1'));
		$sql->join(Product::sqlStock('p', Combination::isFeatureActive() ? 'product_attribute_shop' : 0));

		$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);

		if ($order_by == 'price')
			Tools::orderbyPrice($result, $order_way);
		if (!$result)
			return false;

		$products_ids = array();
		foreach ($result as $row)
			$products_ids[] = $row['id_product'];
		// Thus you can avoid one query per product, because there will be only one query for all the products of the cart
		Product::cacheFrontFeatures($products_ids, $id_lang);
		return Product::getProductsProperties((int)$id_lang, $result);



  • Like 1
Link to comment
Share on other sites

  • 3 months later...
  • 5 years later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...