Forum

Thread tagged as: Question, Shop

Filtering products by brand

I am probably going about this all wrong, but...

Here is what I am trying to achieve: My "shop.php" uses an if statement to show a list of brand names; selecting one makes the else statement true, which in turn generates shop.php?brand=example (using the slug for brand), showing an introduction to the brand. What I want beneath that, is a list of all that particular brand's products.

<?php
  $brand = $_GET['brand'];
  if ($brand=="") perch_shop_brands();
  else            perch_shop_brand(perch_get('brand'));
?>

The code above works perfectly.

Where I am stuck is the next stage, filtering for perch_shop_products... I cannot seem to find the correct filter/match/value. I think I need something like this (which works perfectly on a different site, but using perch_content_custom instead of perch_shop):

<?php
  $brand = $_GET['brand'];
  if (perch_get('brand')) { echo perch_shop_products([
    'filter'   => 'slug',
    'match'    => 'eq',
    'value'    => $_GET['brand'],
    ]);
  }
?>

However, I cannot figure out how to filter the products for this application (what I am showing above obviously does not work). Is there some way of doing this?

(Using Perch 2.8.29, not Runway)

Jonathan Wilson

Jonathan Wilson 0 points

  • 5 years ago

I guess you have to skip the 'echo' in front of the perch_shop_products call.
And I seem to remember perch_get('brand') only works, if your page is processed by perch (like with perch_layout for instance). Otherwise just stick to $_GET['brand'].

perch_get('brand') and $_GET['brand'] both work (it also works with or without 'echo', which makes it redundant).

If I omit filter/match/value and have just this:

<?php
  $brand = $_GET['brand'];
  if (perch_get('brand')) perch_shop_products();
?>

or:

<?php
  $brand = $_GET['brand'];
  if ($_GET['brand']) perch_shop_products();
?>

both work exactly how I want - except that it returns all the products (obviously, as there is no filtering in place), and not just the products associated with the selected brand, so I seem to be almost there...

Trying to pull a slug from the drop-down menu created by Perch's shop/products/product.html template only produces a numeral. I think my problem is that I have no useful 'value' available from Perch's standard product template (or if there is, I do not know how to obtain it).

Drew McLellan

Drew McLellan 2638 points
Perch Support

This was a bug that we've addressed for Shop 1.0.3, which will be the next release.

Aha, thanks Drew.

Sorry to drag this up again, but I still cannot make it work... I took it from Drew's reply that Shop 1.0.4 should have resolved the bug - or have I misunderstood?

Drew McLellan

Drew McLellan 2638 points
Perch Support

What problem are you having?

Very basically, all I want is to be able to sort products based on their brand. For example; shop.php?brand=adaptogens should display a list of all Adaptogens products, and so-on.

When a product is added to the shop, it can be associated with a brand via a drop-down list of all the brands created - but I cannot seem to figure out how to use that to filter the results. As soon as I add filter/match/value to an array for perch_shop_products() I get nothing, yet no array happily loads every single product.

This produces all products:

<?php
  $brand = $_GET['brand'];
  if (perch_get('brand')) perch_shop_products();
?>

Whereas this (or any variation of it), produces nothing:

<?php
  $brand = $_GET['brand'];
  if (perch_get('brand')) perch_shop_products([
    'filter' => 'brand',
    'match'  => 'eq',
    'value'  => $_GET['brand'],
  ]);
?>

I am at a loss as to what to try next...

Rachel Andrew

Rachel Andrew 394 points
Perch Support

The first step would be to turn on Perch Debug to see what queries are being run.

If the filter is not running then the second step would be to hardcode the filter into your call to the function, to see if the issue is that the brand is not being passed.

Ok, so using the example above, here is the debug massage generated by that particular chunk of php with the filter in place:

[3] SELECT DISTINCT idx.itemID FROM perch2_shop_index idx JOIN perch2_shop_products main ON idx.itemID=main.productID AND idx.itemKey='productID' AND ((idx.indexKey='status' AND idx.indexValue='1')) GROUP BY idx.itemID HAVING COUNT(idx.itemID)=1
[3] SELECT DISTINCT idx.itemID FROM perch2_shop_index idx JOIN perch2_shop_products main ON idx.itemID=main.productID AND idx.itemKey='productID' AND ((idx.indexKey='parentID' AND idx.indexValue='')) GROUP BY idx.itemID HAVING COUNT(idx.itemID)=1
[nil] SELECT tbl.* FROM ( SELECT idx.itemID, main.*, idx2.indexValue as sortval FROM perch2_shop_index idx JOIN perch2_shop_products main ON idx.itemID=main.productID AND idx.itemKey='productID' JOIN perch2_shop_index idx2 ON idx.itemID=idx2.itemID AND idx.itemKey='productID' AND idx2.indexKey='title' AND idx.itemID IN ('1', '2', '3') AND idx.itemID IN ('1', '2', '3') WHERE 1=1 AND ((idx.indexKey='brand' AND idx.indexValue='adaptogens-nz-ltd')) AND idx.itemID=idx2.itemID AND idx.itemKey=idx2.itemKey GROUP BY idx.itemID, idx2.indexValue, productID ) as tbl WHERE (productDeleted IS NULL) GROUP BY itemID, sortval ORDER BY sortval ASC
Using template: /templates/shop/../shop/products/hbl_product_list.html

Or do you need to see the entire debug message? Everything else that is happening before this point is working perfectly.

Drew McLellan

Drew McLellan 2638 points
Perch Support

Can you try resaving a product or two?

I re-saved two products and deleted & re-entered a third; but still the same nil result.

(removing the filter still happily produces all products, regardless of the chosen brand)

Drew McLellan

Drew McLellan 2638 points
Perch Support

Change:

'filter' => 'brand',

to

'filter' => 'brand.slug',

Brilliant - that fixed it! Thanks a million :o)