You are here:  » Search functionality across multiple fields


Search functionality across multiple fields

Submitted by lafirt on Fri, 2012-08-10 20:33 in

Hi David
Many thanks for your support. I thought I would put this set of queries on a post as well as email in case others may find it of use. As you know in terms of current state, I have a blog in WP, and have the script and the WP plugin installed.

I am planning on adding a few custom fields to the DB, the custom fields will be populated with information on the feed file before they are uploaded (i.e. I will be amending the data feed and re-saving in csv format prior to upload).

For example, to a feed from a jewelry retailer, I plan to add fields that identify the type of jewelry (ring, bracelet, necklace...), material (gold, silver, platinum..), the stone (diamond, sapphire, topaz, etc). The feed already contains the title and description from the retailer as well.

I would like to do 2 things:

1. Create a series of pages that contain specific sets of results. For example, a page listing Men's diamond gold rings would display all the items in the DB that meet the following criteria:
Type = ring, Material = gold, stone = diamond, title - contains "men"

2. Have a single page in which the user can define criteria, based on the above custom fields and other existing fields (such as price)

I am currently unsure as to how to implement as the search seems to work based solely on the title or description fields? Could you help?

Thanks
Lafir

Submitted by support on Sun, 2012-08-12 13:17

Hello Lafir,

The first stage involves duplicate the existing filter code to include filters for your custom fields. Using categoryFilter as a template, you'll find the relevant code as follows:

pto.php

Line 306:

  array_push($vars, 'pto_categoryFilter');

pto_search.php

Line 52:

  global $pto_categoryFilter;

Line 117;

  $pto_categoryFilter = (isset($pto_categoryFilter)?$pto_categoryFilter:"");

Line 146:

  if ($pto_categoryFilter)
  {
    $priceWhere .= " AND category = '".$wpdb->escape($pto_categoryFilter)."' ";
  }

Line 367:

  global $pto_categoryFilter;

Line 385:

  if ($pto_categoryFilter) $sortBaseHREF .= "&pto_categoryFilter=".urlencode($pto_categoryFilter);

Line 557:

  global $pto_categoryFilter;

Line 602:

      if ($pto_categoryFilter) $navigationBaseHREF .= "&pto_categoryFilter=".urlencode($pto_categoryFilter);

For each section of code; duplicate for any custom fields that you wish to add filters for, replacing "category" throughout with the exact name of the custom field. So for example, in the first instance above and for your custom field "type" you would add the line

  array_push($vars, 'pto_typeFilter');

Type = ring, Material = gold, stone = diamond

With the new filters in place; you can then link to search results for the required criteria by linking to the required query e.."mens" together with the required filter values; e.g.

/shopping?pto_q=mens&pto_typeFilter=ring&pto_materialFilter=gold&pto_stoneFilter=diamond

Rather than overloading a single reply with too much information; let me know when you have the above in place and we can extend the modification to;

1) use filters within a search shortcode so that you don't need to link to the above verbose URL

2) create an "advanced search form" for the filters

Cheers,
David.
--
PriceTapestry.com

Submitted by lafirt on Tue, 2012-08-14 12:06

Hi David
Thanks for the quick response - Checked with my developer - the above looks good - could you provide the answer to point 2 (in terms of the advanced search form) as well please?

cheers
Lafir

Submitted by support on Wed, 2012-08-15 16:14

Hello Lafir,

Here's a nice generic solution to add filters for any specified fields to the main search form. They will pre-select to the filtered value (if applicable) on search results page.

In pto_search.php, look for the following code at line 33 within the pto_search_form() function:

  return $html;

...and REPLACE with:

  global $wpdb;
  global $pto_searchWhere;
  global $pto_config_databaseTablePrefix;
  $filterHTML = "";
  if ((!isset($pto_searchWhere)) || ($pto_searchWhere=="")) $pto_searchWhere = "1";
  $showFilters = array("Merchant"=>"merchant","Category"=>"category");
  foreach($showFilters as $title => $field)
  {
    $sql = "SELECT DISTINCT(".$field.") FROM `".$pto_config_databaseTablePrefix."products` WHERE ".$pto_searchWhere." AND ".$field." <> '' ORDER BY ".$field;
    if ($numRows = $wpdb->query($sql))
    {
      $filterHTML .= $title.": <select name='pto_".$field."Filter'><option value=''>All</option>";
      for($i=0;$i<$numRows;$i++)
      {
        $product = $wpdb->last_result[$i];
        $filterHTML .= "<option ".($GLOBALS["pto_".$field."Filter"]==$product->$field?"selected='selected'":"")." value='".htmlentities($product->$field,ENT_QUOTES,get_settings("blog_charset"))."'>".$product->$field."</option>";
      }
      $filterHTML .= "</select> ";
    }
  }
  $html = str_replace("</form>",$filterHTML."</form>",$html);
  return $html;

Within the replacement, this line:

$showFilters = array("Merchant"=>"merchant","Category"=>"category");

...can be modified as required for the filters you wish to display.

To insert the filter HTML, this code performs an str_replace() on the closing form tag </form> within the search form template (wp-admin > Settings > PriceTapestry.org) so you may wish to slightly re-arrange this so that the "Search or browse by ..." links appear outside of the form.

Hope this helps!

Cheers,
David.
--
PriceTapestry.com