advanced search by type ahead

Open to all! Ask other shopowners for help.
User avatar
burt
Core Team
Posts: 4551
Joined: Tue Oct 29, 2019 9:37 am
Phoenix Version: v1.1.0.8
Has thanked: 252 times
Been thanked: 412 times

Re: advanced search by type ahead

Post by burt »

It should be do-able. If you can get some other shopowners interested enough I can take a day out to recode and maybe simplify it a bit. That's a lot of beer.

I now leave logistics in the hands of a "captain" shopowner to sort out, as I've just gone ahead so many times (recode things or fix things or make things) based on what shopowner(s) say they want/need, then when it's done and time to buy a beer in return...pufffff...they disappear in a cloud of smoke, just to pop up again after 6 months to ask for something else. Utterly soul destroying.
I am not here to build for you.
I am here to build with you. Let's help each other.


Join The Code Co-op to get access to your library in the Code Co-op Forum
BatteryTrader
Contributor
Posts: 153
Joined: Thu Apr 11, 2024 7:18 am
Phoenix Version: 1.1.0.3
Has thanked: 3 times
Been thanked: 17 times

Re: advanced search by type ahead

Post by BatteryTrader »

I use a old version of Typeahead on my site, I have the best part of 20K product pages and its the only realistic way of doing the Job

In the drop down its search only for keywords in seo title and seo keywords, so trimmed for speed.

If its not allowed to drop down and clicked before it happens then it reverts to normal search which takes a lot longer.

On my advanced search page if there is no results then it also uses a old addon called sitesearch, using which can send a email to us with the term they are looking for

Also odyms, which I cant remember what that does, and Fuzzy search, in all the search works well

I have included here my advanced search page

Code: Select all

<?php
/*
  $Id$

  osCommerce, Open Source E-Commerce Solutions
  http://www.oscommerce.com

  Copyright (c) 2018 osCommerce

  Released under the GNU General Public License
*/

  require('includes/application_top.php');

  require('includes/languages/' . $language . '/advanced_search.php');
  
    /************** BEGIN SITESEARCH CHANGE ****************/
  if (isset($_POST['request_submit'])) {
      $keywords = tep_db_prepare_input(strip_tags($_POST['keywords']));
      $keywords = preg_replace('/[^a-z0-9 ]/i', '', $keywords);
      $emailBody = sprintf(NO_PRODUCT_EMAIL_TEXT_BODY, tep_db_prepare_input($_POST['cust_name']), $keywords, tep_db_prepare_input($_POST['comments']));
      $emailSubject = sprintf(NO_PRODUCT_EMAIL_TEXT_SUBJECT, $keywords);
      tep_mail('', STORE_OWNER_EMAIL_ADDRESS, $emailSubject, $emailBody, '', $_POST['cust_email']);
      tep_redirect(tep_href_link('contact_us.php?action=success'));
  }
  /************** END SITESEARCH CHANGE ****************/
