The default OpenCart search is rather simple and can only search in the products’ names and descriptions. This limits the user in finding the desired product, which is a bad thing trade-wise. And this is where this article will come in handy, since there is nothing on the internet that even comes close to a tutorial on the subject.
Please note that:
- at least some knowledge of OpenCart is required tor one to follow the tutorial.
- all paths and file locations are specified relative to the path where OpenCart has been installed, unless specified otherwise.
- the version used here is 1.5.1.3
- PHP and JavaScript are not my primary programming languages, so I apologize for any “ugly” code I might be providing. But then, it works. Please report any problems/issues in the comments area, so I can address them ASAP.
- a complete working installation is available from BitBucket’s repository at https://bitbucket.org/solidhosting/solid-hosting-opencart-search. All changes are framed by a starting “// CUSTOM SEARCH BEGINS” and a closing “// CUSTOM SEARCH ENDS”
First, we need to determine what new search options need to be implemented. This is a relatively easy task, since the options depend heavily on the types of products being searched. In this case we will implement search functions for the products’ dimensions:
- Width
- Height
- Length
Since all these variables can assume only finite, predetermined values, they can be conveniently represented by the “SELECT” HTML tag. They can take on numerical values only, and the values are pretty much static in time, so we can simply hard code them – say from 1 to 10 (inches/centimeters/what have you).
These properties are already defined for each product, in the “product” table of OpenCart’s database, the “length”, “width” and “height” fields. So there will be no changes to the database.
Now that the search criteria has been determined, we are ready to proceed with the interface changes. Nothing complex here, just three SELECTs, organized in any way you want (or just let the designer make it up). These changes must be made to the Search page, and more precisely – the catalog/view/theme/default/template/product/search.tpl file. The language templates must also be updated, to include some static strings for the interface changes.
To sum up, we need to modify:
- the language file(s) to include the static text for the search page’s interface changes.
- the search page template
- the controller to search in the product dimensions
- the model to support this search
Now, let’s delve into the actual changes to the cart.
1. Modifying the language files
a. We’ll start with the changes to the language template, to accommodate for the titles of the search choices:
- each of the installed languages will have its own folder in the “catalog/language/” one. In this case we will only be modifying the default, English language templates.
- the file of interest is “product/search.php” under the language folder, in this case – “catalog/language/english/product/search.php”.
- edit that file and insert the appropriate definitions at the end of the file, before the closing “?>” php tag:
// Custom search
$_[‘text_width’] = ‘Width:';
$_[‘text_height’] = ‘Height:';
$_[‘text_length’] = ‘Length:';
- save the file and close it, as no further changes will be made to it
b. Then we need to load these custom titles in the controller, so we can use them in the search.tpl template file. The file that needs to be changed is “catalog/controller/product/search.php”:
- open that file and locate the end of the language strings’ loading, around the 155th line (that’s for version 1.5.1.3).
- insert these lines in it:
$this->data[‘text_width’] = $this->language->get(‘text_width’);
$this->data[‘text_height’] = $this->language->get(‘text_height’);
$this->data[‘text_length’] = $this->language->get(‘text_length’);
- save the file but keep it open.
2. Modifying the search page template
We are now ready to implement the changes to the Search page.
a. The interface will be kept as simple as possible, its design will be omitted for clarity. Only values between 1 (one) and 10 (ten) will be used. The three SELECT dropdown menus will be displayed horizontally, in one line, between the “Search in product descriptions” checkbox and the “Search” button:
- open the aforementioned “catalog/view/theme/default/template/product/search.tpl” file
- locate the end of the <div> that contains the search box, categories and the “Search in product description” checkbox, which is just after the lines
<label for=”description”><?php echo $entry_description; ?></label>
</div>
- insert a new td and a div:
<td>
<div id=”extended_search” style=”display: block;”>
<table>
<tr>
<td>
<div><?php echo $text_length; ?></div>
<select name=”length” id=”length”>
<option value=”–“>–</option>
<option value=”1″>1</option>
<option value=”2″>2</option>
<option value=”3″>3</option>
<option value=”4″>4</option>
<option value=”5″>5</option>
<option value=”6″>6</option>
<option value=”7″>7</option>
<option value=”8″ >8</option>
<option value=”9″>9</option>
<option value=”10″>10</option>
</select>
</td>
<td>
<div><?php echo $text_width; ?></div>
<select name=”width” id=”width”>
<option value=”–” >–</option>
<option value=”1″>1</option>
<option value=”2″>2</option>
<option value=”3″>3</option>
<option value=”4″>4</option>
<option value=”5″>5</option>
<option value=”6″>6</option>
<option value=”7″>7</option>
<option value=”8″ >8</option>
<option value=”9″>9</option>
<option value=”10″>10</option>
</select>
</td>
<td>
<div><?php echo $text_height; ?></div>
<select name=”height” id=”height”>
<option value=”–” >–</option>
<option value=”1″>1</option>
<option value=”2″>2</option>
<option value=”3″>3</option>
<option value=”4″>4</option>
<option value=”5″>5</option>
<option value=”6″>6</option>
<option value=”7″>7</option>
<option value=”8″ >8</option>
<option value=”9″>9</option>
<option value=”10″>10</option>
</select>
</td>
</tr>
</table>
</div>
</td>
- finally, save the file (but keep it open) and load the search page – http://www.example.com/OPENCARTFOLDER/index.php?route=product/search – to test the changes. Remember to replace example.com and OPENCARTFOLDER with your domain name and OpenCart’s installation folder, respectively.
b. Now we must incorporate the new parameters in the search procedure. We need to change the JavaScript function at the end of the search template to include the new parameters – if selected – in the URL, as GET parameters:
- return to the “catalog/view/theme/default/template/product/search.tpl” file
- insert these lines just before the last line in the “#button-search” function:
var filter_width = $(‘#content select[name=\’width\’]’).attr(‘value’);
if (filter_width!=’–‘) {
url += ‘&width=’ + encodeURIComponent(filter_width);
}var filter_height = $(‘#content select[name=\’height\’]’).attr(‘value’);
if (filter_height!=’–‘) {
url += ‘&height=’ + encodeURIComponent(filter_height);
}var filter_length = $(‘#content select[name=\’length\’]’).attr(‘value’);
if (filter_length!=’–‘) {
url += ‘&length=’ + encodeURIComponent(filter_length);
}
- save and again test the changes by reloading the search page and choosing a value in one (or more) of the new SELECTs. Hit the “Search” button and the selected option(s) should appear in the URL.
c. Let’s reflect the selected values by marking the appropriate options in the SELECTs as “selected”. The way to do this is as follows:
- examine the GET parameters in the search controller to see whether any of the dimensions have been specified and if yes, create the appropriate PHP variables and initialize them
- check the dimension variables in the search template and if set, mark the appropriate options in the SELECT dropdowns as “selected”
Point 1. is easily achieved:
- open the search controller file, catalog/controller/product/search.php, and locate the initialization of the “breadcrumbs” array, around line 74:
$this->data[‘breadcrumbs’] = array();
- and insert these lines just before it:
if (isset($this->request->get[‘length’])) {
$this->data[‘length’] = $this->request->get[‘length’];
} else {
$this->data[‘length’] = ”;
}if (isset($this->request->get[‘width’])) {
$this->data[‘width’] = $this->request->get[‘width’];
} else {
$this->data[‘width’] = ”;
}if (isset($this->request->get[‘height’])) {
$this->data[‘height’] = $this->request->get[‘height’];
} else {
$this->data[‘height’] = ”;
}
- (some housekeeping here) scroll down to the next assignment of the $this->data[‘breadcrumbs’][] variable (around line 138):
$this->data[‘breadcrumbs’][] = array( …
- and insert these lines just above it:
if (isset($this->request->get[‘length’])) {
$url .= ‘&length=’ . $this->request->get[‘length’];
}if (isset($this->request->get[‘width’])) {
$url .= ‘&width=’ . $this->request->get[‘width’];
}if (isset($this->request->get[‘height’])) {
$url .= ‘&height=’ . $this->request->get[‘height’];
}
- save the file, still keeping it open, and move on to the search template.
Point 2. Now we will have $length, $width and $height as variables in the search template, either set to the previously selected values, or empty, if no selection has been made. We have two ways to set the appropriate options in the SELECT elements as “selected” – JavaScript and PHP code. Both will be discussed here, starting with PHP:
- just test whether the value of the option matches the variable, as in:
<select name=”length” id=”length”>
<option value=”–“>–</option>
<option value=”1″ <?php if ($length == 1) echo “selected=\”selected\””; ?>>1</option>
<option value=”2″ <?php if ($length == 2) echo “selected=\”selected\””; ?>>2</option>
<option value=”3″ <?php if ($length == 3) echo “selected=\”selected\””; ?>>3</option>
- or use a for(…) loop from 1 to 10 (inclusive), to print the value of each option, eventually set the “selected” attribute, and print the text of the option, like the categories loops above.
I like the JavaScript way of changing the SELECTs better – just check whether any of the variables are set, and print the appropriate JavaScript to change the SELECT selected option:
- insert these lines at the very end of the search.tpl file:
<?php
if ($height || $width || $length) { ?><script type=”text/javascript”>
<!–function SetSelectOption(id, opt) {
var selectmenu=document.getElementById(id);
for( i = 0; i < selectmenu.length; i++ ) {
if (selectmenu.options[i].value == opt) {
selectmenu.options[i].selected = true;
return;
}
}
}<?php
if ($length) {
?>
SetSelectOption(“length”, <?php echo $length ?>);
<?php
}
if ($width) {
?>
SetSelectOption(“width”, <?php echo $width ?>);
<?php
}
if ($height) {
?>
SetSelectOption(“height”, <?php echo $height ?>);
<?php
}
?>//–>
</script><?php
}
?>
and it works like a charm. This is the last change you need to make in the Search template, so you can close search.tpl.
3. Modifying the controller to search in the product dimensions
a. For the sake of completeness and compliance, we have to alter the Search controller to add the variables to the Sort and Show page modifiers. See the problem by searching for “samsung” in the Search textbox, in “All Categories”, checking the “Search in product descriptions” checkbox, and setting random values for the dimensions’ parameters. All will be fine until you sort the search results by any criteria other than “Default” – then the dimension parameters disappear. The same goes for the “results per page” limit, set via the “Show” dropdown. The changes are similar to the housekeeping changes before the $this->data[‘breadcrumbs’] variable above, so they will be omitted here – examine the modified files to see the changes, if you wish. The changes must be made to the “catalog/controller/product/search.php” file, before the initialization of both the “$this->data[‘sorts’]” array (on line 319 at this point of coding) and the “$this->data[‘limits’]” array (on line 417 at this moment). The same goes for the pagination, which is just below the “$this->data[‘limits’]” populating.
b. The last thing we have to do is check the products’ dimensions against the newly introduced parameters, if set. An important decision has to be made here – whether the newly introduced search parameters will be restrictive, or if they could be enhancing. In other words, whether the search results by keyword will be further restricted by the specified dimension(s), or one could search by only the dimensions, without a keyword. The second option will require more modifications, and is more complex. Only the first option will be covered in detail here, and instructions on how to implement the second one will be provided along the way.
c. The Search controller (catalog/controller/product/search.php) places all search criteria in a named array, that is passed to the Catalog Product model search functions getTotalProducts(…) and getProducts(…). This is executed only if the “filter_name” or the “filter_tag” parameters have been set (that is, if a keyword has been entered in the search field). If one needs to implement the second option then s/he will need to modify the condition of the search to be true even if only one of the dimensions parameters has been set, i.e. the line
if (isset($this->request->get[‘filter_name’]) || isset($this->request->get[‘filter_tag’])) {
becomes something like:
if (isset($this->request->get[‘filter_name’]) || isset($this->request->get[‘filter_tag’]) || isset($this->request->get[‘height’]) || isset($this->request->get[‘width’]) || isset($this->request->get[‘length’])) {
d. Regardless of whether you make that change or not, we need to include the dimensions in the data array. Make the following changes to the controller file just after the aforementioned condition, inserting them before the closing bracket of the $data initialization (the entire $data initialization is shown here, the new code lines are the last three, and don’t forget the comma after the $limit variable):
$data = array(
‘filter_name’ => $filter_name,
‘filter_tag’ => $filter_tag,
‘filter_description’ => $filter_description,
‘filter_category_id’ => $filter_category_id,
‘filter_sub_category’ => $filter_sub_category,
‘sort’ => $sort,
‘order’ => $order,
‘start’ => ($page – 1) * $limit,
‘limit’ => $limit,
‘height’ => isset($this->request->get[‘height’]) ? $this->request->get[‘height’] : ”,
‘width’ => isset($this->request->get[‘width’]) ? $this->request->get[‘width’] : ”,
‘length’ => isset($this->request->get[‘length’]) ? $this->request->get[‘length’] : ”
);
These are the last modifications that will be made to the Search controller, so close the catalog/controller/product/search.php file and move to the model changes.
4. Modifying the model to support this search
The Catalog Product model class is located in the catalog/model/catalog/product.php file.
a. We will first change the getTotalProducts(…) function. Locate it near the bottom of the file, around line 480, and find the actual execution of the constructed query near its end:
- $query = $this->db->query($sql);
Insert the amendment to the SQL statement just above it:
if (!empty($data[‘length’])) {
$sql .= ” AND p.length = ‘” . (int)$data[‘length’] . “‘”;
}if (!empty($data[‘width’])) {
$sql .= ” AND p.width = ‘” . (int)$data[‘width’] . “‘”;
}if (!empty($data[‘height’])) {
$sql .= ” AND p.height = ‘” . (int)$data[‘height’] . “‘”;
}
This alteration works in both options, mentioned above – the restricting and enhancing ones. If you wish to truly go for the restrictive one only (option one) then place the alteration in the
if (!empty($data[‘filter_name’]) || !empty($data[‘filter_tag’])) {
clause.
b. Then:
- locate the getProducts(…) function – near the top of the file – and find the GROUP BY addition, i.e. this line:
$sql .= ” GROUP BY p.product_id”;
- insert the SQL modification just above it:
if (!empty($data[‘length’])) {
$sql .= ” AND p.length = ‘” . $data[‘length’] . “‘”;
}if (!empty($data[‘width’])) {
$sql .= ” AND p.width = ‘” . $data[‘width’] . “‘”;
}if (!empty($data[‘height’])) {
$sql .= ” AND p.height = ‘” . $data[‘height’] . “‘”;
}
- save the file and set out for testing.
All you have to do now is access the admin interface and set the dimensions for several products, then test the search with entering a keyword and a dimension or two.
Now, notice that the dimensions are not shown when you access a product’s description, and we must show them if we can search by them. But that is the topic of another article, which will be coming soon.
Enjoy!
36 comments
David says:
Apr 10, 2013
Hi,
First of all, this is a great tutorial. I just had a quick question regarding the structure of the database queries that are made when entering in search terms.
It seems like the search function utilizes the getProducts and the getTotalProducts functions to find the terms once the queries have been made with db queries which pulls the entirety of products from the db and then analyses which terms match the results.
Correct me if I’m wrong but is there a way to first have a boolean match against db query in the name column of oc_product_description only first, then have the matching results based on the product_id pull only those relevant product details to put less strain on the MySql server?
I am making a site with over one million products and regular search on 1.5.5.1 takes a long time 20-40 seconds.
Any recommendations will be much appreciated.
Solid Hosting says:
Apr 11, 2013
Hello,
Both functions restrict the SELECT clause with a WHERE condition based on the product_description.name and/or product_description.description fields, if a search string (filter_name) has been entered.
An easy way to see exactly what OpenCart creates as SQL queries is to write the SQL statement in each function to a file:
$FILE_MINE = "/PATH/TO/FILE/getTotal.txt";
$myfile = fopen($FILE_MINE, "a") or die("Error opening the file $FILE_MINE");
fwrite($myfile, "$sql\r\n");
fclose($myfile);
Place that code just before this line:
$query = $this->db->query($sql);
at the end of both functions.
Your data is huge, this is true, but you can check whether the database is optimized, for example having the proper indexes in your tables. There are free OpenCart plugins which do that, like VQMod. Of course, a database query cache would help too.
But then you are right that OpenCart’s database flow can certainly be improved. However, this is not a light undertaking as it requires a careful examination of the way all its code interacts with the database layer and perform the changes in such a way as not to break other components.
As such, this question is better suited for the very developers of OpenCart.
Solid Hosting Programming Team
For programming services please contact us at sales@solid-hosting.net
David says:
Apr 23, 2013
Thanks for the response. I managed to strip a lot of the queries out of the product/model file and I am getting really quick results now. However, when I want to search in product_description I am stuck with a match against pd.name OR match against pd.description.
Is there a way to have the query only include the pd.description once a search term has been inserted into the search page and the “search in description” box has been selected?
In other words, how do I exclude pd.name from being included in the query?
I tested out both options and the latter is much faster.
David
cao says:
Apr 9, 2013
catalog/view/theme/default/template/product/search.tpl
I need help with the underfined variable.
code
<a href="”>
<input type="text" name="search" value="” />
(line 15) <input type="text" name="search" value="” onclick=”this.value = ”;” onkeydown=”this.style.color = ‘000000’” style=”color: #FF0000;” />
Notice: Undefined variable: search in C:\wamp\www\Test1551\catalog\view\theme\default\template\product\search.tpl on line 15
Notice: Undefined variable: sub_category in C:\wamp\www\Test1551\catalog\view\theme\default\template\product\search.tpl on line 41
Undefined variable: description in C:\wamp\www\Test1551\catalog\view\theme\default\template\product\search.tpl on line 48
catalog/language/english/product/search.php
Solid Hosting says:
Apr 10, 2013
Hello,
The download files were a much older version. We placed the latest version we have from this project at BitBucket:
https://bitbucket.org/solidhosting/solid-hosting-opencart-search
It is much better in functionality – it comes with a side search panel, selectable search features, etc. Check its user and administrative interfaces – the administrative interface is in the Extensions/Modules page.
Solid Hosting Programming Team
For programming services please contact us at sales@solid-hosting.net
cao says:
Apr 8, 2013
catalog/view/theme/default/template/product/search.tpl
line 15 is the one causing the error.
code:
?php echo $header; ?><?php echo $column_left; ? ?php echo $column_right; ?
div id="content" ?php echo $content_top; ?
div class="breadcrumb"
?php foreach ($breadcrumbs as $breadcrumb) { ?
?php echo $breadcrumb['separator']; ? a href="
/div
h1 ?php echo $heading_title; ? /h1
b ?php echo $text_critea; ? /b
div class=”content”
p ?php echo $entry_search; ?
?php if ($search) { ?
input type=”text” name=”search” value=”<?php echo $search; ? " /
?php } else { ?
(line 15) — input type="text" name="search" value="<?php echo $search; ? " onclick="this.value = '';" onkeydown="this.style.color = '000000'" style="color: #FF0000;" /
?php } ?
cao says:
Apr 8, 2013
the first part of the file
catalog/view/theme/default/template/product/search.tpl
<a href="”>
<input type="text" name="search" value="” />
(line 15) <input type="text" name="search" value="” onclick=”this.value = ”;” onkeydown=”this.style.color = ‘000000’” style=”color: #FF0000;” />
Notice: Undefined variable: search in C:\wamp\www\Test1551\catalog\view\theme\default\template\product\search.tpl on line 15
Notice: Undefined variable: sub_category in C:\wamp\www\Test1551\catalog\view\theme\default\template\product\search.tpl on line 41
Undefined variable: description in C:\wamp\www\Test1551\catalog\view\theme\default\template\product\search.tpl on line 48
cao says:
Apr 8, 2013
catalog/view/theme/default/template/product/search.tpl
<a href="”>
<input type="text" name="search" value="” />
(line 15) <input type="text" name="search" value="” onclick=”this.value = ”;” onkeydown=”this.style.color = ‘000000’” style=”color: #FF0000;” />
I need help with the undefined variables:
Notice: Undefined variable: search in C:\wamp\www\Test1551\catalog\view\theme\default\template\product\search.tpl on line 15
Notice: Undefined variable: sub_category in C:\wamp\www\Test1551\catalog\view\theme\default\template\product\search.tpl on line 41
Undefined variable: description in C:\wamp\www\Test1551\catalog\view\theme\default\template\product\search.tpl on line 48
catalog/language/english/product/search.php
<?php
// Heading
$_['heading_title'] = 'Search';
// Text
$_['text_search'] = 'Products meeting the search criteria';
$_['text_keyword'] = 'Keywords';
$_['text_category'] = 'All Categories';
$_['text_sub_category'] = 'Search in subcategories';
catalog/controller/product/search.php
language->load(‘product/search’);
$this->load->model(‘catalog/category’);
$this->load->model(‘catalog/product’);
$this->load->model(‘tool/image’);
if (isset($this->request->get[‘filter_name’])) {
$filter_name = $this->request->get[‘filter_name’];
} else {
$filter_name = ”;
}
if (isset($this->request->get[‘filter_tag’])) {
$filter_tag = $this->request->get[‘filter_tag’];
} elseif (isset($this->request->get[‘filter_name’])) {
$filter_tag = $this->request->get[‘filter_name’];
} else {
$filter_tag = ”;
}
if (isset($this->request->get[‘filter_description’])) {
$filter_description = $this->request->get[‘filter_description’];
} else {
$filter_description = ”;
}
if (isset($this->request->get[‘filter_category_id’])) {
$filter_category_id = $this->request->get[‘filter_category_id’];
} else {
$filter_category_id = 0;
}
if (isset($this->request->get[‘filter_sub_category’])) {
$filter_sub_category = $this->request->get[‘filter_sub_category’];
} else {
$filter_sub_category = ”;
}
serhio says:
Mar 27, 2013
Hello! I am sorry to ask a question after a year that this topic has been answered, but i am in need of a code that would let me search my opencart website through the help of the product code. i looked at your answers but my product.php file is not the same as the ones you are talking about.. what is the row number or i dont know…anything…because there isn’t even the word “words” from the sql statement…please help me with this, is it possible there is another way or something…?
Solid Hosting says:
Apr 10, 2013
Hello,
Most probably your cart is a newer version than the one we used for this tutorial, hence the differences you see. We placed an extended version of this search module, along with an entire cart, at BitBucket:
https://bitbucket.org/solidhosting/solid-hosting-opencart-search
You can download the entire cart from there and check out all the features we have built in there.
Unfortunately this project is no longer supported, though if there is enough interest in it, we might be able to reopen it.
Solid Hosting Programming Team
For programming services please contact us at sales@solid-hosting.net
gopikrishnan says:
Dec 6, 2012
hi i am using option price update using custom coding adding jquery script in header.tpl and my new issue is to hide price in drop down option price but i dont want to remove it,only need to merge text color of option price to background color but i tried using and tags then also its not working.
this is the line i want to print as invisible as user the varible used in it are array.
( )
If anybody knows how to solve my issue means update…we are looking forward to ur idea on this please help us.
Speedovic says:
Nov 18, 2012
I need some help translating a working PHP/SQL code from PHP into MVC opencart. The code works fine as a one file, it looks for the nearest zip-code of a store. Search the net I can’t find any existing solution. If someone is willing to take a challenge plz let me know I will forward the the code or send you the link.
Zoeken op LBH | Open Cart Know How says:
Oct 31, 2012
[…] http://www.solid-hosting.net/blog/coding/how-to-customize-opencarts-search/ […]
Melanie says:
Aug 29, 2012
That works perfectly!!
I appreciate this so much, it was so simple and I actually understand it as well
Thank you so much, you’re fantastic,
Melanie
Solid Hosting says:
Aug 30, 2012
Hello,
You are welcome anytime! Please note that we have compiled information from this article and all the comments to it and we are currently creating an OpenCart search module/plug-in that will allow one to modify the search to look in various places for information, i.e. attributes, options, the product model/dimensions, etc. We hope to have it completed in the next few weeks, so check back often for updates.
Best Regards,
Solid Hosting Programming Team
For programming services please contact us at sales@solid-hosting.net
Melanie says:
Aug 28, 2012
Hi there,
Similar to your first comment by Vikram the Bookshop owner – I am hoping to allow customers to search by product code (model).
Your explanation of modifying the SQL statement in the model was explained beautifully so I thought I could do it simply but unfortunately – although I am using “Version 1.5.1.3″ – my code appears differently. Instead of :
foreach ($words as $word) {
if (!empty($data[‘filter_description’])) {
$implode[] = “LCASE(pd.name) LIKE ‘%” . $this->db->escape(utf8_strtolower($word)) . “%’ OR LCASE(pd.description) LIKE ‘%” . $this->db->escape(utf8_strtolower($word)) . “%’ OR LCASE(patt.text) LIKE ‘%” . $this->db->escape(utf8_strtolower($word)) . “%'”;
} else {
$implode[] = “LCASE(pd.name) LIKE ‘%” . $this->db->escape(utf8_strtolower($word)) . “%’ OR LCASE(patt.text) LIKE ‘%” . $this->db->escape(utf8_strtolower($word)) . “%'”;
}
}
My code looks like this:
foreach ($words as $word) {
if (!empty($data[‘filter_description’])) {
$implode[] = “LCASE(pd.name) LIKE ‘%” . $this->db->escape(utf8_strtolower($word)) . “%’ OR LCASE(pd.description) LIKE ‘%” . $this->db->escape(utf8_strtolower($word)) . “%'”;
} else {
$implode[] = “LCASE(pd.name) LIKE ‘%” . $this->db->escape(utf8_strtolower($word)) . “%'”;
}
}
Could you give me a little advice on how to adjust to my code.
Thank you so much for answering these questions,
Melanie
Solid Hosting says:
Aug 29, 2012
Hello,
It appears we made a mistake in the answer to Vikram Khosla – we copy/pasted extended code from previous enhancements. You are correct that the original code in catalog/model/catalog/product.php is indeed the one you pasted.
As such, all you need to do is change this original code to read:
foreach ($words as $word) {
if (!empty($data['filter_description'])) {
$implode[] = "LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%' OR LCASE(pd.description) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%' OR LCASE(p.model) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%'";
} else {
$implode[] = "LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%' OR LCASE(p.model) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%'";
}
}
The original post was updated as well.
Please accept our apologies for the mistake, and thank you for bringing it to our attention.
Best Regards,
Solid Hosting Programming Team
For programming services please contact us at sales@solid-hosting.net
Vikram Khosla says:
Jul 19, 2012
Hi,
I am hosting a book shop. Most of my customers search for 5 search criteria on the TOP HEADER SEARCH BAR. They look for Book Title (Sale as Product Name), ISBN-13 Number (Same as Model Number), ISBN-10 (Attribute), Author (Attribute) or Publisher (Attribute).
Is there any way to search for all these from default top search bar and get quick results for any of these criteria’s.
If the top default search cannot look into attributes, is there a way to copy these attributes into product description or maybe a new table and then look for these terms from one table and pull the results?
There are many advance search modules which I can buy to search for attributes. But the problem is I don’t want customers to:
1. Get to search page and see “No result found” from the top menu bar and then
2. choose from drop down menus and select the attributes to get the result.
I want a search function like google or yahoo where any search term could be found easily.
Please reply ASAP.
Solid Hosting says:
Jul 20, 2012
Hello,
Yes, you can easily do that. An assumption is made that you want your customers to be able to enter a keyword in the search box and find any of the books that contain that keyword in the
book title
ISBN numbers
Author
Publisher
fields.
If this assumption is correct then all you need to do is modify the SQL statement in the model to achieve your goal. The default search will look for the keywords entered in the product name (book title) only.
Thus you need to search all attributes (ISBN-10, Author, Publisher) and the product.model field too. Here is how:
– open the catalog/model/catalog/product.php file
– find the getProducts function and locate these lines in it (about line 60)
1.
if (!empty($data['filter_category_id'])) {
$sql .= " LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (p.product_id = p2c.product_id)";
}
Insert this code just below the above lines:
if (!empty($data['filter_name'])) {
$sql .= " LEFT JOIN " . DB_PREFIX . "product_attribute pa ON (p.product_id = pa.product_id)";
}
2.
foreach ($words as $word) {
if (!empty($data['filter_description'])) {
$implode[] = "LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%' OR LCASE(pd.description) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%'";
} else {
$implode[] = "LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%'";
}
}
– change the lines to read
foreach ($words as $word) {
if (!empty($data['filter_description'])) {
$implode[] = "LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%' OR LCASE(pd.description) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%' OR LCASE(patt.text) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%' OR LCASE(p.model) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%'";
} else {
$implode[] = "LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%' OR LCASE(patt.text) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%' OR LCASE(p.model) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%'";
}
}
– perform the same changes in the getTotalProducts() function – the respective code is around line 438
and that should achieve your goal.
Best Regards,
Solid Hosting Programming Team
For programming services please contact us at sales@solid-hosting.net
Gaetano says:
Jul 19, 2012
Hello Solid Hosting,
First of all, your tutorial is awesome, very very helpful. Now I come with a rather simple question and I believe many others have asked you the same. what about adding a quantity box to the standard search?
Is there a easy way to do that?
Thanks a lot
Gaetano
Solid Hosting says:
Jul 19, 2012
Hello,
Thank you for your kind words.
Actually you are the first to inquire about such a functionality of the search function. All the questions we have received are listed above as comments.
On to your issue – the short answer is yes. I am assuming that you wish to be able to search for a product by its name or keywords, and have a quantity box that specifies that the shown results have that many items in store as a minimum, i.e. searching for “Apple iPhone 4? and specifying ten (10) in that box will only turn out results if you have ten iPhone 4 in store. IF THIS ASSUMPTION IS INCORRECT THEN PLEASE ELABORATE.
The way to do it is very simple – follow the tutorial, but instead of a dropdown (SELECT) add a textbox (INPUT TYPE=”text”) to the search page and change the SQL to search for this quantity in the products.quantity field (AND products.quantity >= input_quantity). I have numbered each step for your convenience.
Note that you, in most cases, just copy/paste the tutorial steps’ code, but just copy the lines for one of the selects, changing it as appropriate.
More precisely:
At step 1. insert only one line for the label for the quantity box.
At step 2.a. just insert one textbox:
<td>
<div id=”extended_search” style=”display: block;”>
<div>< ?php echo $text_length; ?></div>
<p><input type=”text” name=”quantity_box” id=”quantity_box” />
</div>
</td>
Add the quantity box contents to the URL in 2.b.
Initialize the value of the textbox with the quantity, if it exists in the GET parameters, in 2.c.
No changes at 3.a – the default behavior of the search function is to show the quantity of each product.
Again no changes at 3.b., as per the assumption above.
Still no changes at 3.c. – the only check whether the quantity box has been filled will be in the model modification.
Insert the quantity box value in the $data array in 3.d.
On to 4. Make the appropriate change to the SQL statement in 4.a.:
if (!empty($data[‘quantity_box’])) {
$sql .= ” AND p.quantity >= ‘” . (int)$data[‘quantity_box’] . “‘”;
}
Perform the same change in 4.b. and you should be set!
Thus, you see, the only significant change to the tutorial steps is in 4.a. and 4.b.
Again, if my assumption was incorrect then please elaborate.
Best Regards,
Solid Hosting Programming Team
For programming services please contact us at sales@solid-hosting.net
Gaetano says:
Jul 20, 2012
Thank you so much for your prompt replay and I have to apologise because I didn’t make my question clear enough, totally my bad.
What I meant is, how can I show in the result of a standard search (no extra fields added) also a quantity input box where clients can set the amount of an item they wish to add to the chart .
On the other hand, your modification to the initial tutorial will definitely turns out very useful for us. Thank you so much again.
Regards
Gaetano
Solid Hosting says:
Jul 21, 2012
Hello,
Your clarification does change the task at hand. But the changes you wish to make are very simple. First of all, we must ask where must the changes be made? Simple – in the search template. If you examine the catalog/view/theme/default/template/product/search.tpl file, you will notice the section where the products found are listed:
<div class="product-list">
<?php foreach ($products as $product) { ?>
We will add the quantity box just before the “Add to cart” button, for the sake of simplicity. Find the line in the search template that shows that button:
<div class="cart"><input type="button" value="<?php echo $button_cart; ?>" onclick="addToCart('<?php echo $product['product_id']; ?>');" class="button" /></div>
and insert a textbox in it:
<div class="cart">Quantity: <input type="text" value="1" name="quantity_<?php echo $product['product_id']; ?>" /><input type="button" value="<?php echo $button_cart; ?>" onclick="addToCart('<?php echo $product['product_id']; ?>');" class="button" /></div>
The “Add to cart” button calls a JSON function – addToCart(…) – located in the catalog/view/javascript/common.js file. There are two scenarios here:
i. The product does not have any options that need to be specified before it is added to the cart. In this case the product is directly added to the cart.
ii. The product does need to be configured. The user is then redirected to the product page – catalog/controller/product/product.php – to enter any additional information that is required.
The first scenario is very easy to cover – just modify the JSON Javascript function to get the quantity from the textbox you have added earlier to the search results page:
/* Modifying addToCart(…) in catalog/view/javascript/common.js, starting at line 89 */
– find this line at the very beginning of the addToCart(…) function:
quantity = typeof(quantity) != 'undefined' ? quantity : 1;
– replace it with:
quantity = document.getElementById('quantity_' + product_id).value;
if (typeof(quantity) == 'undefined')
quantity = 0;
if (quantity < 1) { alert("Please specify the quantity of the product!"); return false; }
Please note that simple validation of the user input is performed here, you might wish to check whether the entered string is numeric, etc.
And if the product does not have any configurable options, or its minimum order quantity is 1, it will be added directly to the cart with the specified quantity. Try it out on a default installation of OpenCart, search for "iphone" for example, enter 4 (four) in the quantity box and hit the "Add to Cart" button, then check the shopping cart contents (via the "Shopping Cart" link) to verify.
However, if the product has options that need to be set before adding it to the cart, then the product page appears - scenario ii. It appears that the quantity is not passed to the catalog/controller/product/product.php page, and instead the minimum order quantity of that product is displayed in the "Qty:" textbox. If you wish to preserve the user's input in this case, then you will need to:
a. pass the quantity to the product page via a GET parameter. The JSON response in the Javascript function addToCart will contain a redirect parameter if there are configurable options for the product. Just add the quantity to that redirect url:
- find this line in the catalog/view/javascript/common.js file:
if (json['redirect']) {
location = json['redirect'];
}
- and change it to read:
if (json['redirect']) {
location = json['redirect'] + "&cust_quantity=" + quantity;
}
- then open the product page - catalog/controller/product/product.php - and locate the initialization of the "Qty:" textbox:
if ($product_info['minimum']) {
$this->data['minimum'] = $product_info['minimum'];
} else {
$this->data['minimum'] = 1;
}
- check whether the user has ordered more than the minimum, and if so, update the appropriate variable. Insert these lines just below the above ones:
if (isset($this->request->get['cust_quantity'])) {
if ($this->data['minimum'] < $this->request->get['cust_quantity'])
$this->data['minimum'] = $this->request->get['cust_quantity'];
}
Thus the user's input will be preserved, even if the product needs to be additionally configured.
Best Regards,
Solid Hosting Programming Team
For programming services please contact us at sales@solid-hosting.net
Gaetano says:
Jul 22, 2012
Thank you so much, I really don’t have words to express my gratitude.
The instructions are perfect and clear, now I only have one more question. How can I set my search to be of the first scenario? I want my addToChart button to add directly the item in the chart without any redirection. Is it something I can set in my admin, or do I have to change the code to match the first scenario you mentioned in your post?
Thanks a lot!
Gaetano
Solid Hosting says:
Jul 25, 2012
Hello,
Sorry for the late reply – it has been rather busy here for some time now.
The first scenario occurs when the product has no configurable options, which you, the store owner, can set/modify/remove. In essence, if you want all your products to be ordered via the first scenario, then just do not set any configurable options for them.
An example is in order – log in to your administration panel of OpenCart and visit the Catalog/Products page. Edit any of the products there and visit the Options tab. You can set many options for the product via that page – the color of the item, its dimensions, etc.
If you do not set any options for the item, then you will be using scenario one. It is up to you, the store owner.
You will need to examine your inventory, or the services you will offer, and see whether they have any variables that need to be set before the sale occurs. For example, if your main business is spa services, you might at least ask the customer about the duration of the treatment s/he is ordering – a one hour mud bath, two hours mud bath, what have you.
Hopefully this has made things clearer.
Best Regards,
Solid Hosting Programming Team
For programming services please contact us at sales@solid-hosting.net
IF you like this post, share it.
Gaetano Egidio says:
Jul 26, 2012
Hello and thanks again.
The explanation is crystal clear, I went to ask about the settings for the first scenario kind of add to chart, because I couldn’t find the line of code you suggested in the creation of the extra input field for qualities. In common.js, this is what “addToChart” looks like:
function addToCart(product_id) {
$.ajax({
url: ‘index.php?route=checkout/cart/update’,
type: ‘post’,
data: ‘product_id=’ + product_id,
dataType: ‘json’,
success: function(json) {
$(‘.success, .warning, .attention, .information, .error’).remove();
if (json[‘redirect’]) {
location = json[‘redirect’];
}
if (json[‘error’]) {
if (json[‘error’][‘warning’]) {
$(‘#notification’).html(” + json[‘error’][‘warning’] + ”);
$(‘.warning’).fadeIn(‘slow’);
$(‘html, body’).animate({ scrollTop: 0 }, ‘slow’);
}
}
if (json[‘success’]) {
$(‘#notification’).html(” + json[‘success’] + ”);
$(‘.success’).fadeIn(‘slow’);
$(‘#cart_total’).html(json[‘total’]);
$(‘html, body’).animate({ scrollTop: 0 }, ‘slow’);
}
}
});
}
Is there something that I’m missing or there is something I should do to change this code?
Regards
Gaetano
Solid Hosting says:
Jul 26, 2012
Hello,
It appears your version of the common.js file is modified – I checked both versions 1.5.1.3 and 1.5.3.1 and the addToCart() functions were identical. The default function is as follows:
function addToCart(product_id, quantity) {
quantity = typeof(quantity) != 'undefined' ? quantity : 1;
$.ajax({
url: 'index.php?route=checkout/cart/add',
type: 'post',
data: 'product_id=' + product_id + '&quantity=' + quantity,
dataType: 'json',
success: function(json) {
$('.success, .warning, .attention, .information, .error').remove();
if (json['redirect']) {
location = json['redirect'];
}
if (json['success']) {
$('#notification').html('
');
$('.success').fadeIn('slow');
$('#cart-total').html(json['total']);
$('html, body').animate({ scrollTop: 0 }, 'slow');
}
}
});
}
Note that your version makes a JSON request to “index.php?route=checkout/cart/update”, while the default one requests “index.php?route=checkout/cart/add” instead. Also, your version does not accept a quantity as a second parameter.
Please check the version of your OpenCart. We are creating these changes on a default installation, and we recommend you keep a clean installation of OpenCart handy, for cases like this.
Unfortunately we cannot advise how to change your version of the addToCart() function, as any changes to it might break other custom changes to your site.
Solid Hosting Programming Team
For programming services please contact us at sales@solid-hosting.net
IF you like this post, share it.
Gaetano Egidio says:
Aug 2, 2012
Dear Solid Hosting Programming Team,
After some time looking for the reason of the differences between our version of the common.js file and the one you described, we found the way to change back our version of opencart to the standard one.
However, when we tried to apply the changes you kindly suggested, we faced a difficulty: apparently the modified function addToCart takes two parameters the product_id and the quantity (which we added on the search template). But, while modifying the search.tpl, we found out that the onclick event of the input button was calling a function addToCart with a single parameter:
<input type="button" value="” onclick=”addToCart(”);” class=”button” />
Is there something wrong or it has to be like this?
Thanks
Gaetano
Solid Hosting says:
Aug 2, 2012
Hello,
This is how the programmers of OpenCart coded the calling of the addToCart function – since there is no “quantity” box to specify the quantity of the product that is added to the cart, then the “quantity” parameter is useless in this case. The code in the function sets the quantity to 1 if the “quantity” parameter is not specified when calling addToCart.
Please note that the default behaviour of the addToCart function was modified several answers ago (our second answer to your comments) to check for the value, specified in the quantity box, and use that.
We made that change to the addToCart function, as else we would have to modify the onclick property of the Add To Cart button, making it rather long and ugly to read. Another option would be to create a separate function in the common.js file that would collect the value of the quantity box and pass it to the addToCart function, but modifying addToCart was the easiest way to go.
Please note that the checks and the initialization of the “quantity” parameter of the addToCart function are far from perfect, so you might need to alter them a bit – check whether a parameter has been passed, if not, check whether there is a quantity box in the page, if not – decide what to do, etc.
Solid Hosting Programming Team
For programming services please contact us at sales@solid-hosting.net
Ron says:
Jul 13, 2012
Hi. I followed your example and attempted to modify it so that I could search by product ID but with no luck.
The Search by Product ID checkbox reflected the selection correctly, the url was modified appropriately, in fact everything appeared to be functioning as it should except no results were returned.
I’m assuming I missed/messed something up in the translation from drop down select to using the existing text input. I worked on it for several hours with no success.
When/if you have the time could you point out the code changes I would need for searching by product ID? Thanks!
Solid Hosting says:
Jul 16, 2012
Hello,
The product ID column in the OpenCart/product page contains a numerical to uniquely identify an OpenCart inventory item. Searching by it is a strange feature, so I have to ask, out of pure curiosity, why are you implementing it? (If that’s not secret of course)
Anyway, here is how to do it. First, an assumption is made, that you will really be searching by the product ID, which is an integer, and you will be entering that number in the search box, checking off a checkbox, and hitting the Search button.
Since you have implemented all the interface changes, I will concentrate on the modifications that need to be made to the controller and the model.
1. Modify the controller class ControllerProductSearch (/catalog/controller/product/search.php) to specify to the model whether it should be searching in the product IDs too, perhaps by including a variable in the $data array that is passed to the getTotalProducts(…) and getProducts(…) functions, in this area:
if (isset($this->request->get['filter_name']) || isset($this->request->get['filter_tag'])) {
$data = array(
'filter_name' => $filter_name,
'filter_tag' => $filter_tag,
'filter_description' => $filter_description,
'filter_category_id' => $filter_category_id,
'filter_sub_category' => $filter_sub_category,
'sort' => $sort,
'order' => $order,
'start' => ($page - 1) * $limit,
'limit' => $limit
);
$product_total = $this->model_catalog_product->getTotalProducts($data);
$results = $this->model_catalog_product->getProducts($data);
Since the assumption is that you will be using the default search box to input the product ID, the if condition will be satisfied, and you can just add your custom checkbox value in the $data array:
'limit' => $limit,
'isitpID' => $this->request->get['cb_pid']
);
where cb_pid is the ID of your checkbox. Then you modify the code in the getTotalProducts and getProducts functions (in catalog/model/catalog/product.php) to create the appropriate SQL code. Modify the getProducts function as follows:
– locate these lines in that function – about line 55 in the file:
if (!empty($data['filter_name'])) {
$implode = array();
– change it like this:
if (!empty($data['filter_name'])) {
if ($data['isitpID']) {
$sql .= "p.product_id = '" . $data['filter_name'] . "'";
}
else {
$implode = array();
$words = explode(' ', $data['filter_name']);
foreach ($words as $word) {
if (!empty($data['filter_description'])) {
$implode[] = "LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%' OR LCASE(pd.description) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%'";
} else {
$implode[] = "LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%'";
}
}
if ($implode) {
$sql .= " " . implode(" OR ", $implode) . "";
}
}
}
– if you are implementing the search functionality to be able to search by more than one ID, then you will need to break the search string in IDs, enumerate them one by one and change the SQL search string to look something like
p.product_id = 'ID1' OR p.product_id = 'ID2' OR p.product_id = 'ID3'
– the getTotalProducts function changes are identical to the ones above, so I will not be posting them here. If the search will be restricted to only one ID, then you can just do this in the beginning of the function:
if ($data['isitpID'])
return 1;
This is pretty much all you need to do. Let us know your progress!
Best Regards,
Solid Hosting Programming Team
For programming services please contact us at sales@solid-hosting.net
dnastov says:
May 19, 2012
Is there a way to make the search use AND instead of OR, so that when I search for “full hd” I receive just the results containing both words (full AND hd), and not everuthing that has either of the two words (full OR hd).
I tried editing the \catalog\model\catalog\product.php but I never seem to get the desired result.
Best regards,
Peter says:
May 3, 2012
How can I modify this code to search in the product attributes?
I know that I have to modify only the query, and put there 2 JOINs with the “attribute_description” and “product_attribute”
I tried but no result, any advice would be helpful
Thanks
Solid Hosting says:
May 3, 2012
Hello,
Assuming we operate on a default installation of OpenCart.
Much like the search options from the article above, you can create this functionality in either a restrictive or enhancing way:
1. match the search string in the product name, description or the product attribute text
2. create controls at the search page to display the available attributes and restrict the search, based on the user selection
The first option is implemented by simply changing the SQL query indeed – see below. N.B. The attribute_description table contains (guess what) the descriptions for the attributes, and they are pretty much static for all products, so I do not really see any reason for searching in it, neither JOINing it to the search results. Please correct me if I am wrong.
The second option requires a LOT more work and thought. I will cover the first scenario here and I will provide indications on how to accomplish the second one. Here we go:
– open the ModelCatalogProduct file (catalog/model/catalog/product.php)
– locate the getProducts() function
– there are two JOINs there already, just add another one after the product_to_category one:
if (!empty($data['filter_category_id'])) {
$sql .= " LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (p.product_id = p2c.product_id)";
}
--- THIRD JOIN STARTS ---
$sql .= " LEFT JOIN " . DB_PREFIX . "product_attribute patt on (p.product_id = patt.product_id)";
--- THIRD JOIN ENDS ---
– now change the search SQL query to search in the product attributes
foreach ($words as $word) {
if (!empty($data['filter_description'])) {
$implode[] = "LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%' OR LCASE(pd.description) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%' OR LCASE(patt.text) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%'";
} else {
$implode[] = "LCASE(pd.name) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%' OR LCASE(patt.text) LIKE '%" . $this->db->escape(utf8_strtolower($word)) . "%'";
}
}
– change the getTotalProducts() function in absolutely the same way
– save the catalog/model/catalog/product.php
– test the changes by searching for “mhz” (w/o the quotes) and you will get the Apple Cinema 30″ display as a result (the attribute is under the “Specification” tab)
The second option is more complex. I would go about implementing it in much the same way as the article goes, i.e. in the following way:
– place a select input (a dropdown menu) at the search page with all the attributes’ descriptions (and the options’ values set to the “attribute_id”s)
– of course, add an empty item in the select input
– if a non-empty item was selected, show several other inputs to further narrow down the search, i.e. if the “Clockspeed” attribute was selected, then show a textbox (or another dropdown, etc.) to have the user input the speed in megahertz, or even show two textboxes, to have a “BETWEEN” search – less than X and more than Y megahertz. One can customize the design for each input separately, with DIVs, showing and hiding each one as appropriate
– each such search criteria must be saved as a GET parameter (see the article on how to do that)
– the controller must handle each such parameter, placing it in the named array that is passed to the model
– the model must adjust its SQL query according to the parameters passed
and you will be ready. Easy when you know how, right?
Best Regards,
Solid Hosting Programming Team
For programming services please contact us at sales@solid-hosting.net
Ankit says:
Apr 4, 2012
Can you please tell me how to search in categories by default?
Solid Hosting says:
Apr 15, 2012
Hello,
First, please accept my apologies for the late answer, but it is been hectic around here for some time now. Anyway, your question is rather vague, but I will do my best to answer it.
The default search operates on all categories, and if you check the “Search in subcategories” checkbox, you will be able to search in the subcategories too. This search operates on the products in the (sub)categories, though, and not on the categories’ names or their description. However, if you wish to perform a search in the categories’ names or descriptions, you will need to make some changes to the model and controller. Unfortunately I cannot provide a full solution to the problem, but here are some pointers:
1. Add the appropriate function to the ModelCatalogCategory class, in the “/catalog/model/catalog/category.php” file. For example:
public function searchCategories($searchString) {
$query = $this->db->query(“SELECT * FROM ” . DB_PREFIX . “category_description cd WHERE LOWER(cd.name) like ‘%” . strtolower($searchString) . “%’ ORDER BY LOWER(cd.name)”);
return $query->rows;
}
This search function will search all categories’ names for the search string and return the rows found. If you need some other search functionality then modify the SQL statement to your needs.
2. Modify the search template (“/catalog/view/theme/default/template/product/search.tpl”) to include a checkbox that will specify whether the search will be performed on the categories or on the products.
3. Modify the controller – /catalog/controller/product/search.php – to check whether the “Categories” checkbox is checked. If yes, then perform a search in the categories, using the search function, mentioned above. This modification does not seem to be a trivial one, as the products and categories have different fields.
4. Finally, modify the search template again, to show the categories’ search results in some fashion.
This is not a light undertaking, so good luck
If this does not answer your question then please elaborate.
Best Regards,
Solid Hosting Programming Team
For programming services please contact us at sales@solid-hosting.net