Index: trunk/core/kernel/db/db_event_handler.php =================================================================== diff -u -r4216 -r4228 --- trunk/core/kernel/db/db_event_handler.php (.../db_event_handler.php) (revision 4216) +++ trunk/core/kernel/db/db_event_handler.php (.../db_event_handler.php) (revision 4228) @@ -1308,36 +1308,32 @@ $event->setPseudoClass('_List'); $object =& $event->getObject(); - $keyword = $this->Application->GetVar( $event->getPrefixSpecial(true).'_search_keyword'); - $this->Application->StoreVar( $event->getPrefixSpecial().'_search_keyword', $keyword); - + $search_keyword = $this->Application->GetVar( $event->getPrefixSpecial(true).'_search_keyword'); + $this->Application->StoreVar( $event->getPrefixSpecial().'_search_keyword', $search_keyword); + $search_keyword = str_replace('*', '%', $search_keyword); + $custom_filters = $this->Application->RecallVar( $event->getPrefixSpecial().'_custom_filters'); $custom_filters = $custom_filters ? unserialize($custom_filters) : Array(); $submit_custom_filters = $this->Application->GetVar('custom_filters'); - if($submit_custom_filters) - { + if ($submit_custom_filters) { $submit_custom_filters = getArrayValue($submit_custom_filters, $event->getPrefixSpecial() ); - if($submit_custom_filters) - { - foreach($submit_custom_filters as $cf_name => $cf_value) - { - if($cf_value) - { + if ($submit_custom_filters) { + foreach ($submit_custom_filters as $cf_name => $cf_value) { + if ($cf_value) { $custom_filters[$cf_name] = $cf_value; } - else - { + else { unset($custom_filters[$cf_name]); } } } } $this->Application->StoreVar($event->getPrefixSpecial().'_custom_filters', serialize($custom_filters) ); - if( !$keyword && !count($custom_filters) ) + if( !$search_keyword && !count($custom_filters) ) { $this->OnSearchReset($event); return true; @@ -1348,14 +1344,14 @@ $search_fields = array_keys($grids[$grid_name]['Fields']); $search_filter = Array(); - + $search_helper =& $this->Application->recallObject('SearchHelper'); + $search_keywords = $search_helper->splitKeyword($search_keyword); + foreach($search_fields as $search_field) { $filter_type = isset($object->VirtualFields[$search_field]) ? 'having' : 'where'; $field_type = getArrayValue($object->Fields[$search_field],'type'); if(!$field_type) $field_type = 'string'; // default LIKE filter for all fields without type - $keyword = trim($keyword); - $keyword = str_replace(Array('"',"'"),'',$keyword); $filter_value = ''; $table_name = ($filter_type == 'where') ? '`'.$object->TableName.'`.' : ''; @@ -1369,23 +1365,33 @@ $field_value = getArrayValue($custom_filters, $search_field); if ($field_value !== false) { + // if keyword passed through advanced search filter (e.g. on Visits lists section) array_push($search_keys, $this->Conn->qstr($field_value)); } else { + // if keywords passed through simple search filter (on each grid) $use_phrases = getArrayValue($object->Fields[$search_field], 'use_phrases'); foreach($object->Fields[$search_field]['options'] as $key => $val) { - $pattern = '#'.$keyword.'#i'; - if ( preg_match($pattern, $use_phrases ? $this->Application->Phrase($val) : $val) ) { - array_push($search_keys, $this->Conn->qstr($key)); + foreach ($search_keywords as $keyword => $sign) { + $pattern = '#'.$keyword.'#i'; + if (!preg_match($pattern, $use_phrases ? $this->Application->Phrase($val) : $val)) continue; + + if ($sign == '+' || $sign == '') { + $search_keys[$key] = $this->Conn->qstr($key); + } + elseif($sign == '-') { + // if same value if found as exclusive too, then remove from search result + unset($search_keys[$key]); + } } } } - if (count($search_keys) > 0) { + if ($search_keys) { $filter_value = $table_name.'`'.$search_field.'` IN ('.implode(',', $search_keys).')'; } - + $field_processed = true; break; @@ -1425,44 +1431,47 @@ // if not already processed by formatter, then get clause by field type - if(!$field_processed && $keyword) - { + if (!$field_processed && $search_keywords) { switch($field_type) { case 'int': case 'integer': case 'numeric': - if( !is_numeric($keyword) ) break; - $filter_value = $table_name.'`'.$search_field.'` = \''.$keyword.'\''; + $search_keys = Array(); + foreach ($search_keywords as $keyword => $sign) { + if (!is_numeric($keyword) || ($sign == '-')) continue; + $search_keys[] = $this->Conn->qstr($keyword); + } + + if ($search_keys) { + $filter_value = $table_name.'`'.$search_field.'` IN ('.implode(',', $search_keys).')'; + } break; case 'double': case 'float': case 'real': - if( !is_numeric($keyword) ) break; - $filter_value = 'ABS('.$table_name.'`'.$search_field.'` - \''.str_replace(',','.',$keyword).'\') <= 0.0001'; + $search_keys = Array(); + foreach ($search_keywords as $keyword => $sign) { + $keyword = str_replace(',', '.', $keyword); + if (!is_numeric($keyword) || ($sign == '-')) continue; + $search_keys[] = 'ABS('.$table_name.'`'.$search_field.'` - '.$this->Conn->qstr($keyword).') <= 0.0001'; + } + + if ($search_keys) { + $filter_value = '('.implode(') OR (', $search_keys).')'; + } break; case 'string': - $like_keyword = preg_replace( '/\'(.*)\'/U', '\\1', $this->Conn->qstr( str_replace('\\','\\\\', $keyword) ) ); - $keywords = explode(' ', $like_keyword); - foreach($keywords as $keyword_pos => $keyword_value) - { - $keyword_value = trim($keyword_value); - if($keyword_value) - { - $keywords[$keyword_pos] = $table_name.'`'.$search_field.'` LIKE \'%'.$keyword_value.'%\''; - } - else - { - unset($keywords[$keyword_pos]); - } - } - $filter_value = '('.implode(') OR (',$keywords).')'; + $filter_value = $search_helper->buildWhereClause($search_keyword, Array($table_name.'`'.$search_field.'`')); break; } } - if($filter_value) $search_filter[$search_field] = Array('type' => $filter_type, 'value' => $filter_value); + + if ($filter_value) { + $search_filter[$search_field] = Array('type' => $filter_type, 'value' => $filter_value); + } } $this->Application->StoreVar($event->getPrefixSpecial().'_search_filter', serialize($search_filter) );