Search by Product Code

I want the default search on our website to include the Product code as well as the default search criteria. I found a topic covering this same topic here : [url]http://forum.cs-cart.com/showthread.php?t=12554&highlight=search+product+code[/url]



But it didn’t work for me, and I didn’t want to resurrect that thread, when I can ask here. They mention in the post listed that you have to modify the “core/fn.core.php”. The reason why it didn’t work for me was because the file “core/fn.core.php” does not exist on my server or local download of my site. Is this normal?



Does anyone know which file I should be modifying now that I have 2.0.9 so I can change the search criteria?

HAd you read the entire thread you would have seen that the file you want is:



/core/fn.catalog.php



Bob

Ahh, didn’t notice that Bob. Thank you for pointing that out.



So I have opened it up and now I have found the code snippet, but mine looks a little different than the code discussed in the thread. Another reason I wanted to make a new thread.



For instance the $params[‘pname’] field is already being used for something other than the product_code.



```php

foreach ($pieces as $piece) {

$tmp = db_quote(“(descr1.search_words LIKE ?l)”, “%$piece%”); // check search words



if ($params[‘pname’] == ‘Y’) {

$tmp .= db_quote(" OR descr1.product LIKE ?l", “%$piece%”);

}

if ($params[‘pshort’] == ‘Y’) {

$tmp .= db_quote(" OR descr1.short_description LIKE ?l", “%$piece%”);

}

if ($params[‘pfull’] == ‘Y’) {

$tmp .= db_quote(" OR descr1.full_description LIKE ?l", “%$piece%”);

}

if ($params[‘pkeywords’] == ‘Y’) {

$tmp .= db_quote(" OR (descr1.meta_keywords LIKE ?l OR descr1.meta_description LIKE ?l)“, “%$piece%”, “%$piece%”);

}

if (!empty($params[‘feature’]) && $params[‘action’] != ‘feature_search’) {

$tmp .= db_quote(” OR ?:product_features_values.value LIKE ?l", “%$piece%”);

}



fn_set_hook(‘additional_fields_in_search’, $params, $fields, $sortings, $condition, $join, $sorting, $group_by, $tmp);



$_condition[] = ‘(’ . $tmp . ‘)’;

}

```



So I thought maybe I could just declare another value called $params[‘product_code’] , but not without the declaring that field beforehand above the search code. So viewing the rest of the function we see



```php

function fn_get_products($params, $items_per_page = 0, $lang_code = CART_LANGUAGE)

// Set default values to input params

$default_params = array (

‘pname’ => ‘’,

‘pshort’ => ‘’,

‘pfull’ => ‘’,

‘pkeywords’ => ‘’,

‘feature’ => array(),

‘type’ => ‘simple’,

‘page’ => 1,

‘action’ => ‘’,

‘variants’ => array(),

‘ranges’ => array(),

‘custom_range’ => array(),

‘field_range’ => array(),

‘features_hash’ => ‘’,

‘limit’ => 0,

‘bid’ => 0,

‘match’ => ‘’,

‘search_tracking_flags’ => array()

);



$params = array_merge($default_params, $params);



if (empty($params[‘pname’]) && empty($params[‘pshort’]) && empty($params[‘pfull’]) && empty($params[‘pkeywords’]) && empty($params[‘feature’])) {

$params[‘pname’] = ‘Y’;

}



$auth = & $_SESSION[‘auth’];



// Define fields that should be retrieved

$fields = array (

‘products.product_id’,

‘descr1.product as product’,

‘products.tracking’,

‘products.feature_comparison’,

‘products.zero_price_action’,

‘products.product_type’,

‘products.tax_ids’,

‘products.weight’,

“GROUP_CONCAT(IF(products_categories.link_type = ‘M’, CONCAT(products_categories.category_id, ‘M’), products_categories.category_id)) as category_ids”,

‘min_qty’,

‘max_qty’,

‘products.qty_step’,

‘products.list_qty_count’,

‘avail_since’,

‘buy_in_advance’,

‘popularity.total as popularity’

);

```



So since the $params is passed into the function then is it even possible to modify what it is pulling to do the search, or am I missing something here? I understand how the forearch is going through each of the parameters, and i just need to add the code in there to make sure it checks for product code. But from the code I posted above, it is isn’t even pulling product_code as a parametere, so where do I declare the “product_code” as something the search should pull before doing the foreach?

Assuming that you are using 2.0.8 all you have to do is what is in the last part of that thread that I posted.



I added:


if ($params['pshort'] == 'Y') {
$tmp .= db_quote(" OR descr1.short_description LIKE ?l", "%$piece%");
}




After:


if ($params['pname'] == 'Y') {
$tmp .= db_quote(" OR products.product_code LIKE ?s", "%$piece%");
}




That was it, that is all I did and it worked perfect for 2.0.8



Brandon

[quote name=‘brandonvd’]Assuming that you are using 2.0.8 all you have to do is what is in the last part of that thread that I posted.



I added:


if ($params['pshort'] == 'Y') {
$tmp .= db_quote(" OR descr1.short_description LIKE ?l", "%$piece%");
}




After:


if ($params['pname'] == 'Y') {
$tmp .= db_quote(" OR products.product_code LIKE ?s", "%$piece%");
}




That was it, that is all I did and it worked perfect for 2.0.8