$_GET['search_in_description'] = 1;
  $error = false;

  if ( (isset($_GET['keywords']) && empty($_GET['keywords'])) &&
       (isset($_GET['dfrom']) && (empty($_GET['dfrom']) || ($_GET['dfrom'] == DOB_FORMAT_STRING))) &&
       (isset($_GET['dto']) && (empty($_GET['dto']) || ($_GET['dto'] == DOB_FORMAT_STRING))) &&
       (isset($_GET['pfrom']) && !is_numeric($_GET['pfrom'])) &&
       (isset($_GET['pto']) && !is_numeric($_GET['pto'])) ) {
    $error = true;

    $messageStack->add_session('search', ERROR_AT_LEAST_ONE_INPUT);
  } else {
    $dfrom = '';
    $dto = '';
    $pfrom = '';
    $pto = '';
    $keywords = '';

    if (isset($_GET['dfrom'])) {
      $dfrom = (($_GET['dfrom'] == DOB_FORMAT_STRING) ? '' : $_GET['dfrom']);
    }

    if (isset($_GET['dto'])) {
      $dto = (($_GET['dto'] == DOB_FORMAT_STRING) ? '' : $_GET['dto']);
    }

    if (isset($_GET['pfrom'])) {
      $pfrom = $_GET['pfrom'];
    }

    if (isset($_GET['pto'])) {
      $pto = $_GET['pto'];
    }

    if (isset($_GET['keywords'])) {
      $keywords = tep_db_prepare_input($_GET['keywords']);
    }

    $price_check_error = false;
    if (tep_not_null($pfrom)) {
      if (!settype($pfrom, 'double')) {
        $error = true;
        $price_check_error = true;

        $messageStack->add_session('search', ERROR_PRICE_FROM_MUST_BE_NUM);
      }
    }

    if (tep_not_null($pto)) {
      if (!settype($pto, 'double')) {
        $error = true;
        $price_check_error = true;

        $messageStack->add_session('search', ERROR_PRICE_TO_MUST_BE_NUM);
      }
    }

    if (($price_check_error == false) && is_float($pfrom) && is_float($pto)) {
      if ($pfrom >= $pto) {
        $error = true;

        $messageStack->add_session('search', ERROR_PRICE_TO_LESS_THAN_PRICE_FROM);
      }
    }

    if (tep_not_null($keywords)) {
      if (!tep_parse_search_string($keywords, $search_keywords)) {
        $error = true;

        $messageStack->add_session('search', ERROR_INVALID_KEYWORDS);
      }
    }
  }

  if (empty($dfrom) && empty($dto) && empty($pfrom) && empty($pto) && empty($keywords)) {
    $error = true;

    $messageStack->add_session('search', ERROR_AT_LEAST_ONE_INPUT);
  }

  if ($error == true) {
    tep_redirect(tep_href_link('advanced_search.php', tep_get_all_get_params(), 'NONSSL', true, false));
  }
  
    /************** BEGIN SITESEARCH CHANGE ****************/
  require('includes/functions/site_search.php');
  $dir = 'includes/languages/';
  $searchTerm = $keywords;
  
  $articlesList = array();
  $fileList = array();
  $pagesList = array();
  if (tep_not_null($keywords)) //only check for words
  {
    CheckAllPages($dir, $searchTerm, $fileList, $articlesList, $pagesList, $languages_id);
  }   

  /************** END SITESEARCH CHANGE ****************/

  $breadcrumb->add(NAVBAR_TITLE_1, tep_href_link('advanced_search.php'));
  $breadcrumb->add(NAVBAR_TITLE_2, tep_href_link('advanced_search_result.php', tep_get_all_get_params(), 'NONSSL', true, false));

  require('includes/template_top.php');
?>

<?php  /************** BEGIN SITESEARCH CHANGE ****************/ ?>
<script language="JavaScript" type="text/javascript">
<!--
function trim(s)
{
  return s.replace(/^\s+|\s+$/, '');
}

