Index: branches/RC/core/units/general/helpers/search_helper.php
===================================================================
--- branches/RC/core/units/general/helpers/search_helper.php	(revision 11855)
+++ branches/RC/core/units/general/helpers/search_helper.php	(revision 11856)
@@ -1,686 +1,686 @@
 <?php
 
 	class kSearchHelper extends kHelper {
 
 
 		/**
 		 * Splits search phrase into keyword using quotes,plus and minus sings and spaces as split criteria
 		 *
 		 * @param string $keyword
 		 * @return string
 		 */
 		function splitKeyword($keyword)
 		{
 			if ($this->Application->ConfigValue('CheckStopWords')) {
 				$keyword_after_remove = $this->_removeStopWords($keyword);
 				if ($keyword_after_remove) {
 					// allow to search through stop word grid
 					$keyword = $keyword_after_remove;
 				}
 			}
 
 			$quotes_re = '/([+\-]?)"(.*?)"/';
 			$no_quotes_re = '/([+\-]?)([^ ]+)/';
 
 			$quoted_kw = preg_match_all($quotes_re, $keyword, $res);
 			foreach ($res[2] as $index => $kw) $final[$kw] = $res[1][$index];
 			$keyword = preg_replace($quotes_re, '', $keyword);
 			$not_quoted_kw =  preg_match_all($no_quotes_re, $keyword, $res);
 			foreach ($res[2] as $index => $kw) $final[$kw] = $res[1][$index];
 
 			return $final;
 		}
 
 		function getPositiveKeywords($keyword)
 		{
 			$keywords = $this->splitKeyword($keyword);
 
 			$ret = Array();
 			foreach ($keywords as $keyword => $sign) {
 				if ($sign == '+' || $sign == '') {
 					$ret[] = $keyword;
 				}
 			}
 			return $ret;
 		}
 
 		function buildWhereClause($keyword, $fields)
 		{
 			$keywords = $this->splitKeyword($keyword);
 
 			$normal_conditions = Array();
 			$plus_conditions = Array();
 			$minus_conditions = Array();
 
 			foreach ($keywords as $keyword => $sign) {
 				switch ($sign) {
 					case '+':
-						$plus_conditions[] =   implode(' LIKE "%'.$keyword.'%" OR ', $fields).' LIKE "%'.$keyword.'%"';
+						$plus_conditions[] = implode(' LIKE "%'.$keyword.'%" OR ', $fields).' LIKE "%'.$keyword.'%"';
 						break;
 
 					case '-':
 						foreach ($fields as $field) {
 							$condition[] = $field.' NOT LIKE "%'.$keyword.'%" OR '.$field.' IS NULL';
 						}
 						$minus_conditions[] = '('.implode(') AND (', $condition).')';
 						break;
 
 					case '':
 						$keyword = str_replace('"', '\"', $keyword);
 						$normal_conditions[] = implode(' LIKE "%'.$keyword.'%" OR ', $fields).' LIKE "%'.$keyword.'%"';
 						break;
 				}
 			}
 
 			// building where clause
 			if ($normal_conditions) {
 				$where_clause = '('.implode(') OR (', $normal_conditions).')';
 			}
 			else {
 				$where_clause = '1';
 			}
 
 			if ($plus_conditions) {
 				$where_clause = '('.$where_clause.') AND ('.implode(') AND (', $plus_conditions).')';
 			}
 
 			if ($minus_conditions) {
 				$where_clause = '('.$where_clause.') AND ('.implode(') AND (', $minus_conditions).')';
 			}
 
 			return $where_clause;
 		}
 
 		/**
 		 * Returns additional information about search field
 		 *
 		 * @param kDBList $object
 		 * @param string $field_name
 		 * @return Array
 		 */
-		function getFieldInformation(&$object, $field_name)
+		function _getFieldInformation(&$object, $field_name)
 		{
 			$sql_filter_type = isset($object->VirtualFields[$field_name]) ? 'having' : 'where';
 			$field_type = isset($object->Fields[$field_name]['type']) ? $object->Fields[$field_name]['type'] : 'string';
 
 			if (preg_match('/(.*)\.(.*)/', $field_name, $regs)) {
 				$table_name = '`'.$regs[1].'`.'; // field from external table
 				$field_name = $regs[2];
 			}
 			elseif ($sql_filter_type == 'where') {
 				$table_name = '`'.$object->TableName.'`.'; // field from local table
 			}
 
 			$table_name = ($sql_filter_type == 'where') ? $table_name : '';
 
 			// replace wid inside table name to WID_MARK constant value
 			$is_temp_table = preg_match('/(.*)'.TABLE_PREFIX.'ses_'.$this->Application->GetSID().'(_[\d]+){0,1}_edit_(.*)/', $table_name, $regs);
 			if ($is_temp_table) {
 				$table_name = $regs[1].TABLE_PREFIX.'ses_'.EDIT_MARK.'_edit_'.$regs[3]; // edit_mark will be replaced with sid[_main_wid] in AddFilters
 			}
 
-			return Array ('field_name' => $field_name, 'field_type' => $field_type, 'table_name' => $table_name, 'sql_filter_type' => $sql_filter_type);
+			return Array ($field_name, $field_type, $table_name, $sql_filter_type);
 		}
 
 		/**
 		 * Removes stop words from keyword
 		 *
 		 * @param string $keyword
 		 * @return string
 		 */
 		function _removeStopWords($keyword)
 		{
 			static $stop_words = Array ();
 
 			if (!$stop_words) {
 				$sql = 'SELECT StopWord
 						FROM ' . $this->Application->getUnitOption('stop-word', 'TableName') . '
 						ORDER BY LENGTH(StopWord) DESC, StopWord ASC';
 				$stop_words = $this->Conn->GetCol($sql);
 
 				foreach ($stop_words as $index => $stop_word) {
 					$stop_words[$index] = '/(^| )' . preg_quote($stop_word, '/') . '( |$)/';
 				}
 			}
 
 			$keyword = preg_replace($stop_words, ' ', $keyword);
 
 			return trim( preg_replace('/[ ]+/', ' ', $keyword) );
 		}
 
 		/**
 		 * Enter description here...
 		 *
 		 * @param kEvent $event
 		 */
 		function performSearch(&$event)
 		{
 			$object =& $event->getObject();
 
 			// process search 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_filter = $this->processCustomFilters($event);
 
 			if(!$search_keyword && $custom_filter === false) {
 				$this->resetSearch($event);
 				return true;
 			}
 
 			if ($search_keyword) {
 				$this->processAutomaticFilters($event, $search_keyword, $custom_filter);
 			}
 		}
 
 
 		function processAutomaticFilters(&$event, $search_keyword, $custom_filter)
 		{
 			$grid_name = $this->Application->GetVar('grid_name');
 			$grids = $this->Application->getUnitOption($event->Prefix, 'Grids');
 			$search_fields = array_keys($grids[$grid_name]['Fields']);
 
 			$search_filter = Array();
 			$object =& $event->getObject();
 
 			foreach ($search_fields as $search_field) {
 				$custom_search = isset($custom_filter[$search_field]);
 
 				$filter_data = $this->getSearchClause($object, $search_field, $search_keyword, $custom_search);
 
 				if ($filter_data) {
 					$search_filter[$search_field] = $filter_data;
 				}
 				else {
 					unset($search_filter[$search_field]);
 				}
 			}
 			$this->Application->StoreVar($event->getPrefixSpecial().'_search_filter', serialize($search_filter) );
 		}
 
 		/**
 		 * Returns search clause for any particular field
 		 *
 		 * @param kDBList $object
 		 * @param string $search_field
 		 * @param string $search_keyword what we are searching (false, when building custom filter clause)
 		 * @param string $custom_search already found using custom filter
 		 * @return Array
 		 */
 		function getSearchClause(&$object, $field_name, $search_keyword, $custom_search)
 		{
 			if (array_key_exists($field_name, $object->VirtualFields) && !array_key_exists($field_name, $object->CalculatedFields)) {
 				// Virtual field, that is shown in grid, but it doesn't have corresponding calculated field.
 				// Happens, when field value is calculated on the fly (during grid display) and it is not searchable.
 				return '';
 			}
 
 			$search_keywords = $this->splitKeyword($search_keyword);
 
-			extract( $this->getFieldInformation($object, $field_name) ); // see getFieldInformation for more details
+			list ($field_name, $field_type, $table_name, $sql_filter_type) = $this->_getFieldInformation($object, $field_name);
 
 			$filter_value = '';
 
 			// get field clause by formatter name and/or parameters
 			$formatter = getArrayValue($object->Fields[$field_name], 'formatter');
 			switch ($formatter) {
 				case 'kOptionsFormatter':
 					$search_keys = Array();
 
 					if ($custom_search === false) {
 						// if keywords passed through simple search filter (on each grid)
 						$use_phrases = getArrayValue($object->Fields[$field_name], 'use_phrases');
 						$field_options = $object->GetFieldOptions($field_name);
 						foreach ($field_options['options'] as $key => $val) {
 							foreach ($search_keywords as $keyword => $sign) {
 								$pattern = '#'.$keyword.'#i';
 								if (!preg_match($pattern, $use_phrases ? $this->Application->Phrase($val) : $val)) {
 									if ($sign == '+') {
 										$filter_value = $table_name.'`'.$field_name.'` = NULL';
 										break;
 									}
 									else {
 										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 ($search_keys) {
 						$filter_value = $table_name.'`'.$field_name.'` IN ('.implode(',', $search_keys).')';
 					}
 
 					$field_processed = true;
 					break;
 
 				case 'kDateFormatter':
 					// if date is searched using direct filter, then do nothing here, otherwise search using LIKE clause
 					$field_processed = ($custom_search !== false) ? true : false;
 					break;
 
 				default:
 					$field_processed = false;
 					break;
 			}
 
 			// if not already processed by formatter, then get clause by field type
 			if (!$field_processed && $search_keywords) {
 				switch($field_type)
 				{
 					case 'int':
 					case 'integer':
 					case 'numeric':
 						$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.'`'.$field_name.'` IN ('.implode(',', $search_keys).')';
 						}
 						break;
 
 					case 'double':
 					case 'float':
 					case 'real':
 						$search_keys = Array();
 						foreach ($search_keywords as $keyword => $sign) {
 							$keyword = str_replace(',', '.', $keyword);
 							if (!is_numeric($keyword) || ($sign == '-')) continue;
 							$search_keys[] = 'ABS('.$table_name.'`'.$field_name.'` - '.$this->Conn->qstr($keyword).') <= 0.0001';
 						}
 
 						if ($search_keys) {
 							$filter_value = '('.implode(') OR (', $search_keys).')';
 						}
 						break;
 
 					case 'string':
 						$filter_value = $this->buildWhereClause($search_keyword, Array($table_name.'`'.$field_name.'`'));
 						break;
 				}
 			}
 
 			if ($filter_value) {
 				return Array('type' => $sql_filter_type, 'value' => $filter_value);
 			}
 
 			return false;
 		}
 
 		/**
 		 * Processes custom filters from submit
 		 *
 		 * @param KEvent $event
 		 * @return bool
 		 */
 		function processCustomFilters(&$event)
 		{
 			$grid_name = $this->Application->GetVar('grid_name');
 
 			// update "custom filter" with values from submit: begin
 			$view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view');
 			$custom_filters = $this->Application->RecallPersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name/*, ALLOW_DEFAULT_SETTINGS*/);
 			if ($custom_filters) {
 				$custom_filters = unserialize($custom_filters);
 				$custom_filter = isset($custom_filters[$grid_name]) ? $custom_filters[$grid_name] : Array ();
 			}
 			else {
 				$custom_filter = Array ();
 			}
 
 			// submit format custom_filters[prefix_special][field]
 			$submit_filters = $this->Application->GetVar('custom_filters');
 			if ($submit_filters) {
 				$submit_filters = getArrayValue($submit_filters, $event->getPrefixSpecial(), $grid_name);
 				if ($submit_filters) {
 					foreach ($submit_filters as $field_name => $field_options) {
 						list ($filter_type, $field_value) = each($field_options);
 						$is_empty = strlen(is_array($field_value) ? implode('', $field_value) : $field_value) == 0;
 						if ($is_empty) {
 							if (isset($custom_filter[$field_name])) {
 								// use isset, because non-existing key will cause "php notice"!
 								unset($custom_filter[$field_name][$filter_type]); // remove filter
 
 								if (!$custom_filter[$field_name]) {
 									// if no filters left for field, then delete record at all
 									unset($custom_filter[$field_name]);
 								}
 							}
 						}
 						else {
 							$custom_filter[$field_name][$filter_type]['submit_value'] = $field_value;
 						}
 					}
 				}
 			}
 
 			if ($custom_filter) {
 				$custom_filters[$grid_name] = $custom_filter;
 			}
 			else {
 				unset($custom_filters[$grid_name]);
 			}
 			// update "custom filter" with values from submit: end
 
 			if (!$custom_filter) {
 				// in case when no filters specified, there are nothing to process
 				$this->Application->StorePersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name, serialize($custom_filters) );
 				return false;
 			}
 
 			$object =& $event->getObject(); // don't recall it each time in getCustomFilterSearchClause
 			$grid_info = $this->Application->getUnitOption($event->Prefix.'.'.$grid_name, 'Grids');
 			foreach ($custom_filter as $field_name => $field_options) {
 				list ($filter_type, $field_options) = each($field_options);
 				$field_options['grid_options'] = $grid_info['Fields'][$field_name];
 				$field_options = $this->getCustomFilterSearchClause($object, $field_name, $filter_type, $field_options);
 				if ($field_options['value']) {
 					unset($field_options['grid_options']);
 					$custom_filter[$field_name][$filter_type] = $field_options;
 				}
 			}
 
 			$custom_filters[$grid_name] = $custom_filter;
 			$this->Application->StorePersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name, serialize($custom_filters) );
 			return $custom_filter;
 		}
 
 		/**
 		 * Checks, that range filters "To" part is defined for given grid
 		 *
 		 * @param string $prefix_special
 		 * @param string $grid_name
 		 * @return bool
 		 */
 		function rangeFiltersUsed($prefix_special, $grid_name)
 		{
 			static $cache = Array ();
 			$cache_key = $prefix_special . $grid_name;
 
 			if (array_key_exists($cache_key, $cache)) {
 				return $cache[$cache_key];
 			}
 
 			$view_name = $this->Application->RecallVar($prefix_special . '_current_view');
 			$custom_filters = $this->Application->RecallPersistentVar($prefix_special . '_custom_filter.' . $view_name/*, ALLOW_DEFAULT_SETTINGS*/);
 			if (!$custom_filters) {
 				// filters not defined for given prefix
 				$cache[$cache_key] = false;
 				return false;
 			}
 
 			$custom_filters = unserialize($custom_filters);
 			if (!array_key_exists($grid_name, $custom_filters)) {
 				// filters not defined for given grid
 				$cache[$cache_key] = false;
 				return false;
 			}
 
 			$range_filter_defined = false;
 
 			$custom_filter = $custom_filters[$grid_name];
 			foreach ($custom_filter as $field_name => $field_options) {
 				list ($filter_type, $field_options) = each($field_options);
 
 				if (strpos($filter_type, 'range') === false) {
 					continue;
 				}
 
 				$to_value = (string)$field_options['submit_value']['to'];
 				if ($to_value !== '') {
 					$range_filter_defined = true;
 					break;
 				}
 			}
 
 			$cache[$cache_key] = $range_filter_defined;
 			return $range_filter_defined;
 		}
 
 		/**
 		 * Return numeric range filter value + checking that it's number
 		 *
 		 * @param Array $value array containing range filter value
 		 * @return unknown
 		 */
 		function getRangeValue($value)
 		{
 			return strlen($value) && is_numeric($value) ? $this->Conn->qstr($value) : false;
 		}
 
 		function getCustomFilterSearchClause(&$object, $field_name, $filter_type, $field_options)
 		{
 			// this is usually used for mutlilingual fields and date fields
 			if (isset($field_options['grid_options']['sort_field'])) {
 				$field_name = $field_options['grid_options']['sort_field'];
 			}
-			extract( $this->getFieldInformation($object, $field_name) ); // see getFieldInformation for more details
+			list ($field_name, $field_type, $table_name, $sql_filter_type) = $this->_getFieldInformation($object, $field_name);
 
 			$filter_value = '';
 
 			switch ($filter_type) {
 				case 'range':
 					$from = $this->getRangeValue($field_options['submit_value']['from']);
 					$to = $this->getRangeValue($field_options['submit_value']['to']);
 
 					if ($from !== false && $to !== false) {
 						// add range filter
 						$filter_value = $table_name.'`'.$field_name.'` >= '.$from.' AND '.$table_name.'`'.$field_name.'` <= '.$to;
 					}
 					elseif ($from !== false) {
 						// add equals filter on $from
 						$filter_value = $table_name.'`'.$field_name.'` = '.$from;
 					}
 					elseif ($to !== false) {
 						// add equals filter on $to
 						$filter_value = $table_name.'`'.$field_name.'` = '.$to;
 					}
 					break;
 
 				case 'float_range':
 					// MySQL can't compare values in "float" type columns using "=" operator
 					$from = $this->getRangeValue($field_options['submit_value']['from']);
 					$to = $this->getRangeValue($field_options['submit_value']['to']);
 
 					if ($from !== false && $to !== false) {
 						// add range filter
 						$filter_value = $table_name.'`'.$field_name.'` >= '.$from.' AND '.$table_name.'`'.$field_name.'` <= '.$to;
 					}
 					elseif ($from !== false) {
 						// add equals filter on $from
 						$filter_value = 'ABS('.$table_name.'`'.$field_name.'` - '.$from.') <= 0.0001';
 					}
 					elseif ($to !== false) {
 						// add equals filter on $to
 						$filter_value = 'ABS('.$table_name.'`'.$field_name.'` - '.$to.') <= 0.0001';
 					}
 					break;
 
 				case 'date_range':
 					$from = $this->processRangeField($object, $field_name, $field_options['submit_value'], 'from');
 					$to = $this->processRangeField($object, $field_name, $field_options['submit_value'], 'to');
 
 					$day_seconds = 23 * 60 * 60 + 59 * 60 + 59;
 					if ($from !== false && $to === false) {
 						$from = strtotime(date('Y-m-d', $from) . ' 00:00:00', $from); // reset to morning
 						$to = $from + $day_seconds;
 					}
 					elseif ($from === false && $to !== false) {
 						$to = strtotime(date('Y-m-d', $to) . ' 23:59:59', $to); // reset to evening
 						$from = $to - $day_seconds;
 					}
 
 					if ($from !== false && $to !== false) {
 						$filter_value = $table_name.'`'.$field_name.'` >= '.$from.' AND '.$table_name.'`'.$field_name.'` <= '.$to;
 					}
 					break;
 
 				case 'equals':
 				case 'options':
 					$field_value = strlen($field_options['submit_value']) ? $this->Conn->qstr($field_options['submit_value']) : false;
 					if ($field_value) {
 						$filter_value = $table_name.'`'.$field_name.'` = '.$field_value;
 					}
 					break;
 
 				case 'picker':
 					$field_value = strlen($field_options['submit_value']) ? $field_options['submit_value'] : false;
 					if ($field_value) {
 						$filter_value = $table_name.'`'.$field_name.'` LIKE "%|'.$field_value.'|%"';
 					}
 					break;
 
 				case 'like':
 					$filter_value = $this->buildWhereClause($field_options['submit_value'], Array($table_name.'`'.$field_name.'`'));
 					break;
 
 				default:
 					break;
 			}
 
 			$field_options['sql_filter_type'] = $sql_filter_type;
 			$field_options['value'] = $filter_value;
 
 			return $field_options;
 		}
 
 		/**
 		 * Enter description here...
 		 *
 		 * @param kdbItem $object
 		 * @param string $search_field
 		 * @param string $value
 		 * @param string $type
 		 */
 		function processRangeField(&$object, $search_field, $value, $type)
 		{
 			if (!strlen($value[$type])) {
 				return false;
 			}
 
 			$options = $object->GetFieldOptions($search_field);
 			$dt_separator = array_key_exists('date_time_separator', $options) ? $options['date_time_separator'] : ' ';
 			$value[$type] = trim($value[$type], $dt_separator); // trim any
 
 			$tmp_value = explode($dt_separator, $value[$type], 2);
 			if (count($tmp_value) == 1) {
 				$time_format = $this->_getInputTimeFormat($options);
 				if ($time_format) {
 					// time is missing, but time format available -> guess time and add to date
 					$time = ($type == 'from') ? adodb_mktime(0, 0, 0) : adodb_mktime(23, 59, 59);
 					$time = adodb_date($time_format, $time);
 					$value[$type] .= $dt_separator . $time;
 				}
 			}
 
 			$formatter =& $this->Application->recallObject($object->Fields[$search_field]['formatter']);
 
 			$value_ts = $formatter->Parse($value[$type], $search_field, $object);
 			$pseudo = getArrayValue($object->FieldErrors, $search_field, 'pseudo');
 			if ($pseudo) {
 				unset($object->FieldErrors[$search_field]); // remove error!
 				// invalid format -> ignore this date in search
 				return false;
 			}
 			return $value_ts;
 		}
 
 		/**
 		 * Returns InputTimeFormat using given field options
 		 *
 		 * @param Array $field_options
 		 * @return string
 		 */
 		function _getInputTimeFormat($field_options)
 		{
 			if (array_key_exists('input_time_format', $field_options)) {
 				return $field_options['input_time_format'];
 			}
 
 			$lang_current =& $this->Application->recallObject('lang.current');
 			return $lang_current->GetDBField('InputTimeFormat');
 		}
 
 		/**
 		 * Resets current search
 		 *
 		 * @param kEvent $event
 		 */
 		function resetSearch(&$event)
 		{
 			$this->Application->RemoveVar($event->getPrefixSpecial().'_search_filter');
 			$this->Application->RemoveVar($event->getPrefixSpecial().'_search_keyword');
 
 			$view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view');
 			$this->Application->RemovePersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name);
 		}
 
 		/**
 		 * Creates filters based on "types" & "except" parameters from PrintList
 		 *
 		 * @param kEvent $event
 		 * @param Array $type_clauses
 		 * @param string $types
 		 * @param string $except_types
 		 */
 		function SetComplexFilter(&$event, &$type_clauses, $types, $except_types)
 		{
 			$includes_or_filter =& $this->Application->makeClass('kMultipleFilter', FLT_TYPE_OR);
 			$excepts_and_filter =& $this->Application->makeClass('kMultipleFilter', FLT_TYPE_AND);
 
 			$includes_or_filter_h =& $this->Application->makeClass('kMultipleFilter', FLT_TYPE_OR);
 			$excepts_and_filter_h =& $this->Application->makeClass('kMultipleFilter', FLT_TYPE_AND);
 
 			if ($types) {
 				$types = explode(',', $types);
 				foreach ($types as $type) {
 					$type = trim($type);
 
 					if (isset($type_clauses[$type])) {
 						if ($type_clauses[$type]['having_filter']) {
 							$includes_or_filter_h->addFilter('filter_'.$type, $type_clauses[$type]['include']);
 						} else {
 							$includes_or_filter->addFilter('filter_'.$type, $type_clauses[$type]['include']);
 						}
 					}
 				}
 			}
 
 			if ($except_types) {
 				$except_types = explode(',', $except_types);
 				foreach ($except_types as $type) {
 					$type = trim($type);
 
 					if (isset($type_clauses[$type])) {
 						if ($type_clauses[$type]['having_filter']) {
 							$excepts_and_filter_h->addFilter('filter_'.$type, $type_clauses[$type]['except']);
 						} else {
 							$excepts_and_filter->addFilter('filter_'.$type, $type_clauses[$type]['except']);
 						}
 					}
 				}
 			}
 
 			$object =& $event->getObject();
 
 			$object->addFilter('includes_filter', $includes_or_filter);
 			$object->addFilter('excepts_filter', $excepts_and_filter);
 
 			$object->addFilter('includes_filter_h', $includes_or_filter_h, HAVING_FILTER);
 			$object->addFilter('excepts_filter_h', $excepts_and_filter_h, HAVING_FILTER);
 		}
 	}
 
 ?>
\ No newline at end of file