Categories
Zen Cart Upgrades

Improving Zen Cart Search Results

You Can’t Always Find What You Want ….

Zen Cart’s search function doesn’t work very well. Search results are not ordered by relevance and many search terms produce no results even though there are products that should be listed.

In this article I describe how I made the search function work better for our model rocket store web site.

Do What I Say, Not What I Do ….

The method I describe here involves directly modifying Zen Cart core files. Generally, it isn’t a good idea to modify the core files of an application since it makes upgrading more difficult and error-prone.  But the upgrade process for Zen Cart is already error-prone since many themes directly modify core files.  Just be aware that by making the changes described here, you may be making things more difficult in the future.

The modifications described here are based on version 1.5.7 of Zen Cart.  If you are using a later version, you may need to do things a little differently than described here. 

Here is a list of the files that will be updated (replace [admin] with the name of your admin folder):

  • includes/modules/pages/advanced_search_result/header_php.php
  • [admin]/includes/functions/general.php
  • [admin]/includes/modules/document_product/preview_info.php

Fixing the Order of the Results ….

The first problem is that the order of the results isn’t based on how well the product matches the search term. For example, a product that has a title matching the search term should be listed before one that uses the search term in its description.  But, the order of the results seems random instead.

“Rob” of www.funkyraw.com offers an elegant solution in a post in the Zen Cart forum based on MySQL’s FULLTEXT search feature. 

I expanded on his technique a bit by adding a text field where you can enter additional text to be searched that isn’t displayed in the store and by slightly changing the order of the results.

Database Updates

We are going to add a column to the table that holds product descriptions and add a Full Text index to the table.

Using phpMyAdmin, go to the Structure tab of your products_description table. Add a products_search column with a type of “text.”

On the row for products_name click the Fulltext (“T”) icon (it may be under the “More” menu).  Next, select the check boxes next to the products_description and products_search field.  Then click the Fulltext link under the table and create a Fulltext index on the two columns .

File Update: includes/modules/pages/advanced_search_result/header_php.php

Edit the includes/modules/pages/advanced_search_result/header_php.php file.  Around line 219, find the following code:

// Notifier Point
$zco_notifier->notify('NOTIFY_SEARCH_SELECT_STRING');

//  $from_str = "from " . TABLE_PRODUCTS . " p left join " . TABLE_MANUFACTURERS . " m using(manufacturers_id), " . TABLE_PRODUCTS_DESCRIPTION . " pd left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id, " . TABLE_CATEGORIES . " c, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c";

$from_str = "FROM (" . TABLE_PRODUCTS . " pCode language: PHP (php)

Replace the above code with:

// Notifier Point
$zco_notifier->notify('NOTIFY_SEARCH_SELECT_STRING');

//  $from_str = "from " . TABLE_PRODUCTS . " p left join " . TABLE_MANUFACTURERS . " m using(manufacturers_id), " . TABLE_PRODUCTS_DESCRIPTION . " pd left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id, " . TABLE_CATEGORIES . " c, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c";

// FullText Ranking code by Rob - www.funkyraw.com
$from_str = ",  MATCH(pd.products_name) AGAINST(:keywords) AS rank1, MATCH(pd.products_description, pd.products_search) AGAINST(:keywords) AS rank2 ";
$from_str = $db->bindVars($from_str, ':keywords', stripslashes($_GET['keyword']), 'string');
//end FullText ranking code

$from_str .= "FROM (" . TABLE_PRODUCTS . " pCode language: PHP (php)

The first few lines are existing code that is not changed just to show you where to add the new code. The new code is added where you find the following in the existing file:

// Notifier Point
$zco_notifier->notify('NOTIFY_SEARCH_SELECT_STRING');

//  $from_str = "from " . TABLE_PRODUCTS . " p left join " . TABLE_MANUFACTURERS . " m using(manufacturers_id), " . TABLE_PRODUCTS_DESCRIPTION . " pd left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id, " . TABLE_CATEGORIES . " c, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c";
Code language: PHP (php)