function validateEmail(fld) {
    var error="";
    var tfld = trim(fld.value);                        // value of field with whitespace trimmed off
    var emailFilter = /^[^@]+@[^@.]+\.[^@]*\w\w$/ ;
    var illegalChars= /[\(\)\<\>\,\;\:\\\"\[\]]/ ;

    if (fld.value == "") {
        fld.style.background = 'Yellow';
        error = "Please enter an email address.\n";
    } else if (!emailFilter.test(tfld)) {              //test email for illegal characters
        fld.style.background = 'Yellow';
        error = "Please enter a valid email address.\n";
    } else if (fld.value.match(illegalChars)) {
        fld.style.background = 'Yellow';
        error = "The email address contains illegal characters.\n";
    } else {
        fld.style.background = 'White';
    }
    return error;
}

function checkform ( form )
{
  if (form.keywords.value == "")
  {
     alert("Please enter the product you would like information about.");
     form.keywords.style.background = 'Yellow';
     form.keywords.focus();
     return false ;
  }
  var result = validateEmail(form.cust_email);
  if (result != "") {
     alert(result);
     form.cust_email.focus();
     return false ;
  }
  return true ;
}
//-->
</script>
<?php  /************** END SITESEARCH CHANGE ****************/ ?>

<h1 class="display-4"><?php echo HEADING_TITLE_2; ?></h1>

<div class="contentContainer">

<?php
// create column list
  $define_list = array('PRODUCT_LIST_MODEL' => PRODUCT_LIST_MODEL,
                       'PRODUCT_LIST_NAME' => PRODUCT_LIST_NAME,
                       'PRODUCT_LIST_MANUFACTURER' => PRODUCT_LIST_MANUFACTURER,
                       'PRODUCT_LIST_PRICE' => PRODUCT_LIST_PRICE,
                       'PRODUCT_LIST_QUANTITY' => PRODUCT_LIST_QUANTITY,
                       'PRODUCT_LIST_WEIGHT' => PRODUCT_LIST_WEIGHT,
                       'PRODUCT_LIST_IMAGE' => PRODUCT_LIST_IMAGE,
                       'PRODUCT_LIST_BUY_NOW' => PRODUCT_LIST_BUY_NOW,
                       'PRODUCT_LIST_ID' => PRODUCT_LIST_ID,
                       'PRODUCT_LIST_ORDERED' => PRODUCT_LIST_ORDERED);

  asort($define_list);

  $column_list = array();
  foreach($define_list as $key => $value) {
    if ($value > 0) $column_list[] = $key;
  }

  $select_str = "select distinct p.products_id, m.*, p.*, pd.*, p.products_quantity as in_stock, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price, if(s.status, 1, 0) as is_special ";
  
  
  if ( (DISPLAY_PRICE_WITH_TAX == 'true') && (tep_not_null($pfrom) || tep_not_null($pto)) ) {
    $select_str .= ", SUM(tr.tax_rate) as tax_rate ";
  }

  $from_str = "from products p left join manufacturers m using(manufacturers_id) left join specials s on p.products_id = s.products_id";

  if ( (DISPLAY_PRICE_WITH_TAX == 'true') && (tep_not_null($pfrom) || tep_not_null($pto)) ) {
    if (!tep_session_is_registered('customer_country_id')) {
      $customer_country_id = STORE_COUNTRY;
      $customer_zone_id = STORE_ZONE;
    }
    $from_str .= " left join tax_rates tr on p.products_tax_class_id = tr.tax_class_id left join zones_to_geo_zones gz on tr.tax_zone_id = gz.geo_zone_id and (gz.zone_country_id is null or gz.zone_country_id = '0' or gz.zone_country_id = '" . (int)$customer_country_id . "') and (gz.zone_id is null or gz.zone_id = '0' or gz.zone_id = '" . (int)$customer_zone_id . "')";
  }

  $from_str .= ", products_description pd, categories c, products_to_categories p2c";

  $where_str = " where p.products_status = '1' and p.products_id = pd.products_id and pd.language_id = '" . (int)$languages_id . "' and p.products_id = p2c.products_id and p2c.categories_id = c.categories_id ";

  if (isset($_GET['categories_id']) && tep_not_null($_GET['categories_id'])) {
    if (isset($_GET['inc_subcat']) && ($_GET['inc_subcat'] == '1')) {
      $subcategories_array = array();
      tep_get_subcategories($subcategories_array, $_GET['categories_id']);

      $where_str .= " and p2c.products_id = p.products_id and p2c.products_id = pd.products_id and (p2c.categories_id = '" . (int)$_GET['categories_id'] . "'";

      for ($i=0, $n=sizeof($subcategories_array); $i<$n; $i++ ) {
        $where_str .= " or p2c.categories_id = '" . (int)$subcategories_array[$i] . "'";
      }

      $where_str .= ")";
    } else {
      $where_str .= " and p2c.products_id = p.products_id and p2c.products_id = pd.products_id and pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" . (int)$_GET['categories_id'] . "'";
    }
  }

  if (isset($_GET['manufacturers_id']) && tep_not_null($_GET['manufacturers_id'])) {
    $where_str .= " and m.manufacturers_id = '" . (int)$_GET['manufacturers_id'] . "'";
  }

  if (isset($search_keywords) && (sizeof($search_keywords) > 0)) {
    $where_str .= " and (";
    for ($i=0, $n=sizeof($search_keywords); $i<$n; $i++ ) {
      switch ($search_keywords[$i]) {
        case '(':
        case ')':
        case 'and':
        case 'or':
          $where_str .= " " . $search_keywords[$i] . " ";
          break;
        default:
          //$keyword = tep_db_prepare_input($search_keywords[$i]);
          $keyword = tep_db_prepare_input(preg_replace('/-/', '', $search_keywords[$i]));

        //  $where_str .= "(";
       //   if ( (defined('MODULE_HEADER_TAGS_PRODUCT_META_KEYWORDS_STATUS')) && ('MODULE_HEADER_TAGS_PRODUCT_META_KEYWORDS_STATUS' != 'Meta') ) {
       //     $where_str .= "pd.products_seo_keywords LIKE '%" . tep_db_input($keyword) . "%' OR ";
       //   }
      //    $where_str .= "pd.products_name like '%" . tep_db_input($keyword) . "%' or p.products_model like '%" . tep_db_input($keyword) . "%' or m.manufacturers_name like '%" . tep_db_input($keyword) . "%'";
          $where_str .= "(((pd.products_seo_title like '%" . tep_db_input($keyword) . "%' or pd.products_seo_description like '%" . tep_db_input($keyword) . "%') OR REPLACE (pd.products_seo_keywords, '-', '') like '%" . tep_db_input($keyword) . "%')";

          if (isset($_GET['search_in_description']) && ($_GET['search_in_description'] == '1')) $where_str .= " or pd.products_description like '%" . tep_db_input($keyword) . "%'";
          if (isset($_GET['search_in_description']) && ($_GET['search_in_description'] == '1')) $where_str .= " or replace(pd.products_description, '-', '') like '%" . tep_db_input($keyword) . "%'";

          $where_str .= ')';
          break;
      }
    }
    $where_str .= " )";
  }

  if (tep_not_null($pfrom)) {
    if ($currencies->is_set($currency)) {
      $rate = $currencies->get_value($currency);

      $pfrom = $pfrom / $rate;
    }
  }

  if (tep_not_null($pto)) {
    if (isset($rate)) {
      $pto = $pto / $rate;
    }
  }

  if (DISPLAY_PRICE_WITH_TAX == 'true') {
    if ($pfrom > 0) $where_str .= " and (IF(s.status, s.specials_new_products_price, p.products_price) * if(gz.geo_zone_id is null, 1, 1 + (tr.tax_rate / 100) ) >= " . (double)$pfrom . ")";
    if ($pto > 0) $where_str .= " and (IF(s.status, s.specials_new_products_price, p.products_price) * if(gz.geo_zone_id is null, 1, 1 + (tr.tax_rate / 100) ) <= " . (double)$pto . ")";
  } else {
    if ($pfrom > 0) $where_str .= " and (IF(s.status, s.specials_new_products_price, p.products_price) >= " . (double)$pfrom . ")";
    if ($pto > 0) $where_str .= " and (IF(s.status, s.specials_new_products_price, p.products_price) <= " . (double)$pto . ")";
  }

  if ( (DISPLAY_PRICE_WITH_TAX == 'true') && (tep_not_null($pfrom) || tep_not_null($pto)) ) {
    $where_str .= " group by p.products_id, tr.tax_priority";
  }

  if ( (!isset($_GET['sort'])) || (!preg_match('/^[1-8][ad]$/', $_GET['sort'])) || (substr($_GET['sort'], 0, 1) > sizeof($column_list)) ) {
    for ($i=0, $n=sizeof($column_list); $i<$n; $i++) {
      if ($column_list[$i] == 'PRODUCT_LIST_NAME') {
        $_GET['sort'] = $i+1 . 'a';
        $order_str = " order by pd.products_seo_title";
       
        
        break;
      }
    }
  } else {
    $sort_col = substr($_GET['sort'], 0 , 1);
    $sort_order = substr($_GET['sort'], 1);

    switch ($column_list[$sort_col-1]) {
      case 'PRODUCT_LIST_MODEL':
        $order_str = " order by p.products_model " . ($sort_order == 'd' ? 'desc' : '') . ", pd.products_name";
        break;
      case 'PRODUCT_LIST_NAME':
        $order_str = " order by pd.products_seo_title " . ($sort_order == 'd' ? 'desc' : '');
        break;
      case 'PRODUCT_LIST_MANUFACTURER':
        $order_str = " order by m.manufacturers_name " . ($sort_order == 'd' ? 'desc' : '') . ", pd.products_name";
        break;
      case 'PRODUCT_LIST_QUANTITY':
        $order_str = " order by p.products_quantity " . ($sort_order == 'd' ? 'desc' : '') . ", pd.products_name";
        break;
      case 'PRODUCT_LIST_IMAGE':
        $order_str = " order by pd.products_name";
        break;
      case 'PRODUCT_LIST_WEIGHT':
        $order_str = " order by p.products_weight " . ($sort_order == 'd' ? 'desc' : '') . ", pd.products_name";
        break;
      case 'PRODUCT_LIST_PRICE':
        $order_str = " order by final_price " . ($sort_order == 'd' ? 'desc' : '') . ", pd.products_name";
        break;
         case 'PRODUCT_LIST_ID':
        $order_str = " order by p.products_id " . ($sort_order == 'd' ? 'desc' : '') . ", pd.products_name";
        break;
      case 'PRODUCT_LIST_ORDERED':
        $order_str = " order by p.products_ordered " . ($sort_order == 'd' ? 'desc' : '') . ", pd.products_name";
        break;
    }
  }

  $listing_sql = $select_str . $from_str . $where_str . $order_str;



  require('includes/modules/product_listing.php');

// stats_keywords.php_bof
  $keyword_lookup = tep_db_query("select search_text, search_date from search_queries where search_text = '" . $HTTP_GET_VARS['keywords'] . "'");
  //$keyword = tep_db_fetch_array($keyword_lookup);
  
  if (tep_db_num_rows($keyword_lookup) > 0) {
  
  tep_db_query("update search_queries set search_count = search_count+1, search_date = now() where search_text = '" . $HTTP_GET_VARS['keywords'] . "'");
  
  } else {
  
  tep_db_query("insert into search_queries (search_text, search_date) values ('" . $HTTP_GET_VARS['keywords'] . "', now())");
  
  }
  
// stats_keywords.php_eof 
  
    /************** BEGIN SITESEARCH CHANGE ****************/
  require('includes/modules/site_search.php'); 
  /************** END SITESEARCH CHANGE ******************/
// odyms start
				$listing_num = tep_db_num_rows(tep_db_query($listing_sql));

				if ($listing_num <=3 ) {
					$file_dir = DIR_FS_CATALOG . 'z_text/';
					$file_name = $file_dir.'words';

					$handle = fopen($file_name.$languages_id.'.txt', "rb");
					$contents = '';
					while (!feof($handle)) {
						$contents .= fread($handle, 8192);
					}
					fclose($handle);
					$words_ar = explode(' ',$contents);
					reset($words_ar);
					$correct_persnt = 75;
					//while (list($id,$val) = each($words_ar)) {
						foreach($words_ar as $id => $val){
						if (isset($search_keywords) && (sizeof($search_keywords) > 0)) {
							$where_str .= " and (";
							for ($i=0, $n=sizeof($search_keywords); $i<$n; $i++ ) {
								switch ($search_keywords[$i]) {
									case '(':
									case ')':
									case 'and':
									case 'or':
										break;
									default:
										similar_text($val,strtolower(stripcslashes($search_keywords[$i])),$prsnt);
										if ($prsnt >= $correct_persnt || (sizeof($search_keywords)>1 && $prsnt >= $correct_persnt && $prsnt<100)) {
											$similar_words_ar[$val] = $prsnt;
										}
										break;
								}
							}
							$where_str .= " )";
						}
					}

					if (sizeof($similar_words_ar)>0) {
						arsort($similar_words_ar);
						reset($similar_words_ar);
						$return_search_words = '';
					//	while (list($id,$val) = each($similar_words_ar)) {
							foreach ($similar_words_ar as $id => $val) {
							$return_search_words = $return_search_words.', <a href="'.tep_href_link('advanced_search_result.php','search_in_description=1&keywords='.$id).'" rel="nofollow"><b>'.$id.'</b></a>';
						}
						$return_search_words = substr($return_search_words,2,strlen($return_search_words));
					}
				}

				if (sizeof($similar_words_ar)>0)
?>
<div class="contentContainer">
  <br>
<?php echo sprintf(SEARCH_SUGGESTION, $return_search_words); ?>
</div>

<?php
// odyms end
?>


  <br>

  <div class="buttonSet">
    <?php echo tep_draw_button(IMAGE_BUTTON_BACK, 'fas fa-angle-left', tep_href_link('advanced_search.php', tep_get_all_get_params(array('sort', 'page')), 'NONSSL', true, false)); ?>
  </div>
</div>
  <div class="row">
    <?php echo $oscTemplate->getContent('advanced_search'); ?>
  </div>
<?php
  require('includes/template_bottom.php');
  require('includes/application_bottom.php');
?>
and the site search module page

Code: Select all

<?php
if (count($fileList) > 0 || count($pagesList) > 0) {
    $combinedList = array_merge($fileList, $pagesList);
    usort($combinedList, "SortFileLists"); 
?>
<div class="pageHeading" style="padding-top:10px"><?php echo TABLE_HEADING_SITESEARCH; ?></div>
<?php   
	   for($i=0; $i < count($combinedList); ++$i) {
?>
<div class="main"><?php echo '<a href="' . tep_href_link($combinedList[$i]['file'], $combinedList[$i]['ext']) . '">' . ucwords(substr($combinedList[$i]['file'], 0, strrpos($combinedList[$i]['file'],'.')) . ' ' . ucwords($combinedList[$i]['ext'])) . '</a>'; ?></div>
<?php 
    }
}
if (count($articlesList) > 0) { ?>
<div><?php echo tep_draw_separator('pixel_trans.gif', '100%', '10'); ?></div>
<div class="pageHeading" style="padding-top:10px"><?php echo TABLE_HEADING_SITESEARCH_ARTICLES; ?></div>
<?php   
	  for($i=0; $i < count($articlesList); ++$i) {
?>
<div class="main"><?php echo '<a href="' . tep_href_link(FILENAME_ARTICLE_INFO, 'articles_id='.$articlesList[$i]['id']) . '">' . ucwords($articlesList[$i]['name']) . '</a>'; ?></div>
<?php 
   } 
}  




I would really like to be able to use all of this on 1.1.0.2, so I will start the ball rolling and Invest in £50 worth of Beer tokens for Burt to make a start to adapt this.

Perhaps if a few of you who would like to use this would do the same then this very important add on could be updated and improved.

David
MyGamesShop
Contributor
Posts: 131
Joined: Wed Mar 10, 2021 3:02 am
Phoenix Version: v1.1.0.6
Has thanked: 8 times
Been thanked: 5 times

Re: advanced search by type ahead

Post by MyGamesShop »

burt wrote: Thu May 08, 2025 10:30 pm It should be do-able. If you can get some other shopowners interested enough I can take a day out to recode and maybe simplify it a bit. That's a lot of beer.




This is one of the plugins that makes Phoenix usability amazing for your customers, particularly when you have thousands of products.

Please like Burt's post if you would send him a beer.......and honor it.
User avatar
burt
Core Team
Posts: 4551
Joined: Tue Oct 29, 2019 9:37 am
Phoenix Version: v1.1.0.8
Has thanked: 252 times
Been thanked: 412 times

Re: advanced search by type ahead

Post by burt »

Odyms
I have never heard of this.

Fuzzy Search
app.php/tag/s08e05

TYpeahead
TY for the Beer, that'll allow me to at least take an initial look at this.
4 more shopowners do the same and that's half a day covered.
I am not here to build for you.
I am here to build with you. Let's help each other.
User avatar
bonbec
Contributor
Posts: 190
Joined: Mon Oct 26, 2020 12:23 pm
Phoenix Version: V1.1.0.7
Has thanked: 54 times
Been thanked: 40 times

Re: advanced search by type ahead

Post by bonbec »

Beer sent for Typeahead ;)
Old MS2.2 PHP7.4 site being converted to CE Phoenix v1.1.0.6 PHP 8.3
User avatar
burt
Core Team
Posts: 4551
Joined: Tue Oct 29, 2019 9:37 am
Phoenix Version: v1.1.0.8
Has thanked: 252 times
Been thanked: 412 times

