You are here:  » Extending search function and related products feature

Support Forum



Extending search function and related products feature

Submitted by jim on Sun, 2009-02-15 09:27 in

Hi David,
If you have a moment, I have a couple of PT questions:

1/
Is it possible to extend the search function so that if there are merchants or brands (or extra indexed fields we may have added) that match the search term (or come close to matching) you get a link at the top (before your product search results),

saying something like for a search for 'widget':

we found two merchants exactly matching your search:
'red widget store'
'blue widget store'
and one that closely matches:
'widdget store'
we found one brand matching your search:
'widget jeans'

and then followed by our usual product search results listings
'red widget store' above would be a link to display all products sold by that store (ie. merchant:red widget store:)

2/
For the related products feature, is it possible to show 3 products from the same merchant and 3 products from the same brand, as the main product being viewed?
(again I would be looking to use this for my extra indexed fields, rather than just merchant and brand)

Thanks for your help!

Submitted by support on Mon, 2009-02-16 02:17

Hi Jim,

Code wise, (1) is straight forward, but you need to watch performance - however as it only involves queries against indexed fields this shouldn't be a problem. As there may be indexed field search results even with no product search results this code needs to go outside of html/searchresults.php, so I would suggest inserting directly into search.php immediately after the following code on line 183:

  require("html/banner.php");

Try this code for starters:

  $indexedFields = array("merchant","category","brand");
  foreach($indexedFields as $field)
  {
    for($i=1;$i<=2;$i++)
    {
      if ($i==1) $sql = "SELECT DISTINCT(".$field.") FROM `".$config_databaseTablePrefix."products` WHERE ".$field."='".database_safe($q)."'";
      if ($i==2) $sql = "SELECT DISTINCT(".$field.") FROM `".$config_databaseTablePrefix."products` WHERE ".$field." LIKE '%".database_safe($q)."%' AND ".$field." <> '".database_safe($q)."'";
      if (database_querySelect($sql,$products))
      {
        if ($i==1) print "<p>We found ".count($products)." ".$field.(count($products)>1?"s":"")." exactly matching your search:</p>";
        if ($i==2) print "<p>We found ".count($products)." ".$field.(count($products)>1?"s":"")." closely matching your search:</p>";
        print "<ul>";
        foreach($products as $product)
        {
          print "<li><a href='".$config_baseHREF."search.php?q=".$field.":".$product[$field]."'>".$product[$field]."</a></li>";
        }
        print "</ul>";
      }
    }
  }

Simply modify the list of fields in $indexedFields to change the fields searched.

Re (2), use the following code to replace the existing Featured Products section of products.php, that is everything between and including lines 62:

if ($config_useRelated || (!isset($product)))

...and 99:

}

Here's the code:

  $indexedFields = array("merchant","category","brand");
  $searchresults = array();
  foreach($indexedFields as $field)
  {
    if ($product["products"][0][$field])
    {
      $sql = "SELECT * FROM `".$config_databaseTablePrefix."products` WHERE ".$field."='".database_safe($product["products"][0][$field])."' AND name <> '".database_safe($product["products"][0]["name"])."' LIMIT 3";
      if (database_querySelect($sql,$rows))
      {
        $searchresults["products"] = array_merge($searchresults["products"],$rows);
        $searchresults["numRows"] += count($rows);
      }
    }
  }
  if ($searchresults["numRows"])
  {
    foreach($searchresults["products"] as $k => $related)
    {
      if ($config_useRewrite)
      {
        $searchresults["products"][$k]["productHREF"] = "product/".tapestry_hyphenate($related["name"]).".html";
        if ($rewrite) $searchresults["products"][$k]["productHREF"] = "../".$searchresults["products"][$k]["productHREF"];
      }
      else
      {
        $searchresults["products"][$k]["productHREF"] = "products.php?q=".urlencode($related["name"]);
      }
    }
    $related = true;
  }

As before, modify the $indexedFields array as required and the above code will (as it stands) pick 3 products from each indexed field matching the current product...

Hope this helps!

Cheers,
David.

Submitted by jim on Wed, 2009-02-18 06:01

Excellent - works a treat!

I had to make a change in (1) as I use Rewrite for my search.
ie. my URLs are like:
example.com/search/merchant/widgets/

I got it working by messing around with the code, but it may be useful to others (as I'm sure lots are using the rewrite for cleaner URLs)

was:

print "<li><a href='".$config_baseHREF."search.php?q=".$field.":".$product[$field]."'>".$product[$field]."</a></li>";

changed to:

      if ($config_useRewrite)
      {
        print "<li><a href='".$config_baseHREF.$field."/".tapestry_hyphenate($product[$field])."/'>".$product[$field]."</a></li>";
      }
      else
      {
      print "<li><a href='".$config_baseHREF."search.php?q=".$field.":".$product[$field]."'>".$product[$field]."</a></li>";
      }

Is this the best way to code it? I kind of guessed it ..

Submitted by support on Wed, 2009-02-18 08:54

Hi Jim,

That looks fine!

Cheers,
David.