The “// $from_str …” comment is dead code that is in the original file for version 1.57 (it might not be in a later version). Note that a “.” is added before the “=” in the last line of the new code.

Look farther down in the file for the following code:

if (isset($_GET['search_in_description']) && ($_GET['search_in_description'] == '1')) {
 $where_str .= " OR pd.products_description 
                 LIKE '%:keywords%'";
Code language: PHP (php)

Replace that code with:

// Full Text Search
// if (isset($_GET['search_in_description']) && ($_GET['search_in_description'] == '1')) {
//  $where_str .= " OR pd.products_description
//                  LIKE '%:keywords%'";

if (isset($_GET['search_in_description']) && ($_GET['search_in_description'] == '1')) {
  $where_str .= " OR pd.products_description
          LIKE '%:keywords%' OR pd.products_search
          LIKE '%:keywords%'";
// End ROGERCode language: PHP (php)

Now, closer to the end of the file, somewhere near line 420, and replace:

$order_str .= " order by p.products_sort_order, pd.products_name";Code language: PHP (php)

With:

// Full text search
// $order_str .= " order by p.products_sort_order, pd.products_name";
$order_str .= " order by rank1 DESC, rank2 DESC, p.products_sort_order, pd.products_name";Code language: PHP (php)

Okay, with these changes, the order of products returned for searches will be nicer.

Now, to make it easier to edit the extra search text, we need to update the Edit Product admin page to allow you to enter text in the new products_search column. Basically, everywhere the code deals with the products_description column, we duplicate it for the new products_search column.

File Update: [admin]/includes/functions/general.php

In the [admin]/includes/functions/general.php file add the following new method:

// Fulltext Search
  function zen_get_products_search($product_id, $language_id) {
    global $db;
    $product = $db->Execute("SELECT products_search
                             FROM " . TABLE_PRODUCTS_DESCRIPTION . "
                             WHERE products_id = " . (int)$product_id . "
                             AND language_id = " . (int)$language_id);
    if ($prodif (empty($products_description)) $products_description = [];
if (empty($products_search)) $products_search = [];ct->EOF) return '';
    return $product->fields['products_search'];
  }Code language: PHP (php)

File Update: [admin]/includes/modules/document_product/preview_info.php

Now, edit the [admin]/includes/modules/document_product/preview_info.php file. Near the top, find the code:

if (empty($products_description)) $products_description = [];
Code language: PHP (php)

Replace it with:

if (empty($products_description)) $products_description = [];
if (empty($products_search)) $products_search = [];Code language: PHP (php)

Around line 20, replace this code:

  $products_description = $_POST['products_description'];
Code language: PHP (php)

With:

  $products_description = $_POST['products_description'];
  $products_search = $_POST['products_search'];Code language: PHP (php)

Near line 28, replace:

  $product = $db->Execute("SELECT p.*,
                                  pd.language_id, pd.products_name, pd.products_description, pd.products_url
                           FROM " . TABLE_PRODUCTS . " p,
                                " . TABLE_PRODUCTS_DESCRIPTION . " pd
                           WHERE p.products_id = pd.products_id
                           AND p.products_id = " . (int)$_GET['pID']);
Code language: PHP (php)

With:

  $product = $db->Execute("SELECT p.*,
                                  pd.language_id, pd.products_name, pd.products_description, pd.products_search, pd.products_url
                           FROM " . TABLE_PRODUCTS . " p,
                                " . TABLE_PRODUCTS_DESCRIPTION . " pd
                           WHERE p.products_id = pd.products_id
                           AND p.products_id = " . (int)$_GET['pID']);
Code language: PHP (php)

Around line 41, replace:

    $products_description[$prod['language_id']] = $prod['products_description'];
Code language: PHP (php)

With:

    $products_description[$prod['language_id']] = $prod['products_description'];
    $products_search[$prod['language_id']] = $prod['products_search'];
Code language: PHP (php)

Near line 54, replace:

    for ($i = 0, $n = count($languages); $i < $n; $i++) {
      if (isset($_GET['read']) && ($_GET['read'] == 'only')) {
        $pInfo->products_name = zen_get_products_name($pInfo->products_id, $languages[$i]['id']);
        $pInfo->products_description = zen_get_products_description($pInfo->products_id, $languages[$i]['id']);
        $pInfo->products_url = zen_get_products_url($pInfo->products_id, $languages[$i]['id']);
      } else {
        $pInfo->products_name = zen_db_prepare_input($products_name[$languages[$i]['id']]);
        $pInfo->products_description = zen_db_prepare_input($products_description[$languages[$i]['id']]);
        $pInfo->products_url = zen_db_prepare_input($products_url[$languages[$i]['id']]);
      }
Code language: PHP (php)

With:

    for ($i = 0, $n = count($languages); $i < $n; $i++) {
      if (isset($_GET['read']) && ($_GET['read'] == 'only')) {
        $pInfo->products_name = zen_get_products_name($pInfo->products_id, $languages[$i]['id']);
        $pInfo->products_description = zen_get_products_description($pInfo->products_id, $languages[$i]['id']);
        $pInfo->products_search = zen_get_products_search($pInfo->products_id, $languages[$i]['id']);
        $pInfo->products_url = zen_get_products_url($pInfo->products_id, $languages[$i]['id']);
      } else {
        $pInfo->products_name = zen_db_prepare_input($products_name[$languages[$i]['id']]);
        $pInfo->products_description = zen_db_prepare_input($products_description[$languages[$i]['id']]);
        $pInfo->products_search = zen_db_prepare_input($products_search[$languages[$i]['id']]);
        $pInfo->products_url = zen_db_prepare_input($products_url[$languages[$i]['id']]);
      }
Code language: PHP (php)

Around line 160, replace:

        for ($i = 0, $n = count($languages); $i < $n; $i++) {
          echo zen_draw_hidden_field('products_name[' . $languages[$i]['id'] . ']', htmlspecialchars(stripslashes($products_name[$languages[$i]['id']]), ENT_COMPAT, CHARSET, TRUE));
          echo zen_draw_hidden_field('products_description[' . $languages[$i]['id'] . ']', htmlspecialchars(stripslashes($products_description[$languages[$i]['id']]), ENT_COMPAT, CHARSET, TRUE));
          echo zen_draw_hidden_field('products_url[' . $languages[$i]['id'] . ']', htmlspecialchars(stripslashes($products_url[$languages[$i]['id']]), ENT_COMPAT, CHARSET, TRUE));
        }
Code language: PHP (php)

With:

        for ($i = 0, $n = count($languages); $i < $n; $i++) {
          echo zen_draw_hidden_field('products_name[' . $languages[$i]['id'] . ']', htmlspecialchars(stripslashes($products_name[$languages[$i]['id']]), ENT_COMPAT, CHARSET, TRUE));
          echo zen_draw_hidden_field('products_description[' . $languages[$i]['id'] . ']', htmlspecialchars(stripslashes($products_description[$languages[$i]['id']]), ENT_COMPAT, CHARSET, TRUE));
          echo zen_draw_hidden_field('products_search[' . $languages[$i]['id'] . ']', htmlspecialchars(stripslashes($products_search[$languages[$i]['id']]), ENT_COMPAT, CHARSET, TRUE));
          echo zen_draw_hidden_field('products_url[' . $languages[$i]['id'] . ']', htmlspecialchars(stripslashes($products_url[$languages[$i]['id']]), ENT_COMPAT, CHARSET, TRUE));
        }
Code language: PHP (php)

File Update: [admin]/includes/modules/product/collect_info.php

In the [admin]/includes/modules/product/collect_info.php file, near line 11, change:

$parameters = [
  'products_name' => '',
  'products_description' => '',
  'products_url' => '',
  'products_id' => '',
  'products_quantity' => '0',
  'products_model' => '',
  'products_image' => '',
  'products_price' => '0.0000',
  'products_virtual' => DEFAULT_PRODUCT_PRODUCTS_VIRTUAL,
  'products_weight' => '0',
  'products_date_added' => '',
  'products_last_modified' => '',
  'products_date_available' => '',
  'products_status' => '1',
  'products_tax_class_id' => DEFAULT_PRODUCT_TAX_CLASS_ID,
  'manufacturers_id' => '',
  'products_quantity_order_min' => '1',
  'products_quantity_order_units' => '1',
  'products_priced_by_attribute' => '0',
  'product_is_free' => '0',
  'product_is_call' => '0',
  'products_quantity_mixed' => '1',
  'product_is_always_free_shipping' => DEFAULT_PRODUCT_PRODUCTS_IS_ALWAYS_FREE_SHIPPING,
  'products_qty_box_status' => PRODUCTS_QTY_BOX_STATUS,
  'products_quantity_order_max' => '0',
  'products_sort_order' => '0',
  'products_discount_type' => '0',
  'products_discount_type_from' => '0',
  'products_price_sorter' => '0',
  'master_categories_id' => '',
];
Code language: PHP (php)

To:

$parameters = [
  'products_name' => '',
  'products_description' => '',
  'products_search' => '',
  'products_url' => '',
  'products_id' => '',
  'products_quantity' => '0',
  'products_model' => '',
  'products_image' => '',
  'products_price' => '0.0000',
  'products_virtual' => DEFAULT_PRODUCT_PRODUCTS_VIRTUAL,
  'products_weight' => '0',
  'products_date_added' => '',
  'products_last_modified' => '',
  'products_date_available' => '',
  'products_status' => '1',
  'products_tax_class_id' => DEFAULT_PRODUCT_TAX_CLASS_ID,
  'manufacturers_id' => '',
  'products_quantity_order_min' => '1',
  'products_quantity_order_units' => '1',
  'products_priced_by_attribute' => '0',
  'product_is_free' => '0',
  'product_is_call' => '0',
  'products_quantity_mixed' => '1',
  'product_is_always_free_shipping' => DEFAULT_PRODUCT_PRODUCTS_IS_ALWAYS_FREE_SHIPPING,
  'products_qty_box_status' => PRODUCTS_QTY_BOX_STATUS,
  'products_quantity_order_max' => '0',
  'products_sort_order' => '0',
  'products_discount_type' => '0',
  'products_discount_type_from' => '0',
  'products_price_sorter' => '0',
  'master_categories_id' => '',
];
Code language: PHP (php)

Near line 48, change:

  $product = $db->Execute("SELECT pd.products_name, pd.products_description, pd.products_url,
                                  p.*, 
                                  date_format(p.products_date_available, '" .  zen_datepicker_format_forsql() . "') as products_date_available
                           FROM " . TABLE_PRODUCTS . " p,
                                " . TABLE_PRODUCTS_DESCRIPTION . " pd
                           WHERE p.products_id = " . (int)$_GET['pID'] . "
                           AND p.products_id = pd.products_id
                           AND pd.language_id = " . (int)$_SESSION['languages_id']);
Code language: PHP (php)

To:

  $product = $db->Execute("SELECT pd.products_name, pd.products_description, pd.products_search, pd.products_url,
                                  p.*, 
                                  date_format(p.products_date_available, '" .  zen_datepicker_format_forsql() . "') as products_date_available
                           FROM " . TABLE_PRODUCTS . " p,
                                " . TABLE_PRODUCTS_DESCRIPTION . " pd
                           WHERE p.products_id = " . (int)$_GET['pID'] . "
                           AND p.products_id = pd.products_id
                           AND pd.language_id = " . (int)$_SESSION['languages_id']);
Code language: PHP (php)

Around line 61, replace:

  $products_description = isset($_POST['products_description']) ? $_POST['products_description'] : '';
Code language: PHP (php)

With:

  $products_description = isset($_POST['products_description']) ? $_POST['products_description'] : '';
  $products_search = isset($_POST['products_search']) ? $_POST['products_search'] : '';
Code language: PHP (php)

Around line 323, replace:

  <div class="form-group">
      <p class="col-sm-3 control-label"><?php echo TEXT_PRODUCTS_DESCRIPTION; ?></p>
    <div class="col-sm-9 col-md-6">
        <?php
        for ($i = 0, $n = count($languages); $i < $n; $i++) {
          ?>
        <div class="input-group">
          <span class="input-group-addon">
              <?php echo zen_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']); ?>
          </span>
          <?php echo zen_draw_textarea_field('products_description[' . $languages[$i]['id'] . ']', 'soft', '100', '30', htmlspecialchars((isset($products_description[$languages[$i]['id']])) ? stripslashes($products_description[$languages[$i]['id']]) : zen_get_products_description($pInfo->products_id, $languages[$i]['id']), ENT_COMPAT, CHARSET, TRUE), 'class="editorHook form-control"'); ?>
        </div>
        <br>
        <?php
      }
      ?>
    </div>
  </div>
Code language: JavaScript (javascript)

With:

  <div class="form-group">
      <p class="col-sm-3 control-label"><?php echo TEXT_PRODUCTS_DESCRIPTION; ?></p>
    <div class="col-sm-9 col-md-6">
        <?php
        for ($i = 0, $n = count($languages); $i < $n; $i++) {
          ?>
        <div class="input-group">
          <span class="input-group-addon">
              <?php echo zen_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']); ?>
          </span>
          <?php echo zen_draw_textarea_field('products_description[' . $languages[$i]['id'] . ']', 'soft', '100', '30', htmlspecialchars((isset($products_description[$languages[$i]['id']])) ? stripslashes($products_description[$languages[$i]['id']]) : zen_get_products_description($pInfo->products_id, $languages[$i]['id']), ENT_COMPAT, CHARSET, TRUE), 'class="editorHook form-control"'); ?>
        </div>
        <br>
        <?php
      }
      ?>
    </div>
  </div>
  <div class="form-group">
      <p class="col-sm-3 control-label">Extra Search Text</p>
    <div class="col-sm-9 col-md-6">
        <?php
        for ($i = 0, $n = count($languages); $i < $n; $i++) {
          ?>
        <div class="input-group">
          <span class="input-group-addon">
              <?php echo zen_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']); ?>
          </span>
          <?php echo zen_draw_textarea_field('products_search[' . $languages[$i]['id'] . ']', 'soft', '100', '30', htmlspecialchars((isset($products_search[$languages[$i]['id']])) ? stripslashes($products_search[$languages[$i]['id']]) : zen_get_products_search($pInfo->products_id, $languages[$i]['id']), ENT_COMPAT, CHARSET, TRUE), 'class="editorHook form-control"'); ?>
        </div>
        <br>
        <?php
      }
      ?>
    </div>
  </div>
Code language: JavaScript (javascript)

File Update: [admin]/includes/modules/product/collect_info.php

In the [admin]/includes/modules/product/collect_info.php file, near line 11, change:

$parameters = [
  'products_name' => '',
  'products_description' => '',
  'products_url' => '',
  'products_id' => '',
  'products_quantity' => '0',
  'products_model' => '',
  'products_image' => '',
  'products_price' => '0.0000',
  'products_virtual' => DEFAULT_PRODUCT_PRODUCTS_VIRTUAL,
  'products_weight' => '0',
  'products_date_added' => '',
  'products_last_modified' => '',
  'products_date_available' => '',
  'products_status' => '1',
  'products_tax_class_id' => DEFAULT_PRODUCT_TAX_CLASS_ID,
  'manufacturers_id' => '',
  'products_quantity_order_min' => '1',
  'products_quantity_order_units' => '1',
  'products_priced_by_attribute' => '0',
  'product_is_free' => '0',
  'product_is_call' => '0',
  'products_quantity_mixed' => '1',
  'product_is_always_free_shipping' => DEFAULT_PRODUCT_PRODUCTS_IS_ALWAYS_FREE_SHIPPING,
  'products_qty_box_status' => PRODUCTS_QTY_BOX_STATUS,
  'products_quantity_order_max' => '0',
  'products_sort_order' => '0',
  'products_discount_type' => '0',
  'products_discount_type_from' => '0',
  'products_price_sorter' => '0',
  'master_categories_id' => '',
];
Code language: PHP (php)

To:

$parameters = [
  'products_name' => '',
  'products_description' => '',
  'products_search' => '',
  'products_url' => '',
  'products_id' => '',
  'products_quantity' => '0',
  'products_model' => '',
  'products_image' => '',
  'products_price' => '0.0000',
  'products_virtual' => DEFAULT_PRODUCT_PRODUCTS_VIRTUAL,
  'products_weight' => '0',
  'products_date_added' => '',
  'products_last_modified' => '',
  'products_date_available' => '',
  'products_status' => '1',
  'products_tax_class_id' => DEFAULT_PRODUCT_TAX_CLASS_ID,
  'manufacturers_id' => '',
  'products_quantity_order_min' => '1',
  'products_quantity_order_units' => '1',
  'products_priced_by_attribute' => '0',
  'product_is_free' => '0',
  'product_is_call' => '0',
  'products_quantity_mixed' => '1',
  'product_is_always_free_shipping' => DEFAULT_PRODUCT_PRODUCTS_IS_ALWAYS_FREE_SHIPPING,
  'products_qty_box_status' => PRODUCTS_QTY_BOX_STATUS,
  'products_quantity_order_max' => '0',
  'products_sort_order' => '0',
  'products_discount_type' => '0',
  'products_discount_type_from' => '0',
  'products_price_sorter' => '0',
  'master_categories_id' => '',
];
Code language: PHP (php)

Near line 47, replace:

if (isset($_GET['pID']) && empty($_POST)) {
  $product = $db->Execute("SELECT pd.products_name, pd.products_description, pd.products_url,
                                  p.*, 
                                  date_format(p.products_date_available, '" .  zen_datepicker_format_forsql() . "') as products_date_available
                           FROM " . TABLE_PRODUCTS . " p,
                                " . TABLE_PRODUCTS_DESCRIPTION . " pd
                           WHERE p.products_id = " . (int)$_GET['pID'] . "
                           AND p.products_id = pd.products_id
                           AND pd.language_id = " . (int)$_SESSION['languages_id']);

  $pInfo->updateObjectInfo($product->fields);
} elseif (zen_not_null($_POST)) {
  $pInfo->updateObjectInfo($_POST);
  $products_name = isset($_POST['products_name']) ? $_POST['products_name'] : '';
  $products_description = isset($_POST['products_description']) ? $_POST['products_description'] : '';
  $products_url = isset($_POST['products_url']) ? $_POST['products_url'] : '';
}
Code language: PHP (php)

With:

if (isset($_GET['pID']) && empty($_POST)) {
  $product = $db->Execute("SELECT pd.products_name, pd.products_description, pd.products_search, pd.products_url,
                                  p.*, 
                                  date_format(p.products_date_available, '" .  zen_datepicker_format_forsql() . "') as products_date_available
                           FROM " . TABLE_PRODUCTS . " p,
                                " . TABLE_PRODUCTS_DESCRIPTION . " pd
                           WHERE p.products_id = " . (int)$_GET['pID'] . "
                           AND p.products_id = pd.products_id
                           AND pd.language_id = " . (int)$_SESSION['languages_id']);

  $pInfo->updateObjectInfo($product->fields);
} elseif (zen_not_null($_POST)) {
  $pInfo->updateObjectInfo($_POST);
  $products_name = isset($_POST['products_name']) ? $_POST['products_name'] : '';
  $products_description = isset($_POST['products_description']) ? $_POST['products_description'] : '';
  $products_search = isset($_POST['products_search']) ? $_POST['products_search'] : '';
  $products_url = isset($_POST['products_url']) ? $_POST['products_url'] : '';
}
Code language: PHP (php)

Near line 323, change:

  <div class="form-group">
      <p class="col-sm-3 control-label"><?php echo TEXT_PRODUCTS_DESCRIPTION; ?></p>
    <div class="col-sm-9 col-md-6">
        <?php
        for ($i = 0, $n = count($languages); $i < $n; $i++) {
          ?>
        <div class="input-group">
          <span class="input-group-addon">
              <?php echo zen_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']); ?>
          </span>
          <?php echo zen_draw_textarea_field('products_description[' . $languages[$i]['id'] . ']', 'soft', '100', '30', htmlspecialchars((isset($products_description[$languages[$i]['id']])) ? stripslashes($products_description[$languages[$i]['id']]) : zen_get_products_description($pInfo->products_id, $languages[$i]['id']), ENT_COMPAT, CHARSET, TRUE), 'class="editorHook form-control"'); ?>
        </div>
        <br>
        <?php
      }
      ?>
    </div>
  </div>
Code language: JavaScript (javascript)

To:

  <div class="form-group">
      <p class="col-sm-3 control-label"><?php echo TEXT_PRODUCTS_DESCRIPTION; ?></p>
    <div class="col-sm-9 col-md-6">
        <?php
        for ($i = 0, $n = count($languages); $i < $n; $i++) {
          ?>
        <div class="input-group">
          <span class="input-group-addon">
              <?php echo zen_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']); ?>
          </span>
          <?php echo zen_draw_textarea_field('products_description[' . $languages[$i]['id'] . ']', 'soft', '100', '30', htmlspecialchars((isset($products_description[$languages[$i]['id']])) ? stripslashes($products_description[$languages[$i]['id']]) : zen_get_products_description($pInfo->products_id, $languages[$i]['id']), ENT_COMPAT, CHARSET, TRUE), 'class="editorHook form-control"'); ?>
        </div>
        <br>
        <?php
      }
      ?>
    </div>
  </div>
  <div class="form-group">
      <p class="col-sm-3 control-label">Extra Search Text</p>
    <div class="col-sm-9 col-md-6">
        <?php
        for ($i = 0, $n = count($languages); $i < $n; $i++) {
          ?>
        <div class="input-group">
          <span class="input-group-addon">
              <?php echo zen_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']); ?>
          </span>
          <?php echo zen_draw_textarea_field('products_search[' . $languages[$i]['id'] . ']', 'soft', '100', '30', htmlspecialchars((isset($products_search[$languages[$i]['id']])) ? stripslashes($products_search[$languages[$i]['id']]) : zen_get_products_search($pInfo->products_id, $languages[$i]['id']), ENT_COMPAT, CHARSET, TRUE), 'class="editorHook form-control"'); ?>
        </div>
        <br>
        <?php
      }
      ?>
    </div>
  </div>
Code language: JavaScript (javascript)

File Update: [admin]/includes/modules/product/preview_info.php

In the [admin]/includes/modules/product/preview_info.php file, near line 12, change:

if (empty($products_description)) $products_description = [];
Code language: PHP (php)

To:

if (empty($products_description)) $products_description = [];
if (empty($products_search)) $products_search = [];
Code language: PHP (php)

Around line 20, change:

  $products_description = $_POST['products_description'];
Code language: PHP (php)

To:

  $products_description = $_POST['products_description'];
  $products_search = $_POST['products_search'];
Code language: PHP (php)

Conclusion

Now, when a visitor searches for a product on your Zen Cart store web site the search results will be more relevant and ordered by relevancy.

Leave a Reply

Your email address will not be published. Required fields are marked *