Re: advanced search by type ahead

Post by burt »

Every Bit helps, TY. I've already started looking at it...it needs some simplifying (especially of the weird styling) and it needs some extra searching (seo title, seo keywords).

typeahead.png

So far, so good.
You do not have the required permissions to view the files attached to this post.
I am not here to build for you.
I am here to build with you. Let's help each other.
ecartz
Core Team
Posts: 3084
Joined: Tue Nov 05, 2019 6:02 pm
Phoenix Version:
Has thanked: 4 times
Been thanked: 208 times

Re: advanced search by type ahead

Post by ecartz »

burt wrote: Sat May 10, 2025 8:14 am Odyms
I have never heard of this.
Industry specific maybe? Possibly material science characteristics. Of course, what you'd actually need would be to know where it was stored in the database.

Alternately, perhaps you just need a hook to specify what will be included. E.g.

Code: Select all

$parameters['criteria'] = [
   'products' => ['products_model' => $GLOBALS['db']->escape("%$search_key%")],
   'products_description' => [
     'products_name'=> $GLOBALS['db']->escape("%$search_key%"),
     'products_description'=> $GLOBALS['db']->escape("%$search_key%"),
   ],
 ];
Then store owners could add or remove as desired. You could use https://github.com/CE-PhoenixCart/Phoen ... _query.php to build the SQL. Or make something similar if you need to support OR as well.
BatteryTrader
Contributor
Posts: 153
Joined: Thu Apr 11, 2024 7:18 am
Phoenix Version: 1.1.0.3
Has thanked: 3 times
Been thanked: 17 times