Brandon[/QUOTE]



Brandon,



THank you. Just to clarify, this part


if ($params['pname'] == 'Y') {
$tmp .= db_quote(" OR descr1.product LIKE ?l", "%$piece%");
}




is already used. So changing descr1.product to descr1.product_code will not be good since it will eliminate whatever descr1.product is from the search criteria. See what i am saying. So i will basically be trading descr1.product from descr1.product_code. That doesn’t seem like the best idea…

You know what I did? I mistakenly posted wrong. What should have been posted was:



In core/fn.catalog.php



Add:


if ($params['pname'] == 'Y') {
$tmp .= db_quote(" OR products.product_code LIKE ?s", "%$piece%");
}




Before:


if ($params['pshort'] == 'Y') {
$tmp .= db_quote(" OR descr1.short_description LIKE ?l", "%$piece%");
}




Does this make more since?



As for the clafifications, I really don’t know what to say. I’m not a coder and didn’t make this up. I got this from the CS-Cart knowledge base and just modified it to work with 2.0.8.



I hope this helps,



Brandon

[quote name=‘brandonvd’]

In core/fn.catalog.php



Add:


if ($params['pname'] == 'Y') {
$tmp .= db_quote(" OR products.product_code LIKE ?s", "%$piece%");
}




Before:


if ($params['pshort'] == 'Y') {
$tmp .= db_quote(" OR descr1.short_description LIKE ?l", "%$piece%");
}


[/QUOTE]



Brandon, thanks again. Let me explain a little my thoughts on this to you and everyone in more detail so I can explain my concern with using the knowledgebase code.



In the core/fn.catalog.php file is where all of this search code appears. I have some knowledge of PHP so I am going to explain what little I think I understand about this. When you do a search what it looks like it is doing is pulling all of the fields related to a product or products, then searching those products for the string that you searched for.



It looks like the “pname” field is actually already taken as a search parameter using the if ($params[‘pname’] == ‘Y’) —> this basically takes the “pname” field and adds the value of the pname the descr1.product field to the end of the $tmp variable, which we eventually use as a list of words to search for.



The problem is, the product field needs to be searchable as well. So when you modify the “descr1.product” to “descr1.product_code” you are losing/trading one search field for another, so now you don’t search on the product field anymore, just product_code… Does that make sense?



More explanation if necessary:



So the way it loops through all the product fields is the foreach ($pieces as $piece) line. Looking at the my specific code further:



foreach ($pieces as $piece) {
$tmp = db_quote("(descr1.search_words LIKE ?l)", "%$piece%"); // check search words




Here we set $tmp equal to all of the search words in the “search words” field specific product we are looking at. Then more code:



if ($params['pname'] == 'Y') {
$tmp .= db_quote(" OR descr1.product LIKE ?l", "%$piece%");
}
if ($params['pshort'] == 'Y') {
$tmp .= db_quote(" OR descr1.short_description LIKE ?l", "%$piece%");
}
if ($params['pfull'] == 'Y') {
$tmp .= db_quote(" OR descr1.full_description LIKE ?l", "%$piece%");
}
if ($params['pkeywords'] == 'Y') {
$tmp .= db_quote(" OR (descr1.meta_keywords LIKE ?l OR descr1.meta_description LIKE ?l)", "%$piece%", "%$piece%");
}




So here we add all of the other fields like “short description” and “full description” and “keywords” etc. to the $tmp variable. This is great because it makes a little list out of everything that we could possibly want to search for.



So if we change “descr1.product” to “descr1.product_code” we don’t search on product anymore, only product_code. … right??



Anyone can correct me if I have evaluated the code wrong, it is very possible, like I said, I have limited knowledge of PHP.



Is this something we should be concerned with? Maybe… Maybe not. What does everyone think? Most importantly, how can we STILL search on the “product” field and the “product_code” field???

Ok, now you got me wondering.



I am a little confused by what you are saying, so please bare with me.



I think you are saying that with the given code the search will get messed up. I don’t fully get this.



I decided to test my search and so I searched by:



product code

product title

keywords

words in the short description

words in the long description



Each time the same product came up in the search. Sure sometimes it was together with other products, but since they had words in common, I think this was right.



So I guess what I am trying to figure out is if the search isn’t supposed to work right with this added code than what am I missing?



Brandon

Brandon,



That is interesting. Now I am wondering is what is the descr1.product field, because as soon as you change it to descr1.product_code, then you will not be searching on the descr1.product field, it will be descr1.product_code.



So wondering now what is the descr1.product??? Anyone know?



For now I am going to change it and test a little.

HA!



Ok, thanks Brandon. I was making something out of nothing, because I was worried about my site. I kind of combined what you said, with my worrying and came up with this. Change this line:



if ($params['pname'] == 'Y') {
$tmp .= db_quote(" OR descr1.product LIKE ?l", "%$piece%");
}




to this:



if ($params['pname'] == 'Y') {
$tmp .= db_quote(" OR descr1.product LIKE ?l", "%$piece%");
$tmp .= db_quote(" OR products.product_code LIKE ?s", "%$piece%");
}




That way now it searches by descr1.product and products.product_code Awesome so now it does both!



Man, I am kind of mad at myself for not doing this earlier, but I hope this helps folks in the future.