ECommerce item search

Okay, it’s not blogging, but it took me forever to track down how to do this, so I figured I’d post it for others to use.

The setting: An ecommerce site.

The need: Searching for items in the inventory, but returning the same result whether the search terms are singular or plural, without messing up an exact phrase.

The solution: create two sets of keywords, singular and plural and search both literal and for the individual words via a regular expression.

I’m sure there are more efficient ways of doing this, but I couldn’t find any, and this is what I cam up with.

//$get_search is the search keyword(s) submitted via a

//  GET and filtered to block any hacking attempts

// $catSort is the sort criteria 'relevance',

//    'price:lo to hi', 'price:ho to lo', etc.

  $catSort=$_GET['catSort'];

  if(!$catSort){$catSort='relevance'; $order=' ORDER BY `rel` DESC';}

  $itemsPerPage=$_GET['itemsPerPage'];

  if(!$itemsPerPage){$itemsPerPage='20';}

  if($catSort=='l2h'){$order=' ORDER BY `price` ASC';}

  if($catSort=='h2l'){$order=' ORDER BY `price` DESC';}

  if($catSort=='item'){$order=' ORDER BY `productname`';}

//clean up the keyword some

  $get_search=rtrim(ltrim(urldecode($get_search

//  this array helps converts the key word (or last keyword in a phrase) to the plural form

$plural_rules = array(

'/(x|ch|ss|sh)$/' => '\1es',            # search, switch, fix, box, process, address

'/series$/' => '\1series',              #series is the same

'/([^aeiouy]|qu)y$/' => '\1ies',        # query, ability, agency

'/(?:([^f])fe|([lr])f)$/' => '\1\2ves', # half, safe, wife

'/sis$/' => 'ses',                      # basis, diagnosis

'/ex$/' => 'ices',                      # index

'/([ti])um$/' => '\1a',                 # datum, medium

'/person$/' => 'people',                # person, salesperson

'/man$/' => 'men',                      # man, woman, spokesman

'/foot$/' => 'feet',

'/louse$/' => 'lice',

'/mouse$/' => 'mice',

'/tooth$/' => 'teeth',

'/child$/' => 'children',

'/([nti])on$/' => 'a',                  # criterion

'/(.*)status$/' => '\1statuses',

'/s$/' => 's',                          # no change (compatibility)

'/$/' => 's'                            # everything else

);

//  this array helps converts the key word (or last keyword in a phrase) to the singular form

$singular_rules = array(

'/(xes|ches|sses|shes)$/e' =>           # the /e allows an executable phrase within the replacement

    "str_replace('es','',$1)",          # boxes, classes

'/series$/' => 'series',

'/([^aeiouy]|qu)ies$/' => '\1y',

'/([lr])ves$/' => '\1\2f',              # halves, scarves

'/([^f])ves$/' => '\1fe',               # wives

'/ses$/' => 'sis',                      # bases, diagnoses

'/ices$/' => 'ex',                      # indices

'/([ti])a$/' => '\1um',                 # data, media

'/people$/' => 'person',                # people, salespeople

'/men$/' => 'man',                      # men, women, spokesmen

'/feet$/' => 'foot',

'/lice$/' => 'louse',

'/mice$/' => 'louse',

'/teeth$/' => 'tooth',

'/children$/' => 'child',

'/([nti])a$/' => 'on',                  # criteria

'/(.*)statuses$/' => '\1status',

'/[aious]s$/' => '',                    # no change (compatibility)

'/s$/' => ''                            # everything else that ends in an 's'

);

$string=$get_search;

$match=false;

foreach($plural_rules as $pattern => $replacement)

  {

  if(!$match and preg_match($pattern, $string))

    {

    $out=preg_replace($pattern, $replacement, $string);

    $match=true;

    }

  }

if($out and $out!=$get_search){$plural=$out;}

else{$plural=$get_search;}

$match=false;$out='';

foreach($singular_rules as $pattern => $replacement)

  {

  if(!$match and preg_match($pattern, $string))

    {

    $out=preg_replace($pattern, $replacement, $string);

    $match=true;

    }

  }

if($out and $out!=$get_search){$singular=$out;}

else{$singular=$get_search;}

}

// the regexp will crash if we send it an empty

//   variable. So we do this

if(!$get_search){$get_search='[[[]]]';}

//I typical throw in a capital letter to distinguish

//  arrays from variables

$get_Search=explode(' ',$get_search);

//Yes, I know there's an easier way to weed out repeated

//   spaces, but I was in a hurry

$Temp='';

foreach($get_Search as $el)

  {

  if($el){$Temp[]=$el;}

  }

$get_Search=$Temp;

//we include all the keywords for the regexp part

$regexp=implode('|',$get_Search);

//these cell names are samples

// the first part (with all the IFs) allows us to create a

Page 1 of 2 | Next page