Index: branches/RC/core/units/general/cat_event_handler.php
===================================================================
diff -u -r9363 -r9398
--- branches/RC/core/units/general/cat_event_handler.php (.../cat_event_handler.php) (revision 9363)
+++ branches/RC/core/units/general/cat_event_handler.php (.../cat_event_handler.php) (revision 9398)
@@ -1072,15 +1072,19 @@
$this->Application->RemoveVar('keywords');
$this->Application->RemoveVar('Search_Keywords');
- $sql = ' SELECT * FROM '.$this->Application->getUnitOption('confs', 'TableName').'
- WHERE ModuleName="In-Commerce"
- AND AdvancedSearch=1';
+ $module_name = $this->Application->findModule('Var', $event->Prefix, 'Name');
+
+ $sql = 'SELECT *
+ FROM '.$this->Application->getUnitOption('confs', 'TableName').'
+ WHERE (ModuleName = '.$this->Conn->qstr($module_name).') AND (AdvancedSearch = 1)';
$search_config = $this->Conn->Query($sql);
+
$lang = $this->Application->GetVar('m_lang');
$object =& $event->getObject();
$object->SetPage(1);
- $product_table = $this->Application->getUnitOption('p', 'TableName');
+ $items_table = $this->Application->getUnitOption($event->Prefix, 'TableName');
+
$search_keywords = $this->Application->GetVar('value'); // will not be changed
$keywords = $this->Application->GetVar('value'); // will be changed down there
@@ -1095,25 +1099,19 @@
$highlight_keywords = Array();
$relevance_parts = Array();
- $condition_patterns = Array( 'any' => '%s LIKE %s',
- 'contains' => '%s LIKE %s',
- 'notcontains' => '(NOT (%1$s LIKE %2$s) OR %1$s IS NULL)',
- 'is' => '%s = %s',
- 'isnot' => '(%1$s != %2$s OR %1$s IS NULL)');
-
$alias_counter = 0;
$custom_fields = $this->Application->getUnitOption($event->Prefix, 'CustomFields');
if ($custom_fields) {
$custom_table = $this->Application->getUnitOption($event->Prefix.'-cdata', 'TableName');
- $join_clauses[] = ' LEFT JOIN '.$custom_table.' custom_data ON '.$product_table.'.ResourceId = custom_data.ResourceId';
+ $join_clauses[] = ' LEFT JOIN '.$custom_table.' custom_data ON '.$items_table.'.ResourceId = custom_data.ResourceId';
}
$search_log = '';
$weight_sum = 0;
+
// processing fields and preparing conditions
- foreach($search_config as $record)
- {
+ foreach ($search_config as $record) {
$field = $record['FieldName'];
$join_clause = '';
$condition_mode = 'WHERE';
@@ -1158,7 +1156,7 @@
$field_name = $alias.'.'.$exploded[1];
$join_clause = str_replace('{ForeignTable}', $alias, $record['JoinClause']);
- $join_clause = str_replace('{LocalTable}', $product_table, $join_clause);
+ $join_clause = str_replace('{LocalTable}', $items_table, $join_clause);
if($record['CustomFieldId'])
{
@@ -1179,142 +1177,33 @@
$field_name = $local_table.'.'.$field_name;
}
- $condition = '';
- switch($record['FieldType'])
- {
- case 'select':
- $keywords[$field] = unhtmlentities( $keywords[$field] );
- $condition = sprintf($condition_patterns['is'], $field_name, $this->Conn->qstr( $keywords[$field] ));
- break;
-
- case 'text':
- $keywords[$field] = unhtmlentities( $keywords[$field] );
-
- if(strlen($keywords[$field]) >= $this->Application->ConfigValue('Search_MinKeyword_Length'))
- {
- $highlight_keywords[] = $keywords[$field];
- if( in_array($verbs[$field], Array('any', 'contains', 'notcontains')) )
- {
- $keywords[$field] = '%'.strtr($keywords[$field], Array('%' => '\\%', '_' => '\\_')).'%';
- }
- $condition = sprintf( $condition_patterns[$verbs[$field]],
- $field_name,
- $this->Conn->qstr( $keywords[$field] ));
- }
- break;
-
- case 'boolean':
- if($keywords[$field] != -1)
- {
- $property_mappings = $this->Application->getUnitOption($event->Prefix, 'ItemPropertyMappings');
- switch($field)
- {
- case 'HotItem':
- $hot_limit_var = getArrayValue($property_mappings, 'HotLimit');
- if($hot_limit_var)
- {
- $sql = 'SELECT Data FROM '.TABLE_PREFIX.'Cache WHERE VarName="'.$hot_limit_var.'"';
- $hot_limit = (int)$this->Conn->GetOne($sql);
- $condition = 'IF('.$product_table.'.HotItem = 2,
- IF('.$product_table.'.Hits >= '.
- $hot_limit.
- ', 1, 0), '.$product_table.'.HotItem) = '.$keywords[$field];
- }
- break;
- case 'PopItem':
- $votes2pop_var = getArrayValue($property_mappings, 'VotesToPop');
- $rating2pop_var = getArrayValue($property_mappings, 'RatingToPop');
- if($votes2pop_var && $rating2pop_var)
- {
- $condition = 'IF('.$product_table.'.PopItem = 2, IF('.$product_table.'.CachedVotesQty >= '.
- $this->Application->ConfigValue($votes2pop_var).
- ' AND '.$product_table.'.CachedRating >= '.
- $this->Application->ConfigValue($rating2pop_var).
- ', 1, 0), '.$product_table.'.PopItem) = '.$keywords[$field];
- }
- break;
- case 'NewItem':
- $new_days_var = getArrayValue($property_mappings, 'NewDays');
- if($new_days_var)
- {
- $condition = 'IF('.$product_table.'.NewItem = 2,
- IF('.$product_table.'.CreatedOn >= (UNIX_TIMESTAMP() - '.
- $this->Application->ConfigValue($new_days_var).
- '*3600*24), 1, 0), '.$product_table.'.NewItem) = '.$keywords[$field];
- }
- break;
- case 'EditorsPick':
- $condition = $product_table.'.EditorsPick = '.$keywords[$field];
- break;
- }
- }
- break;
-
- case 'range':
- $range_conditions = Array();
- if($keywords[$field.'_from'] && !preg_match("/[^0-9]/i", $keywords[$field.'_from']))
- {
- $range_conditions[] = $field_name.' >= '.$keywords[$field.'_from'];
- }
- if($keywords[$field.'_to'] && !preg_match("/[^0-9]/i", $keywords[$field.'_to']))
- {
- $range_conditions[] = $field_name.' <= '.$keywords[$field.'_to'];
- }
- if($range_conditions)
- {
- $condition = implode(' AND ', $range_conditions);
- }
- break;
-
- case 'date':
- if($keywords[$field])
- {
- if( in_array($keywords[$field], Array('today', 'yesterday')) )
- {
- $current_time = getdate();
- $day_begin = adodb_mktime(0, 0, 0, $current_time['mon'], $current_time['mday'], $current_time['year']);
- $time_mapping = Array('today' => $day_begin, 'yesterday' => ($day_begin - 86400));
- $min_time = $time_mapping[$keywords[$field]];
- }
- else
- {
- $time_mapping = Array( 'last_week' => 604800, 'last_month' => 2628000,
- 'last_3_months' => 7884000, 'last_6_months' => 15768000,
- 'last_year' => 31536000
- );
- $min_time = adodb_mktime() - $time_mapping[$keywords[$field]];
- }
- $condition = $field_name.' > '.$min_time;
- }
- break;
+ $condition = $this->getAdvancedSearchCondition($field_name, $record, $keywords, $verbs, $highlight_keywords);
+ if ($record['CustomFieldId'] && strlen($condition)) {
+ // search in primary value of custom field + value in current language
+ $field_name = $local_table.'.'.'l'.$this->Application->GetDefaultLanguageId().'_cust_'.array_search($field, $custom_fields);
+ $primary_condition = $this->getAdvancedSearchCondition($field_name, $record, $keywords, $verbs, $highlight_keywords);
+ $condition = '('.$condition.' OR '.$primary_condition.')';
}
- if($condition)
- {
- if($join_clause)
- {
+ if ($condition) {
+ if ($join_clause) {
$join_clauses[] = $join_clause;
}
+
$relevance_parts[] = 'IF('.$condition.', '.$record['Priority'].', 0)';
- if($glues[$field] == 1) // and
- {
- if($condition_mode == 'WHERE')
- {
+ if ($glues[$field] == 1) { // and
+ if ($condition_mode == 'WHERE') {
$and_conditions[] = $condition;
}
- else
- {
+ else {
$and_having_conditions[] = $condition;
}
}
- else // or
- {
- if($condition_mode == 'WHERE')
- {
+ else { // or
+ if ($condition_mode == 'WHERE') {
$or_conditions[] = $condition;
}
- else
- {
+ else {
$or_having_conditions[] = $condition;
}
}
@@ -1325,18 +1214,21 @@
}
}
- $search_log = implode('
', $search_log);
- $search_log = preg_replace('/(.*) '.preg_quote($this->Application->Phrase('lu_and'), '/').'|'.preg_quote($this->Application->Phrase('lu_or'), '/').'$/is', '\\1', $search_log);
- $this->saveToSearchLog($search_log, 1); // advanced search
+ if ($search_log) {
+ $search_log = implode('
', $search_log);
+ $search_log = preg_replace('/(.*) '.preg_quote($this->Application->Phrase('lu_and'), '/').'|'.preg_quote($this->Application->Phrase('lu_or'), '/').'$/is', '\\1', $search_log);
+ $this->saveToSearchLog($search_log, 1); // advanced search
+ }
$this->Application->StoreVar('highlight_keywords', serialize($highlight_keywords));
// making relevance clause
if($relevance_parts)
{
- $rel_keywords = $this->Application->ConfigValue('SearchRel_Keyword_products') / 100;
- $rel_pop = $this->Application->ConfigValue('SearchRel_Pop_products') / 100;
- $rel_rating = $this->Application->ConfigValue('SearchRel_Rating_products') / 100;
+ $conf_postfix = $this->Application->getUnitOption($event->Prefix, 'SearchConfigPostfix');
+ $rel_keywords = $this->Application->ConfigValue('SearchRel_Keyword_'.$conf_postfix) / 100;
+ $rel_pop = $this->Application->ConfigValue('SearchRel_Pop_'.$conf_postfix) / 100;
+ $rel_rating = $this->Application->ConfigValue('SearchRel_Rating_'.$conf_postfix) / 100;
$relevance_clause = '('.implode(' + ', $relevance_parts).') / '.$weight_sum.' * '.$rel_keywords;
$relevance_clause .= ' + (Hits + 1) / (MAX(Hits) + 1) * '.$rel_pop;
$relevance_clause .= ' + (CachedRating + 1) / (MAX(CachedRating) + 1) * '.$rel_rating;
@@ -1359,7 +1251,7 @@
{
$and_conditions[] = '('.implode(' OR ', $or_conditions).')';
}
-// $and_conditions[] = $product_table.'.Status = 1';
+// $and_conditions[] = $items_table.'.Status = 1';
$where_clause = implode(' AND ', $and_conditions);
if(!$where_clause)
{
@@ -1373,29 +1265,163 @@
$this->Application->SetVar('adv_search_error', 1);
}
}
- $where_clause .= ' AND '.$product_table.'.Status = 1';
+ $where_clause .= ' AND '.$items_table.'.Status = 1';
// building final search query
$search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$this->Conn->Query('DROP TABLE IF EXISTS '.$search_table);
+ $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
+ $fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
+ $pick_field = isset($fields['EditorsPick']) ? $items_table.'.EditorsPick' : '0';
+
$sql = ' CREATE TABLE '.$search_table.'
SELECT '.$relevance_clause.' AS Relevance,
- '.$product_table.'.ProductId AS ItemId,
- '.$product_table.'.ResourceId AS ResourceId,
+ '.$items_table.'.'.$id_field.' AS ItemId,
+ '.$items_table.'.ResourceId AS ResourceId,
11 AS ItemType,
- '.$product_table.'.EditorsPick AS EdPick
- FROM '.$product_table.'
+ '.$pick_field.' AS EdPick
+ FROM '.$items_table.'
'.implode(' ', $join_clauses).'
WHERE '.$where_clause.'
- GROUP BY '.$product_table.'.ProductId'.
+ GROUP BY '.$items_table.'.'.$id_field.
$having_clause;
$res = $this->Conn->Query($sql);
}
+ function getAdvancedSearchCondition($field_name, $record, $keywords, $verbs, &$highlight_keywords)
+ {
+ $field = $record['FieldName'];
+ $condition_patterns = Array (
+ 'any' => '%s LIKE %s',
+ 'contains' => '%s LIKE %s',
+ 'notcontains' => '(NOT (%1$s LIKE %2$s) OR %1$s IS NULL)',
+ 'is' => '%s = %s',
+ 'isnot' => '(%1$s != %2$s OR %1$s IS NULL)'
+ );
+
+ $condition = '';
+ switch ($record['FieldType']) {
+ case 'select':
+ $keywords[$field] = unhtmlentities( $keywords[$field] );
+ if ($keywords[$field]) {
+ $condition = sprintf($condition_patterns['is'], $field_name, $this->Conn->qstr( $keywords[$field] ));
+ }
+ break;
+
+ case 'multiselect':
+ $keywords[$field] = unhtmlentities( $keywords[$field] );
+ if ($keywords[$field]) {
+ $condition = Array ();
+ $values = explode('|', substr($keywords[$field], 1, -1));
+ foreach ($values as $selected_value) {
+ $condition[] = sprintf($condition_patterns['contains'], $field_name, $this->Conn->qstr('%|'.$selected_value.'|%'));
+ }
+ $condition = '('.implode(' OR ', $condition).')';
+ }
+ break;
+
+ case 'text':
+ $keywords[$field] = unhtmlentities( $keywords[$field] );
+
+ if (strlen($keywords[$field]) >= $this->Application->ConfigValue('Search_MinKeyword_Length')) {
+ $highlight_keywords[] = $keywords[$field];
+ if (in_array($verbs[$field], Array('any', 'contains', 'notcontains'))) {
+ $keywords[$field] = '%'.strtr($keywords[$field], Array('%' => '\\%', '_' => '\\_')).'%';
+ }
+ $condition = sprintf($condition_patterns[$verbs[$field]], $field_name, $this->Conn->qstr( $keywords[$field] ));
+ }
+ break;
+
+ case 'boolean':
+ if ($keywords[$field] != -1) {
+ $property_mappings = $this->Application->getUnitOption($this->Prefix, 'ItemPropertyMappings');
+ $items_table = $this->Application->getUnitOption($event->Prefix, 'TableName');
+
+ switch ($field) {
+ case 'HotItem':
+ $hot_limit_var = getArrayValue($property_mappings, 'HotLimit');
+ if ($hot_limit_var) {
+ $sql = 'SELECT Data
+ FROM '.TABLE_PREFIX.'Cache
+ WHERE VarName = "'.$hot_limit_var.'"';
+ $hot_limit = (int)$this->Conn->GetOne($sql);
+
+ $condition = 'IF('.$items_table.'.HotItem = 2,
+ IF('.$items_table.'.Hits >= '.
+ $hot_limit.
+ ', 1, 0), '.$items_table.'.HotItem) = '.$keywords[$field];
+ }
+ break;
+
+ case 'PopItem':
+ $votes2pop_var = getArrayValue($property_mappings, 'VotesToPop');
+ $rating2pop_var = getArrayValue($property_mappings, 'RatingToPop');
+ if ($votes2pop_var && $rating2pop_var) {
+ $condition = 'IF('.$items_table.'.PopItem = 2, IF('.$items_table.'.CachedVotesQty >= '.
+ $this->Application->ConfigValue($votes2pop_var).
+ ' AND '.$items_table.'.CachedRating >= '.
+ $this->Application->ConfigValue($rating2pop_var).
+ ', 1, 0), '.$items_table.'.PopItem) = '.$keywords[$field];
+ }
+ break;
+
+ case 'NewItem':
+ $new_days_var = getArrayValue($property_mappings, 'NewDays');
+ if ($new_days_var) {
+ $condition = 'IF('.$items_table.'.NewItem = 2,
+ IF('.$items_table.'.CreatedOn >= (UNIX_TIMESTAMP() - '.
+ $this->Application->ConfigValue($new_days_var).
+ '*3600*24), 1, 0), '.$items_table.'.NewItem) = '.$keywords[$field];
+ }
+ break;
+
+ case 'EditorsPick':
+ $condition = $items_table.'.EditorsPick = '.$keywords[$field];
+ break;
+ }
+ }
+ break;
+
+ case 'range':
+ $range_conditions = Array();
+ if ($keywords[$field.'_from'] && !preg_match("/[^0-9]/i", $keywords[$field.'_from'])) {
+ $range_conditions[] = $field_name.' >= '.$keywords[$field.'_from'];
+ }
+ if ($keywords[$field.'_to'] && !preg_match("/[^0-9]/i", $keywords[$field.'_to'])) {
+ $range_conditions[] = $field_name.' <= '.$keywords[$field.'_to'];
+ }
+ if ($range_conditions) {
+ $condition = implode(' AND ', $range_conditions);
+ }
+ break;
+
+ case 'date':
+ if ($keywords[$field]) {
+ if (in_array($keywords[$field], Array('today', 'yesterday'))) {
+ $current_time = getdate();
+ $day_begin = adodb_mktime(0, 0, 0, $current_time['mon'], $current_time['mday'], $current_time['year']);
+ $time_mapping = Array('today' => $day_begin, 'yesterday' => ($day_begin - 86400));
+ $min_time = $time_mapping[$keywords[$field]];
+ }
+ else {
+ $time_mapping = Array (
+ 'last_week' => 604800, 'last_month' => 2628000, 'last_3_months' => 7884000,
+ 'last_6_months' => 15768000, 'last_year' => 31536000,
+ );
+ $min_time = adodb_mktime() - $time_mapping[$keywords[$field]];
+ }
+ $condition = $field_name.' > '.$min_time;
+ }
+ break;
+ }
+
+ return $condition;
+ }
+
function getHuman($type, $search_data)
{
$type = ucfirst(strtolower($type));
@@ -1430,7 +1456,7 @@
$ret = $this->Application->Phrase($values[$value]);
break;
- case 'text':
+ default:
$ret = $value;
break;