Re: advanced search by type ahead

Post by BatteryTrader »

Think iits part of z-adv_search.php

Code: Select all

<?php
/*
 $Id: $

 osCommerce, Open Source E-Commerce Solutions
 http://www.oscommerce.com

 Copyright (c) 2007 osCommerce

 Released under the GNU General Public License
 */

require('includes/application_top.php');

if (!isset($lng) || (isset($lng) && !is_object($lng))) {
	include('includes/classes/language.php');
	$lng = new language;
}

/*reset($lng->catalog_languages);
 while (list($key, $value) = each($lng->catalog_languages)) {

 } */

$file_dir = DIR_FS_CATALOG . 'z_text/';
$file_name = $file_dir.'words';

require('includes/template_top.php');
	?>

		<table border="0" width="100%" cellspacing="0" cellpadding="0">
			<tr>
				<td width="100%">
				<table border="0" width="100%" cellspacing="0" cellpadding="0">
					<tr>
						<td class="pageHeading"><?php echo HEADING_TITLE; ?></td>
						<td class="pageHeading" align="right"><?php echo tep_draw_separator('pixel_trans.gif', HEADING_IMAGE_WIDTH, HEADING_IMAGE_HEIGHT); ?></td>
					</tr>
				</table>
				</td>
			</tr>
			<tr>
				<td>
				<table border="0" width="100%" cellspacing="0" cellpadding="2">
					<tr>
						<td class="main"><?php
						reset($lng->catalog_languages);
						while (list($key, $value) = each($lng->catalog_languages)) {
							@unlink($file_name.$lng->catalog_languages[$key]['id'].'.txt');
						}

						$delete_chars_ar[] = "\r\n";
						$delete_chars_ar[] = "\r";
						$delete_chars_ar[] = "\n";
						$delete_chars_ar[] = ".";
						$delete_chars_ar[] = ",";
						$delete_chars_ar[] = "«";
						$delete_chars_ar[] = "»";
						$delete_chars_ar[] = "“";
						$delete_chars_ar[] = "”";
						$delete_chars_ar[] = "!";
						$delete_chars_ar[] = "?";
						$delete_chars_ar[] = "&";
						$delete_chars_ar[] = "(";
						$delete_chars_ar[] = ")";
						$delete_chars_ar[] = ";";
						$delete_chars_ar[] = ":";
						$delete_chars_ar[] = '" ';
						$delete_chars_ar[] = ' "';
						$delete_chars_ar[] = '\' ';
						$delete_chars_ar[] = ' \'';
						$delete_chars_ar[] = '` ';
						$delete_chars_ar[] = ' `';
						tep_db_query('delete from '.TABLE_PRODUCTS_DESCRIPTION_TEXT);
						$words_sq_sql = 'select p.products_model, pd.products_id, pd.language_id, pd.products_name, pd.products_description from ' .TABLE_PRODUCTS. ' p, '.TABLE_PRODUCTS_DESCRIPTION.' pd where p.products_id=pd.products_id order by language_id';
						$words_sq_qu = tep_db_query($words_sq_sql);
						while ($words_sq_ar = tep_db_fetch_array($words_sq_qu)) {
							$current_words = trim($words_sq_ar['products_model'].' '.$words_sq_ar['products_name'].' '.strip_tags($words_sq_ar['products_description']));
							reset($delete_chars_ar);
							while (list($id,$val) = each($delete_chars_ar)) {
								$current_words = str_replace($val,' ',$current_words);
							}

							while (strpos($current_words,'  ')>0) {
								$current_words = str_replace('  ',' ',$current_words);
							}
							$current_words_ar = explode(' ',$current_words);
							$current_words_ar = array_unique($current_words_ar);
							reset($current_words_ar);
							while (list($id,$val) = each($current_words_ar)) {
								$val = trim(strtolower($val));
								if (strlen($val)>2)
								$words_ar[$words_sq_ar['language_id']][$val] = $val;
							}

							$insert_sql_data = array('products_id' => $words_sq_ar['products_id'],
                                   		 'language_id' => $words_sq_ar['language_id'],
                                   		 'products_description' => implode(' ',$current_words_ar));

							tep_db_perform(TABLE_PRODUCTS_DESCRIPTION_TEXT, $insert_sql_data);
							//$words_sq_ar['products_description'];
						}
						reset($lng->catalog_languages);
						while (list($key, $value) = each($lng->catalog_languages)) {
							$curr_file_name = $file_name.$lng->catalog_languages[$key]['id'].'.txt';
							$fp = fopen($curr_file_name, 'w');
							sort($words_ar[$lng->catalog_languages[$key]['id']]);
							fwrite($fp, implode(' ',$words_ar[$lng->catalog_languages[$key]['id']]));
							fclose($fp);
						}
						
						echo COMPLETED_TEXT;
						?>
						</td>
					</tr>
					<!-- body_text_eof //-->
				</table>
				</td>
			</tr>
		</table>

<?php 
  require('includes/template_bottom.php');
  require('includes/application_bottom.php');
?>
which creates a set of words simular to terms and hold them in a text document

If nothing else if found it gives simular

search for appld, cant find it so suggests apple or something simular linked to the page it suggests

I run a cron over night to update the text files it creates as it does take a bit of time. few mins,
User avatar
burt
Core Team
Posts: 4551
Joined: Tue Oct 29, 2019 9:37 am
Phoenix Version: v1.1.0.8
Has thanked: 252 times
Been thanked: 412 times

Re: advanced search by type ahead

Post by burt »

OK, not enough interest/beer to allow the time to try to recode it.

I started fresh, and came up with this, which is a lot quicker, a lot smaller and a lot easier to manage.

burt_typeahead.png

Finalised testing now.
You do not have the required permissions to view the files attached to this post.
I am not here to build for you.
I am here to build with you. Let's help each other.


Join The Code Co-op to get access to your library in the Code Co-op Forum
Post Reply