Osclass forums
Development => Development => Topic started by: Sophia_OS on January 08, 2018, 04:39:30 am
-
Hi everyone,
i wanna search custom field's value in website's main search box, not with its own box.
for example if there is a custom field (color) and its value is "red" and "blue" and "green" , if you search "blue" in the website's main search box, it shows this item in searched list too.
thank you
theme bender
-
its possible by doing as plugin.. post on job section.. dev\s can help you
-
its possible by doing as plugin.. post on job section.. dev\s can help you
@fre2mansur
Thank you for your reply,
Nobody helps us here for free to do this?
-
EDIT These hooks are deprecated
Try adding the custom field's values to the end of the description before sending it to the db when the item is saved. There are some hooks: pre_item_add and pre_item_edit
-
Sorry, pre_item_edit and pre_item_add are deprecated .
use item_add_prepare_data and item_edit_prepare_data instead
In your theme's functions.php file, add to the end
EDITED I reversed the mc_edit_filter_description($aItem) and mc_add_filter_description($aItem) functions
I splitted mc_add_metas in mc_add_metas_item_edit and mc_add_metas_item_add
<?php
function endsWith($haystack, $needle)
{
$length = strlen($needle);
return $length === 0 ||
(substr($haystack, -$length) === $needle);
}
function mc_add_metas_item_add($desc, $aItem) {
$_meta = Field::newInstance()->findByCategory($aItem['catId']);
$meta = Params::getParam("meta");
foreach($_meta as $_m) {
$meta[$_m['pk_i_id']] = (isset($meta[$_m['pk_i_id']]))?$meta[$_m['pk_i_id']]:'';
}
$d = '\n\n ';
$mField = Field::newInstance();
foreach($meta as $k => $v) {
$field = $mField->findByPrimaryKey($k);
$d = $d . $field['s_name'] .': ' .$v. '\n';
}
if(endsWith($desc, $d))
return $desc;
else return $desc . $d;
}
function mc_add_metas_item_edit($desc, $itemId) {
$metas = Item::newInstance()->metaFields($item_Id);
$d = '\n\n ';
foreach($metas as $m) {
$d = $d . $m["s_name"] .': ' .$m["s_value"] . '\n';
}
if(endsWith($desc, $d))
return $desc;
else return $desc . $d;
}
function mc_edit_filter_description($aItem) {
foreach(@$aItem['description'] as $key => $value) {
$aItem['description'][$key] = mc_add_metas_item_edit($value,$aItem['idItem']);
}
return $aItem;
}
function mc_add_filter_description($aItem) {
foreach(@$aItem['description'] as $key => $value) {
$aItem['description'][$key] = mc_add_metas_item_add($value,$aItem);
}
return $aItem;
}
osc_add_filter('item_add_prepare_data', 'mc_add_filter_description');
osc_add_filter('item_edit_prepare_data', 'mc_edit_filter_description');
?>
or if you don't want the custom field's name there remove
$m["s_name"] .': ' .
and
$field['s_name'] .': ' .
After this you must update the descriptions in your db by editing and saving each item.
Step 2
You would want to remove the added text from description when displaying the description to the public and to the owner when it edits hi's item.
You can do that with a function
Put this before the above code in functions.php
<?php
function mc_hide_metas($desc, $itemId) {
$metas = Item::newInstance()->metaFields($item_Id);
$d = '\n\n ';
foreach($metas as $m) {
$d = $d . $m["s_name"] .': ' .$m["s_value"] . '\n';
}
if(endsWith($desc, $d))
return str_replace($d,'',$desc);
else return $desc;
}
?>
or if you don't want the custom field's name there remove
$m["s_name"] .': ' .
and call this function where the description is shown. Have a look here https://stackoverflow.com/questions/43015613/how-to-modify-ft-min-word-len-4-to-ft-min-word-len-1-so-that-osclass-3-7-1-can-s
And see where I call 'removeunderline(' for description.
If you do this admin and user side the solution will work if the item is edited and it's category is changed and or it's custom fields are changed.
If the admin makes the editing and the above function can't be called from oc-admin/themes/modern... files, the last function from above must be placed in /oc-includes/osclass/helpers/hSearch.php and removed from functions.php file.
-
This is a related solution for including category tree to the main search's results.
https://stackoverflow.com/questions/44529922/search-shows-nothing-if-user-types-category-name-in-search-bar-in-osclass/48318427#48318427
Anyway I think that including custom fields values to the search results is better than categories names.
Maybe someone can solve the above question mark about the itemId marked with red.
-
Here, https://forums.osclass.org/3-5-x/custom-field-search-when-'all-categories'/msg159218/#msg159218
Teseo said something about
DBCommandClass
It's in DBCommandClass.php
Variable "dao" is assigned in DAO.php as an instance of DBCommandClass class:
$this->dao = new DBCommandClass($data);
Regards
How to get the item id then?
$itemId = $this->manager->dao->insertedId();
-
@marius-ciclistu
Thank you very much for helping,
Is there a way just by a function in function.php? And not to make mess with description?
-
From what I know, the search is made in the indexes made in db from title and description, so this is the easiest way to not slow down the search queries.
Maybe others have a better idea. Consider ft_min_word_len =1 if you have custom fields made up from only 1character.
Maybe others could help with indexing metas and extend the search on them also.
https://doc.osclass.org/Fine-Tuning_MySQL_Full-Text_Search_-_Improving_search
-
Now that I think about it, mc_add_metas($desc, $itemId) will not work when posting a new add....
because by the time the filter runs,
$metas = Item::newInstance()->metaFields($item_Id);
won't return nothing..
hmm how to get those metas...
I gues like this:
$_meta = Field::newInstance()->findByCategory($aItem['catId']);
$meta = Params::getParam("meta");
EDIT.
I modified the solution. I think now it should work also for item-add.
-
I would implemet this on my site also but from my point of view it has no sense. You search for something and then you can filter your search via search-sidebar after the custom fields values.
-
I would implemet this on my site also but from my point of view it has no sense. You search for something and then you can filter your search via search-sidebar after the custom fields values.
:'(
-
Anyway I'm curious if there is a better solution than this, without slowing down the search query.
EDIT.
How many items does the site have?
-
Anyway I'm curious if there is a better solution than this, without slowing down the search query.
EDIT.
How many items does the site have?
More than 1,000,000 items
-
Nice job :)
If nobody comes with a bether solution for searching in metas too, then a cron job could be made to update all items' descriptions in groups by their ids each hour (to avoid updating them all at once).
-
Nice job :)
If nobody comes with a bether solution for searching in metas too, then a cron job could be made to update all items' descriptions in groups by their ids each hour (to avoid updating them all at once).
Thank you but i think we should find another way. Because with this way we have to edit all of descriptions and this is not good. Editing users items description is not good without a reason.
Solving this is easy for some Users here in this forum. But they don't want to help. Or they do if we pay.
Please you find another way and im working on other way now, i will let you know soon. And you update here if you find a way before me. Thanks
-
Another way would be to index the metas in db just like title and description are indexed and adjust the query to search also in those flelds...but:
1.You would have to regenerate the indexes in db anyway for all the items.(this also if you change the description via sql without editing the item)
2.The metas are stored in meta_fields table and the item's metas in item_meta table, so you should index the columns s_value, fk_i_field_id and fk_i_item_id from the last and s_name from the first table depending by fk_i_field_id column from the above first table.
The easiest way would be to query directly into these tables without using mysql fulltext search . That would impact your query times and server load.
-
Have you received other solutions for this? ( I saw that olx has this finctionality)
-
Have you received other solutions for this? ( I saw that olx has this finctionality)
@marius-ciclistu
Not yet, but I'm working on this. I will let you know when i completely solve it.
Who is olx? He knows the solution? Please ask him to share with us.
-
Olx is a big classifields site that acts in some european countries. :)
-
Olx is a big classifields site that acts in some european countries. :)
:D
With olx we can make a free classified website like osclass? And it has that ability to search both in items and custom-fiels in one text-box?
Please give me more information about this. Thanks.
-
:)) no man:)) It's a big company that has limits on free ads. That is why I discovered osclass.
-
:)) no man:)) It's a big company that has limits on free ads. That is why I discovered osclass.
;D
-
Have you received other solutions for this? ( I saw that olx has this finctionality)
@marius-ciclistu
hey, did you find a solution for this?
-
I didn't.
-
I didn't.
-
Another way would be to index the metas in db just like title and description are indexed and adjust the query to search also in those flelds...but:
1.You would have to regenerate the indexes in db anyway for all the items.(this also if you change the description via sql without editing the item)
2.The metas are stored in meta_fields table and the item's metas in item_meta table, so you should index the columns s_value, fk_i_field_id and fk_i_item_id from the last and s_name from the first table depending by fk_i_field_id column from the above first table.
The easiest way would be to query directly into these tables without using mysql fulltext search . That would impact your query times and server load.
lets work on this way
-
I don't know if changing the way the search is made is not going to have a negative inpact on your server.... osclass wasn't built to support custom fields search... in the maner it does the search.
-
.
-
@marius-ciclistu
Marius, finally i solved it by creating a function in function.php :) now its working very good. The only problem i have now, it doesn't search by location. Location in search doesn't work. Why? Can you please help me to solve this?
Put this code in your function.php
function cust_search_keyword_wildcard_with_customfield($params) {
if ($params['sPattern']) {
$mSearch = Search::newInstance();
$query_elements = (array) json_decode($mSearch->toJson());
$pattern = $query_elements['sPattern'];
$query_elements['sPattern'] = str_replace(' ', '* ', $pattern) . '*';
$mSearch->setJsonAlert($query_elements);
// Search by customfield too
$mSearch->addJoinTable(count($query_elements['tables_join']), DB_TABLE_PREFIX."t_item_meta u", "pk_i_id = u.fk_i_item_id", 'LEFT');
$aPattern = explode(' ', $pattern);
$customfieldCond = '';
foreach ($aPattern as $word) {
if ($word) $customfieldCond .= sprintf(" || u.s_value like '%%%s%%'", $word);
}
$mSearch->addConditions("1 = 1 " . $customfieldCond);
$mSearch->addGroupBy(DB_TABLE_PREFIX.'t_item.pk_i_id');
}
}
osc_add_hook('search_conditions', 'cust_search_keyword_wildcard_with_customfield', 1);
-
This will slow down your db queries because it searches directly into your table. The osclass search is made not into the table that helds the items' title and description, but in the full index generated when the item was saved. You can read more about this online.
-
In order to not loose the advantages offered by full index, you need to modify the core in order to generate full index for metas column and then modify the search to search also into that full index.
-
This will slow down your db queries because it searches directly into your table. The osclass search is made not into the table that helds the items' title and description, but in the full index generated when the item was saved. You can read more about this online.
in this function, first part keyword_wildcard is also slow down db? or just second part customfield search in function slow down db?
can you please help me to fix it to search by location too?
-
The wildcard is used on full index, it returns more results, so yes, but not so much as querying directly into the db tabes.
-
The wildcard is used on full index, it returns more results, so yes, but not so much as querying directly into the db tabes.
can you please help me to fix this function to search by location too?
why with this function it doesn't search by location?
-
I'm on my phone now. Try to var_dump();die; on a test server the whole query to see it.
-
I'm on my phone now. Try to var_dump();die; on a test server the whole query to see it.
you know what? with this function it searches the custom-fields very good. the only problem is that on search.php (modern theme) when you select a location, it doesn't find by that location.
i'm waiting for you to take a look at this function and test it with a computer. hopefully you fix that. thanks.
-
function cust_search_keyword_wildcard_with_customfield($params) {
if ($params['sPattern']) {
$mSearch = Search::newInstance();
$query_elements = (array) json_decode($mSearch->toJson());
$pattern = $query_elements['sPattern'];
$query_elements['sPattern'] = str_replace(' ', '* ', $pattern) . '*';
$mSearch->setJsonAlert($query_elements);
// Search by customfield too
$mSearch->addJoinTable(count($query_elements['tables_join']), DB_TABLE_PREFIX."t_item_meta u", "pk_i_id = u.fk_i_item_id", 'LEFT');
$aPattern = explode(' ', $pattern);
$customfieldCond = '';
foreach ($aPattern as $word) {
if ($word) $customfieldCond .= sprintf(" || u.s_value like '%%%s%%'", $word);
}
$mSearch->addConditions("1 = 1 " . $customfieldCond);
$mSearch->addGroupBy(DB_TABLE_PREFIX.'t_item.pk_i_id');
}
}
osc_add_hook('search_conditions', 'cust_search_keyword_wildcard_with_customfield', 1);
[/code]
I gues you need to add conditions for region and maybe category keys from the $params parameter. I can't test it locally. Maybe Teseo can have a look.
Also, does your filter work? Is your search returning only results from a selected category?
-
Alright, we wait for teseo to take a look at this function.
Search for custom fields is working great. The only problem is that dosnt work by selecting location in search.php (modern theme)
-
Swich to bender(put that function into functions.php) and test. If it doesn't work it's not theme related.
-
Swich to bender(put that function into functions.php) and test. If it doesn't work it's not theme related.
no its not theme related
-
I think this is the problem.
foreach ($aPattern as $word) {
if ($word) $customfieldCond .= sprintf(" || u.s_value like '%%%s%%'", $word);
}
That || ( or ) makes results show even if they don't belong to a region.
Is that the behaviour?
-
I think this is the problem.
foreach ($aPattern as $word) {
if ($word) $customfieldCond .= sprintf(" || u.s_value like '%%%s%%'", $word);
}
That || ( or ) makes results show even if they don't belong to a region.
Is that the behaviour?
Hello,
I suggest you put OR queries between braces. I've had a similar problem on one plugin I worked on, if I would do this like I did on the plugin it would look like this:
<?php
$customfieldCond = '(';
foreach ($aPattern as $word) {
if ($word) $customfieldCond .= sprintf(" || u.s_value like '%%%s%%'", $word);
}
$customfieldCond .= ')';
?>
Regards.
-
I think this is the problem.
foreach ($aPattern as $word) {
if ($word) $customfieldCond .= sprintf(" || u.s_value like '%%%s%%'", $word);
}
That || ( or ) makes results show even if they don't belong to a region.
Is that the behaviour?
but it doesn't work if i remove ||
-
I think this is the problem.
foreach ($aPattern as $word) {
if ($word) $customfieldCond .= sprintf(" || u.s_value like '%%%s%%'", $word);
}
That || ( or ) makes results show even if they don't belong to a region.
Is that the behaviour?
Hello,
I suggest you put OR queries between braces. I've had a similar problem on one plugin I worked on, if I would do this like I did on the plugin it would look like this:
<?php
$customfieldCond = '(';
foreach ($aPattern as $word) {
if ($word) $customfieldCond .= sprintf(" || u.s_value like '%%%s%%'", $word);
}
$customfieldCond .= ')';
?>
Regards.
@patrickFromCroatia
it didn't work, it even didn't find custumfields :(
-
Nevermind. I managed to install a local copy.
-
function cust_search_keyword_wildcard_with_customfield($params) {
if ($params['sPattern']) {
$mSearch = Search::newInstance();
$query_elements = (array) json_decode($mSearch->toJson());
$pattern = $query_elements['sPattern'];
$query_elements['sPattern'] = str_replace(' ', '* ', $pattern) . '*';
// Search by customfield too
$mSearch->addJoinTable(count($query_elements['tables_join']), DB_TABLE_PREFIX."t_item_meta u", "pk_i_id = u.fk_i_item_id", 'LEFT');
$aPattern = explode(' ', $pattern);
$customfieldCond = '';
foreach ($aPattern as $word) {
if ($word) $customfieldCond .= sprintf(" || u.s_value like '%%%s%%'", $word);
}
$mSearch->addConditions("1 = 1 " . $customfieldCond);
$mSearch->addGroupBy(DB_TABLE_PREFIX.'t_item.pk_i_id');
$mSearch->setJsonAlert($query_elements);
}
}
osc_add_hook('search_conditions', 'cust_search_keyword_wildcard_with_customfield', 1);
Please test.
thank you Marius, but it even didn't find customfields
-
Query without your function
string(464) "SELECT oc_t_item.*, oc_t_item.s_contact_name as s_user_name
FROM (oc_t_item)
LEFT JOIN oc_t_item_description as d ON d.fk_i_item_id = oc_t_item.pk_i_id
WHERE MATCH(d.s_title, d.s_description) AGAINST('test' IN BOOLEAN MODE)
AND ( d.fk_c_locale_code LIKE 'en_US' )
AND oc_t_item.b_enabled = 1 AND oc_t_item.b_active = 1 AND oc_t_item.b_spam = 0 AND (oc_t_item.b_premium = 1 || oc_t_item.dt_expiration >= '2018-06-19 07:45:32')
ORDER BY dt_pub_date desc
LIMIT 0, 12"
Query with your function
string(587) "SELECT oc_t_item.*, oc_t_item.s_contact_name as s_user_name
FROM (oc_t_item)
LEFT JOIN oc_t_item_description as d ON d.fk_i_item_id = oc_t_item.pk_i_id
LEFT JOIN oc_t_item_meta u ON pk_i_id = u.fk_i_item_id
WHERE MATCH(d.s_title, d.s_description) AGAINST('test*' IN BOOLEAN MODE)
AND ( d.fk_c_locale_code LIKE 'en_US' )
AND oc_t_item.b_enabled = 1 AND oc_t_item.b_active = 1 AND oc_t_item.b_spam = 0 AND (oc_t_item.b_premium = 1 || oc_t_item.dt_expiration >= '2018-06-19 07:44:53')
AND 1 = 1 || u.s_value like '%test%'
GROUP BY oc_t_item.pk_i_id
ORDER BY dt_pub_date desc
LIMIT 0, 12"
The title and description are hardcoded into
\oc-includes\osclass\model\Search.php
$this->dao->where(sprintf("MATCH(d.s_title, d.s_description) AGAINST('%s' IN BOOLEAN MODE)", $this->sPattern));
-
Also remember the ft_min_word_len variable from the server( 2, 3 or 4 as value of min characters for search).
Also the s_value column from meta table should have full text index in db.
-
still couldn't fix the function to search by location too :(
-
Of course you didn't. I wrote why. You need core changes.
-
Of course you didn't. I wrote why. You need core changes.
How? Please explain step by step. Thanks
-
If you can make s_value column full text index (and regenerate all indexes in your db), the solution would be:
/**
* Make the SQL for the search with all the conditions and filters specified
*
* @access private
* @since unknown
* @param bool $count
*/
private function _makeSQL($count = false,$premium = false)
{
$arrayConditions = $this->_conditions();
$extraFields = $arrayConditions['extraFields'];
$conditionsSQL = $arrayConditions['conditionsSQL'];
$sql = '';
if($this->withItemId) {
// add field s_user_name
$this->dao->select(sprintf('%st_item.*, %st_item.s_contact_name as s_user_name', DB_TABLE_PREFIX, DB_TABLE_PREFIX) );
$this->dao->from(sprintf('%st_item', DB_TABLE_PREFIX));
$this->dao->where('pk_i_id', (int)$this->itemId);
} else {
if($count) {
($this->withPattern) ? $this->dao->select(DB_TABLE_PREFIX.'t_item.pk_i_id, GROUP_CONCAT(u.s_value)') : $this->dao->select(DB_TABLE_PREFIX.'t_item.pk_i_id');
$this->dao->select($extraFields); // plugins!
} else {
($this->withPattern) ?
$this->dao->select(DB_TABLE_PREFIX.'t_item.*, '.DB_TABLE_PREFIX.'t_item.s_contact_name as s_user_name, GROUP_CONCAT(u.s_value)') :
$this->dao->select(DB_TABLE_PREFIX.'t_item.*, '.DB_TABLE_PREFIX.'t_item.s_contact_name as s_user_name');
$this->dao->select($extraFields); // plugins!
}
$this->dao->from(DB_TABLE_PREFIX.'t_item');
if($this->withNoUserEmail) {
$this->dao->where( DB_TABLE_PREFIX.'t_item.s_contact_email', $this->sEmail );
}
if ($this->withPattern ) {
$this->dao->join(DB_TABLE_PREFIX.'t_item_description as d','d.fk_i_item_id = '.DB_TABLE_PREFIX.'t_item.pk_i_id','LEFT');
$this->dao->join(DB_TABLE_PREFIX.'t_item_meta as u', DB_TABLE_PREFIX.'t_item.pk_i_id = u.fk_i_item_id','LEFT');
$this->dao->where(sprintf("MATCH(d.s_title, d.s_description, u.s_value) AGAINST('%s' IN BOOLEAN MODE)", $this->sPattern) );
if(empty($this->locale_code)) {
if(OC_ADMIN) {
$this->locale_code[osc_current_admin_locale()] = osc_current_admin_locale();
} else {
$this->locale_code[osc_current_user_locale()] = osc_current_user_locale();
}
}
$this->dao->where(sprintf("( d.fk_c_locale_code LIKE '%s' )", implode("' d.fk_c_locale_code LIKE '", $this->locale_code)));
}
// item conditions
if(count($this->itemConditions)>0) {
$itemConditions = implode(' AND ', osc_apply_filter('sql_search_item_conditions', $this->itemConditions));
$this->dao->where($itemConditions);
}
if( $this->withCategoryId && (count($this->categories) > 0) ) {
$this->dao->where(sprintf("%st_item.fk_i_category_id", DB_TABLE_PREFIX) .' IN ('. implode(', ', $this->categories) .')' );
}
if($this->withUserId) {
$this->_fromUser();
}
if($this->withLocations || OC_ADMIN) {
$this->dao->join(sprintf('%st_item_location', DB_TABLE_PREFIX), sprintf('%st_item_location.fk_i_item_id = %st_item.pk_i_id', DB_TABLE_PREFIX, DB_TABLE_PREFIX), 'LEFT');
$this->_addLocations();
}
if($this->withPicture) {
$this->dao->join(sprintf('%st_item_resource', DB_TABLE_PREFIX), sprintf('%st_item_resource.fk_i_item_id = %st_item.pk_i_id', DB_TABLE_PREFIX, DB_TABLE_PREFIX), 'LEFT');
$this->dao->where(sprintf("%st_item_resource.s_content_type LIKE '%%image%%' ", DB_TABLE_PREFIX, DB_TABLE_PREFIX, DB_TABLE_PREFIX));
$this->dao->groupBy(DB_TABLE_PREFIX.'t_item.pk_i_id');
}
if($this->onlyPremium) {
$this->dao->where(sprintf("%st_item.b_premium = 1", DB_TABLE_PREFIX));
}
$this->_priceRange();
// add joinTables
$this->_joinTable();
// PLUGINS TABLES !!
if( !empty($this->tables) ) {
$tables = implode(', ', $this->tables);
$this->dao->from($tables);
}
// WHERE PLUGINS extra conditions
if(count($this->conditions) > 0) {
$this->dao->where($conditionsSQL);
}
// ---------------------------------------------------------
// groupBy
if($this->groupBy != '') {
$this->dao->groupBy( $this->groupBy );
}
// having
if($this->having != '') {
$this->dao->having($this->having);
}
// ---------------------------------------------------------
// order & limit
$this->dao->orderBy( $this->order_column, $this->order_direction);
//group by
$this->dao->groupBy(DB_TABLE_PREFIX.'t_item.pk_i_id');
if($count) {
$this->dao->limit(100*$this->results_per_page);
} else {
$this->dao->limit( $this->limit_init, $this->results_per_page);
}
}
$this->sql = $this->dao->_getSelect();
// reset dao attributes
$this->dao->_resetSelect();
return $this->sql;
}
BUT THIS WON'T WORK as it is now.
-
SOLUTION
CORE MOD for searching also in custom fields values.
EDITED
Replace the function _makeSQL from
\oc-includes\osclass\model\Search.php
with this:
UPDATED TO WORK ALSO FOR "exactly these words" in custom fields.
/**
* Make the SQL for the search with all the conditions and filters specified
*
* @access private
* @since unknown
* @param bool $count
*/
private function _makeSQL($count = false,$premium = false)
{
$arrayConditions = $this->_conditions();
$extraFields = $arrayConditions['extraFields'];
$conditionsSQL = $arrayConditions['conditionsSQL'];
$sql = '';
if($this->withItemId) {
// add field s_user_name
$this->dao->select(sprintf('%st_item.*, %st_item.s_contact_name as s_user_name', DB_TABLE_PREFIX, DB_TABLE_PREFIX) );
$this->dao->from(sprintf('%st_item', DB_TABLE_PREFIX));
$this->dao->where('pk_i_id', (int)$this->itemId);
} else {
if($count) {
($this->withPattern) ? $this->dao->select(DB_TABLE_PREFIX.'t_item.pk_i_id, GROUP_CONCAT(u.s_value)') : $this->dao->select(DB_TABLE_PREFIX.'t_item.pk_i_id');
$this->dao->select($extraFields); // plugins!
} else {
($this->withPattern) ?
$this->dao->select(DB_TABLE_PREFIX.'t_item.*, '.DB_TABLE_PREFIX.'t_item.s_contact_name as s_user_name, GROUP_CONCAT(u.s_value)') :
$this->dao->select(DB_TABLE_PREFIX.'t_item.*, '.DB_TABLE_PREFIX.'t_item.s_contact_name as s_user_name');
$this->dao->select($extraFields); // plugins!
}
$this->dao->from(DB_TABLE_PREFIX.'t_item');
if($this->withNoUserEmail) {
$this->dao->where( DB_TABLE_PREFIX.'t_item.s_contact_email', $this->sEmail );
}
if ($this->withPattern ) {
$this->dao->join(DB_TABLE_PREFIX.'t_item_description as d','d.fk_i_item_id = '.DB_TABLE_PREFIX.'t_item.pk_i_id','LEFT');
$this->dao->join(DB_TABLE_PREFIX.'t_item_meta as u', DB_TABLE_PREFIX.'t_item.pk_i_id = u.fk_i_item_id','LEFT');
$customfieldCond = '';
$trimmedSPattern = trim($this->sPattern);
if (!(substr($trimmedSPattern, 0, 1) === '"' && substr($trimmedSPattern, strlen($trimmedSPattern)-1, 1) === '"')) {
$explodePattern = explode(' ', str_replace('+', '', str_replace('*', '', $trimmedSPattern)));
foreach ($explodePattern as $word) {
if ($word) $customfieldCond .= " OR u.s_value LIKE '%" . $word . "%'";
}
} else {
$customfieldCond .= " OR u.s_value LIKE '%" . trim($trimmedSPattern, '"') . "%'";
}
$this->dao->where(sprintf("(MATCH(d.s_title, d.s_description) AGAINST('%s' IN BOOLEAN MODE)", $this->sPattern) . $customfieldCond . ')');
if(empty($this->locale_code)) {
if(OC_ADMIN) {
$this->locale_code[osc_current_admin_locale()] = osc_current_admin_locale();
} else {
$this->locale_code[osc_current_user_locale()] = osc_current_user_locale();
}
}
$this->dao->where(sprintf("( d.fk_c_locale_code LIKE '%s' )", implode("' d.fk_c_locale_code LIKE '", $this->locale_code)));
}
// item conditions
if(count($this->itemConditions)>0) {
$itemConditions = implode(' AND ', osc_apply_filter('sql_search_item_conditions', $this->itemConditions));
$this->dao->where($itemConditions);
}
if( $this->withCategoryId && (count($this->categories) > 0) ) {
$this->dao->where(sprintf("%st_item.fk_i_category_id", DB_TABLE_PREFIX) .' IN ('. implode(', ', $this->categories) .')' );
}
if($this->withUserId) {
$this->_fromUser();
}
if($this->withLocations || OC_ADMIN) {
$this->dao->join(sprintf('%st_item_location', DB_TABLE_PREFIX), sprintf('%st_item_location.fk_i_item_id = %st_item.pk_i_id', DB_TABLE_PREFIX, DB_TABLE_PREFIX), 'LEFT');
$this->_addLocations();
}
if($this->withPicture) {
$this->dao->join(sprintf('%st_item_resource', DB_TABLE_PREFIX), sprintf('%st_item_resource.fk_i_item_id = %st_item.pk_i_id', DB_TABLE_PREFIX, DB_TABLE_PREFIX), 'LEFT');
$this->dao->where(sprintf("%st_item_resource.s_content_type LIKE '%%image%%' ", DB_TABLE_PREFIX, DB_TABLE_PREFIX, DB_TABLE_PREFIX));
$this->dao->groupBy(DB_TABLE_PREFIX.'t_item.pk_i_id');
}
if($this->onlyPremium) {
$this->dao->where(sprintf("%st_item.b_premium = 1", DB_TABLE_PREFIX));
}
$this->_priceRange();
// add joinTables
$this->_joinTable();
// PLUGINS TABLES !!
if( !empty($this->tables) ) {
$tables = implode(', ', $this->tables);
$this->dao->from($tables);
}
// WHERE PLUGINS extra conditions
if(count($this->conditions) > 0) {
$this->dao->where($conditionsSQL);
}
// ---------------------------------------------------------
// groupBy
if($this->groupBy != '') {
$this->dao->groupBy( $this->groupBy );
}
// having
if($this->having != '') {
$this->dao->having($this->having);
}
// ---------------------------------------------------------
// order & limit
$this->dao->orderBy( $this->order_column, $this->order_direction);
//group by
$this->dao->groupBy(DB_TABLE_PREFIX.'t_item.pk_i_id');
if($count) {
$this->dao->limit(100*$this->results_per_page);
} else {
$this->dao->limit( $this->limit_init, $this->results_per_page);
}
}
$this->sql = $this->dao->_getSelect();
// reset dao attributes
$this->dao->_resetSelect();
return $this->sql;
}
This will not be affected by ft_min_word_len value in custom fields' regard.
This will work with Teseo's solutions for searching all the words from the pattern(+) and wildcard (*)
Remove the last part from your functions file(the one about the custom fields).
-
SOLUTION
CORE MOD for searching also in custom fields values.
Replace the function _makeSQL from
\oc-includes\osclass\model\Search.php
with this:
/**
* Make the SQL for the search with all the conditions and filters specified
*
* @access private
* @since unknown
* @param bool $count
*/
}
This will not be affected by ft_min_word_len value in custom fields' regard.
This will work with Teseo's solutions for searching all the words from the pattern(+) and wildcard (*)
Remove the last part from your functions file(the one about the custom fields).
@Marius,
Thank you for the code, but i didn't work for me :( did you test it on modern theme?
-
No. It gives some errors or what is the behaviour?
Did you remove that function from functions.php?
-
No. It gives some errors or what is the behaviour?
Did you remove that function from functions.php?
No errors.
It doesn't even find title and description search.
I tested with that function and also without that function and also removed custom fields part and tested but in all ways it searches nothing.
-
I'll test it again in the morning then.
-
I'll test it again in the morning then.
Thanks
-
I edited my solution and tested it. It workes on bender. It had some issue with sprintf function and I used another method.
Please update or delete your quote with the unworking solution.
-
Thank you very much Marius ;) now its working.
i don't wanna close the topic and work on making this through function.php
because this is a core edit and its better to be in function.php
thank you again marius
-
You won't do it via hooks. It's not possible.
Edit, anyway, by searching into custom fields the speed of the search is reduced.
-
You won't do it via hooks. It's not possible.
Edit, anyway, by searching into custom fields the speed of the search is reduced.
with your code also speed of search reduces?
-
With my first solution the speed is not reduced, but with this core mod it is.
-
With my first solution the speed is not reduced, but with this core mod it is.
which one is your first solution?
-
From the begining of this topic. Putting custom fields values into the description before save and removing them before displaying the description in view.
-
From the begining of this topic. Putting custom fields values into the description before save and removing them before displaying the description in view.
I'm working to find a way to do this in function.php
I will update here as soon as i find a solution
-
please help me to do this,
i explained in the first post of this topic
thanks to @marius-ciclistu that solved this by editing core files here:
https://forums.osclass.org/development/please-help-to-do-this/msg163268/#msg163268
but i'm trying to do this by hook in functions.php, please help me to do this thanks,
-
You can search on google marius ciclistu ft_min_word_len and see the search core mods to see how I edited there the description before save and before displaying it with addunderline and removeunderline functions.
-
You can search on google marius ciclistu ft_min_word_len and see the search core mods to see how I edited there the description before save and before displaying it with addunderline and removeunderline functions.
Hey Marius, but im trying to do it in functions.php!
Did you updated that code since then? Or its the same code? If you updated please give me to update the code too thanksss
-
I did not update it but there are hooks for editing the item before saving it. Teseo gave me the hook solution for that.
-
I did not update it but there are hooks for editing the item before saving it. Teseo gave me the hook solution for that.
Would you please share with us those hooks?
-
osc_add_filter('item_add_prepare_data', 'cust_filter_title_description');
osc_add_filter('item_edit_prepare_data', 'cust_filter_title_description');
?>
https://stackoverflow.com/questions/43015613/how-to-modify-ft-min-word-len-4-to-ft-min-word-len-1-so-that-osclass-3-7-1-can-s
-
osc_add_filter('item_add_prepare_data', 'cust_filter_title_description');
osc_add_filter('item_edit_prepare_data', 'cust_filter_title_description');
?>
https://stackoverflow.com/questions/43015613/how-to-modify-ft-min-word-len-4-to-ft-min-word-len-1-so-that-osclass-3-7-1-can-s
Is this code related to custom-field search you have solved in this post
:?
https://forums.osclass.org/development/please-help-to-do-this/msg163268/#msg163268
-
You said you wanted to add the custom fields into the description. This is the way to do it. Make 2 functions to add and remove them from description. This is a model.
-
You said you wanted to add the custom fields into the description. This is the way to do it. Make 2 functions to add and remove them from description. This is a model.
Yes i want to add custom-fields into title and description by hook in functions.php
But in that link they are talking about minimum word len!
-
It does not mater. the purpose is the same. That is a hack to leave the ft_min_word_len as it is (4 for example) but to enable the user to search by min 1 character. If you read there it is written.
Leave the title out of it. You need only to add them into description, at its end. You can put a sign like ----custom_fields---- or any other sign before them.
Example:
Description:
Bla bla bla ----custom_fields---- valuea : 225 , valueb : 35 , valuea1 : 225 , valueb1 : 40
When you display the description to the public, you run removeCustomFields($description);
When you save the item, you run addCustomFields($description).
You have there my example. If you can't do it by your self and no one is willing to help, you can pay a developer to do it.
-
It does not mater. the purpose is the same. That is a hack to leave the ft_min_word_len as it is (4 for example) but to enable the user to search by min 1 character. If you read there it is written.
Leave the title out of it. You need only to add them into description, at its end. You can put a sign like ----custom_fields---- or any other sign before them.
Example:
Description:
Bla bla bla ----custom_fields---- valuea : 225 , valueb : 35 , valuea1 : 225 , valueb1 : 40
When you display the description to the public, you run removeCustomFields($description);
When you save the item, you run addCustomFields($description).
You have there my example. If you can't do it by your self and no one is willing to help, you can pay a developer to do it.
Now i got you :D I think this way is good to do. Lets do it. You try on your end and i try on my end. Whoever finishs the code earlier update this topic. Thanks
-
osc_add_filter('item_add_prepare_data', 'cust_filter_title_description');
osc_add_filter('item_edit_prepare_data', 'cust_filter_title_description');
?>
https://stackoverflow.com/questions/43015613/how-to-modify-ft-min-word-len-4-to-ft-min-word-len-1-so-that-osclass-3-7-1-can-s
@marius-ciclistu
By the way, i can search with min 3 characters or 2 or 1
I can search even with one character and it shows the result.
-
Then your ft_min_word_len is 1...that is not so good if you get many requests.... if you search 'a' you realize that the results will contain all the items.
-
Then your ft_min_word_len is 1...that is not so good if you get many requests.... if you search 'a' you realize that the results will contain all the items.
Yes. What is the proper way? How can i change it to standard way?
But if min 1 character is bad why are you trying to make minimum less than 4 characters on stackoverflow.com ?
-
Shared hosting is cheaper.
-
Then your ft_min_word_len is 1...that is not so good if you get many requests.... if you search 'a' you realize that the results will contain all the items.
1. Yes. What is the proper way? How can i change it to standard way?
2. But if min 1 character is bad why are you trying to make minimum less than 4 characters on stackoverflow.com ?
Answer this please!
-
I did. Shared hosting has 4.
-
Nope. Mine is on shared hosting and is 1 minimum search word. And i don't know why is 1 min. I use teseos search function for multiple languages, maybe that function makes it 1 min search word.
I did. Shared hosting has 4.
-
@marius-ciclistu
what is the main differences between these 3 solutions?
as far as i know 2nd solution makes the search and server slow, right? if yes, for not making slow, 1st solution is good or 3rd solution?
First solution:
https://forums.osclass.org/development/please-help-to-do-this/msg159748/#msg159748
Second solution: (core)
https://forums.osclass.org/development/please-help-to-do-this/msg163268/#msg163268
Third solution: (adding custom-fields to description) (on progress!)
https://forums.osclass.org/development/please-help-to-do-this/msg167476/#msg167476
-
Now I see, I already gave you your so called 3rd solution into the first one. I forgot.
What more do you want?
First is faser than second in terms of searching because the search in description is full text search.
-
Now I see, I already gave you your so called 3rd solution into the first one. I forgot.
What more do you want?
First is faser than second in terms of searching because the search in description is full text search.
:D so first solution and third solution is the same!
And you recommend first solution because its faster and safe and has no bug!
Let me test the first solution and let you know!
Thanks Marius,
-
I did not test them.
-
@marius-ciclistu
i did everything you explained in the first solution but did not work! : (bender)
it just adds "\n\n" to the: Table: oc_t_item_description -> s_description
-
Are you sure that item has custom fields?
-
Are you sure that item has custom fields?
Yes!
-
@marius-ciclistu
now i added mc_hide_metas() before main function in functions.php and it worked!
and in item-post.php i put this: <?php ItemForm::description_textarea('description',osc_current_user_locale(), osc_esc_html( mc_hide_metas(bender_item_description(), osc_item_id()) )); ?>
but now there is a few problems,
1. what should i do to put only custom-fields that has value! because it put all the custom-fields in description!
2. it doesn't remove custom-fields when i see a listing or edit a listing!
3. when i edit the item, and edit custom-fields, it does not update custom-fields in description!
Thanks,
-
Use just like in item post, the hide metas in the other 2 places.
You see? If you want you can do it yourself:)
To remove the empty metas, search in google how to test array value or any other question you have, and you will learn to do it your self:)
Follow removeunderline from my ft min word len solution to find the places where you should hide metas.
-
@marius-ciclistu
I have a question about your second solution!
Can i ask?
-
Can you?:)
-
@marius-ciclistu
Thank you very much!
With your second solution everything work good. It has only one problem. When i search for example ( android phone ), it shows the results of all title and description and also custom-fields. which is good. But when i search ( "android phone" ), it only shows the results of title and description. But dosnt include the custom-fields search in the result.
How can i fix this to include also custom-fields search in the result when i use double quotation marks?
By the way, double quotation marks is for searching the exact phrase.
And also let you know that i'm using Teseo's (wildcard) and (search in all languages) functions.
Thank you!
-
Those work or worked in google. I think osclass searches for "android and phone" , so the quotes are included in the word. If there is that functionality in your code maybe you don't have andoid phone as a custom field value.
-
@marius-ciclistu
Osclass has this functionality! Like google.
I tried also on osclass general demo and worked:
( have for sale ):
https://demo.osclass.org/general/search/pattern,have+for+sale
( "have for sale" ):
https://demo.osclass.org/general/search/pattern,%22have+for+sale%22
Please try these url above and see that is working.
I do have (android phone) in my custom-fields. And it shows in my search results if i search without double quotes.
-
https://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html
In the bottom of the page.
That means that maybe the custom fields are searched with the words containing the " characters, as they are not full text search columns (https://doc.osclass.org/Fine-Tuning_MySQL_Full-Text_Search_-_Improving_search)
-
@marius-ciclistu
If you test your solution number2, you can see that search method for both (title, description) and (custom-fields) are the same. Check the core file.
I think we could fix this by editing the _makeSQL function!
Please take a look at this code that you gave us. And see if you could fix by editing the _makeSQL function:
https://forums.osclass.org/development/please-help-to-do-this/msg163268/#msg163268
-
I updated the solution from theme.
mods are
$customfieldCond = '';
$trimmedSPattern = trim($this->sPattern);
if (!(substr($trimmedSPattern, 0, 1) === '"' && substr($trimmedSPattern, strlen($trimmedSPattern)-1, 1) === '"')) {
$explodePattern = explode(' ', str_replace('+', '', str_replace('*', '', $trimmedSPattern)));
foreach ($explodePattern as $word) {
if ($word) $customfieldCond .= " OR u.s_value LIKE '%" . $word . "%'";
}
} else {
$customfieldCond .= " OR u.s_value LIKE '%" . trim($trimmedSPattern, '"') . "%'";
}
-
Sorry i didn't understand. Where should i put this code? Please explain. Thanks
-
https://forums.osclass.org/development/please-help-to-do-this/msg163268/#msg163268
-
https://forums.osclass.org/development/please-help-to-do-this/msg163268/#msg163268
Did you update this code? If yes, i replaced this code with mine but didn't work!
-
I wrote with red that I updated it.
Try to focus on the part that I changed and see why it is not working.
-
I wrote with red that I updated it.
Try to focus on the part that I changed and see why it is not working.
I tried but couldn't fix it! Please help to fix this code. Thanks
-
What is not working?
-
What is not working?
My first question. When i put the search inside double quotes it dosnt show the custom-fields results
https://forums.osclass.org/development/please-help-to-do-this/msg169559/#msg169559
-
are you shure that the custom field is stored in db exactly as you wrote it? I mean "word1 word2" ?
The cript does just that. If the value of the custom field is "word1 word2" it should work. If the name is word 1 and the valie word 2 it will not work.