( )
- ( )
+ -
-
Index: branches/5.0.x/core/units/categories/categories_event_handler.php
===================================================================
diff -u -N -r12635 -r12666
--- branches/5.0.x/core/units/categories/categories_event_handler.php (.../categories_event_handler.php) (revision 12635)
+++ branches/5.0.x/core/units/categories/categories_event_handler.php (.../categories_event_handler.php) (revision 12666)
@@ -1,6 +1,6 @@
'OnSimpleSearch',
+ 'subsearch' => 'OnSubSearch',
+ 'advanced' => 'OnAdvancedSearch'
+ );
+
+ $type = $this->Application->GetVar('search_type', 'simple');
+
+ if ($keywords = $event->getEventParam('keyword_string')) {
+ // processing keyword_string param of ListProducts tag
+ $this->Application->SetVar('keywords', $keywords);
+ $type = 'simple';
+ }
+
+ $search_event = $event_mapping[$type];
+ $this->$search_event($event);
+
+ $search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
+ $sql = 'SHOW TABLES LIKE "'.$search_table.'"';
+
+ if ($this->Conn->Query($sql)) {
+ $search_res_ids = $this->Conn->GetCol('SELECT ResourceId FROM '.$search_table);
+ }
+
+ if (isset($search_res_ids) && $search_res_ids) {
+ $type_clauses['search']['include'] = '%1$s.ResourceId IN ('.implode(',', $search_res_ids).')';
+ $type_clauses['search']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $search_res_ids).')';
+ }
+ else {
+ $type_clauses['search']['include'] = '0';
+ $type_clauses['search']['except'] = '1';
+ }
+
+ $type_clauses['search']['having_filter'] = false;
+ }
+
$search_helper =& $this->Application->recallObject('SearchHelper');
/* @var $search_helper kSearchHelper */
@@ -1993,4 +2030,277 @@
$this->Application->StoreVar('_editor_preview_content_', $string);
}
+
+ /**
+ * Makes simple search for categories
+ * based on keywords string
+ *
+ * @param kEvent $event
+ */
+ function OnSimpleSearch(&$event)
+ {
+ $event->redirect = false;
+ $search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
+
+ $keywords = unhtmlentities( trim($this->Application->GetVar('keywords')) );
+
+ $query_object =& $this->Application->recallObject('HTTPQuery');
+ $sql = 'SHOW TABLES LIKE "'.$search_table.'"';
+
+ if(!isset($query_object->Get['keywords']) &&
+ !isset($query_object->Post['keywords']) &&
+ $this->Conn->Query($sql))
+ {
+ return; // used when navigating by pages or changing sorting in search results
+ }
+ if(!$keywords || strlen($keywords) < $this->Application->ConfigValue('Search_MinKeyword_Length'))
+ {
+ $this->Conn->Query('DROP TABLE IF EXISTS '.$search_table);
+ $this->Application->SetVar('keywords_too_short', 1);
+ return; // if no or too short keyword entered, doing nothing
+ }
+
+ $this->Application->StoreVar('keywords', $keywords);
+
+ $this->saveToSearchLog($keywords, 0); // 0 - simple search, 1 - advanced search
+
+ $keywords = strtr($keywords, Array('%' => '\\%', '_' => '\\_'));
+
+ $event->setPseudoClass('_List');
+
+ $object =& $event->getObject();
+ /* @var $object kDBList */
+
+ $this->Application->SetVar($event->getPrefixSpecial().'_Page', 1);
+ $lang = $this->Application->GetVar('m_lang');
+ $items_table = $this->Application->getUnitOption($event->Prefix, 'TableName');
+ $module_name = 'In-Portal';
+
+ $sql = 'SELECT *
+ FROM ' . $this->Application->getUnitOption('confs', 'TableName') . '
+ WHERE ModuleName = ' . $this->Conn->qstr($module_name) . ' AND SimpleSearch = 1';
+ $search_config = $this->Conn->Query($sql, 'FieldName');
+
+ $field_list = array_keys($search_config);
+
+ $join_clauses = Array();
+
+ // field processing
+ $weight_sum = 0;
+
+ $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 '.$items_table.'.ResourceId = custom_data.ResourceId';
+ }
+
+ // what field in search config becomes what field in sql (key - new field, value - old field (from searchconfig table))
+ $search_config_map = Array();
+
+ foreach ($field_list as $key => $field) {
+ $options = $object->getFieldOptions($field);
+ $local_table = TABLE_PREFIX.$search_config[$field]['TableName'];
+ $weight_sum += $search_config[$field]['Priority']; // counting weight sum; used when making relevance clause
+
+ // processing multilingual fields
+ if (getArrayValue($options, 'formatter') == 'kMultiLanguage') {
+ $field_list[$key.'_primary'] = 'l'.$this->Application->GetDefaultLanguageId().'_'.$field;
+ $field_list[$key] = 'l'.$lang.'_'.$field;
+
+ if (!isset($search_config[$field]['ForeignField'])) {
+ $field_list[$key.'_primary'] = $local_table.'.'.$field_list[$key.'_primary'];
+ $search_config_map[ $field_list[$key.'_primary'] ] = $field;
+ }
+ }
+
+ // processing fields from other tables
+ if ($foreign_field = $search_config[$field]['ForeignField']) {
+ $exploded = explode(':', $foreign_field, 2);
+ if ($exploded[0] == 'CALC') {
+ // ignoring having type clauses in simple search
+ unset($field_list[$key]);
+ continue;
+ }
+ else {
+ $multi_lingual = false;
+ if ($exploded[0] == 'MULTI') {
+ $multi_lingual = true;
+ $foreign_field = $exploded[1];
+ }
+
+ $exploded = explode('.', $foreign_field); // format: table.field_name
+ $foreign_table = TABLE_PREFIX.$exploded[0];
+
+ $alias_counter++;
+ $alias = 't'.$alias_counter;
+
+ if ($multi_lingual) {
+ $field_list[$key] = $alias.'.'.'l'.$lang.'_'.$exploded[1];
+ $field_list[$key.'_primary'] = 'l'.$this->Application->GetDefaultLanguageId().'_'.$field;
+ $search_config_map[ $field_list[$key] ] = $field;
+ $search_config_map[ $field_list[$key.'_primary'] ] = $field;
+ }
+ else {
+ $field_list[$key] = $alias.'.'.$exploded[1];
+ $search_config_map[ $field_list[$key] ] = $field;
+ }
+
+ $join_clause = str_replace('{ForeignTable}', $alias, $search_config[$field]['JoinClause']);
+ $join_clause = str_replace('{LocalTable}', $items_table, $join_clause);
+
+ $join_clauses[] = ' LEFT JOIN '.$foreign_table.' '.$alias.'
+ ON '.$join_clause;
+ }
+ }
+ else {
+ // processing fields from local table
+ if ($search_config[$field]['CustomFieldId']) {
+ $local_table = 'custom_data';
+
+ // search by custom field value on current language
+ $custom_field_id = array_search($field_list[$key], $custom_fields);
+ $field_list[$key] = 'l'.$lang.'_cust_'.$custom_field_id;
+
+ // search by custom field value on primary language
+ $field_list[$key.'_primary'] = $local_table.'.l'.$this->Application->GetDefaultLanguageId().'_cust_'.$custom_field_id;
+ $search_config_map[ $field_list[$key.'_primary'] ] = $field;
+ }
+
+ $field_list[$key] = $local_table.'.'.$field_list[$key];
+ $search_config_map[ $field_list[$key] ] = $field;
+ }
+ }
+
+ // keyword string processing
+ $search_helper =& $this->Application->recallObject('SearchHelper');
+ /* @var $search_helper kSearchHelper */
+
+ $where_clause = Array ();
+ foreach ($field_list as $field) {
+ if (preg_match('/^' . preg_quote($items_table, '/') . '\.(.*)/', $field, $regs)) {
+ // local real field
+ $filter_data = $search_helper->getSearchClause($object, $regs[1], $keywords, false);
+ if ($filter_data) {
+ $where_clause[] = $filter_data['value'];
+ }
+ }
+ elseif (preg_match('/^custom_data\.(.*)/', $field, $regs)) {
+ $custom_field_name = 'cust_' . $search_config_map[$field];
+ $filter_data = $search_helper->getSearchClause($object, $custom_field_name, $keywords, false);
+ if ($filter_data) {
+ $where_clause[] = str_replace('`' . $custom_field_name . '`', $field, $filter_data['value']);
+ }
+ }
+ else {
+ $where_clause[] = $search_helper->buildWhereClause($keywords, Array ($field));
+ }
+ }
+
+ $where_clause = '(' . implode(') OR (', $where_clause) . ')';
+
+ $where_clause = $where_clause.' AND '.$items_table.'.Status=1';
+
+ if ($event->MasterEvent && $event->MasterEvent->Name == 'OnListBuild') {
+ if ($event->MasterEvent->getEventParam('ResultIds')) {
+ $where_clause .= ' AND '.$items_table.'.ResourceId IN ('.implode(',', $event->MasterEvent->getEventParam('ResultIds')).')';
+ }
+ }
+
+ // making relevance clause
+ $positive_words = $search_helper->getPositiveKeywords($keywords);
+ $this->Application->StoreVar('highlight_keywords', serialize($positive_words));
+ $revelance_parts = Array();
+ reset($search_config);
+
+ foreach ($positive_words as $keyword_index => $positive_word) {
+ $positive_words[$keyword_index] = mysql_real_escape_string($positive_word);
+ }
+
+ foreach ($field_list as $field) {
+
+ if (!array_key_exists($field, $search_config_map)) {
+ $map_key = $search_config_map[$items_table . '.' . $field];
+ }
+ else {
+ $map_key = $search_config_map[$field];
+ }
+
+ $config_elem = $search_config[ $map_key ];
+ $weight = $config_elem['Priority'];
+ $revelance_parts[] = 'IF('.$field.' LIKE "%'.implode(' ', $positive_words).'%", '.$weight_sum.', 0)';
+ foreach ($positive_words as $keyword) {
+ $revelance_parts[] = 'IF('.$field.' LIKE "%'.$keyword.'%", '.$weight.', 0)';
+ }
+ }
+
+ $revelance_parts = array_unique($revelance_parts);
+
+ $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(' + ', $revelance_parts).') / '.$weight_sum.' * '.$rel_keywords;
+ if ($rel_pop && isset($object->Fields['Hits'])) {
+ $relevance_clause .= ' + (Hits + 1) / (MAX(Hits) + 1) * '.$rel_pop;
+ }
+ if ($rel_rating && isset($object->Fields['CachedRating'])) {
+ $relevance_clause .= ' + (CachedRating + 1) / (MAX(CachedRating) + 1) * '.$rel_rating;
+ }
+
+ // building final search query
+ if (!$this->Application->GetVar('do_not_drop_search_table')) {
+ $this->Conn->Query('DROP TABLE IF EXISTS '.$search_table); // erase old search table if clean k4 event
+ $this->Application->SetVar('do_not_drop_search_table', true);
+ }
+
+
+ $search_table_exists = $this->Conn->Query('SHOW TABLES LIKE "'.$search_table.'"');
+ if ($search_table_exists) {
+ $select_intro = 'INSERT INTO '.$search_table.' (Relevance, ItemId, ResourceId, ItemType, EdPick) ';
+ }
+ else {
+ $select_intro = 'CREATE TABLE '.$search_table.' AS ';
+ }
+
+ $edpick_clause = $this->Application->getUnitOption($event->Prefix.'.EditorsPick', 'Fields') ? $items_table.'.EditorsPick' : '0';
+
+
+ $sql = $select_intro.' SELECT '.$relevance_clause.' AS Relevance,
+ '.$items_table.'.'.$this->Application->getUnitOption($event->Prefix, 'IDField').' AS ItemId,
+ '.$items_table.'.ResourceId,
+ '.$this->Application->getUnitOption($event->Prefix, 'ItemType').' AS ItemType,
+ '.$edpick_clause.' AS EdPick
+ FROM '.$object->TableName.'
+ '.implode(' ', $join_clauses).'
+ WHERE '.$where_clause.'
+ GROUP BY '.$items_table.'.'.$this->Application->getUnitOption($event->Prefix, 'IDField');
+
+ $res = $this->Conn->Query($sql);
+ }
+
+ /**
+ * Make record to search log
+ *
+ * @param string $keywords
+ * @param int $search_type 0 - simple search, 1 - advanced search
+ */
+ function saveToSearchLog($keywords, $search_type = 0)
+ {
+ // don't save keywords for each module separately, just one time
+ // static variable can't help here, because each module uses it's own class instance !
+ if (!$this->Application->GetVar('search_logged')) {
+ $sql = 'UPDATE '.TABLE_PREFIX.'SearchLog
+ SET Indices = Indices + 1
+ WHERE Keyword = '.$this->Conn->qstr($keywords).' AND SearchType = '.$search_type; // 0 - simple search, 1 - advanced search
+ $this->Conn->Query($sql);
+ if ($this->Conn->getAffectedRows() == 0) {
+ $fields_hash = Array('Keyword' => $keywords, 'Indices' => 1, 'SearchType' => $search_type);
+ $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'SearchLog');
+ }
+
+ $this->Application->SetVar('search_logged', 1);
+ }
+ }
}
\ No newline at end of file
Index: branches/5.0.x/themes/advanced/platform/categories/search_results.tpl
===================================================================
diff -u -N
--- branches/5.0.x/themes/advanced/platform/categories/search_results.tpl (revision 0)
+++ branches/5.0.x/themes/advanced/platform/categories/search_results.tpl (revision 12666)
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+