Index: branches/unlabeled/unlabeled-1.4.2/core/units/general/helpers/search_helper.php =================================================================== diff -u -r6788 -r6849 --- branches/unlabeled/unlabeled-1.4.2/core/units/general/helpers/search_helper.php (.../search_helper.php) (revision 6788) +++ branches/unlabeled/unlabeled-1.4.2/core/units/general/helpers/search_helper.php (.../search_helper.php) (revision 6849) @@ -150,6 +150,9 @@ 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) ); } @@ -213,29 +216,9 @@ break; case 'kDateFormatter': - $field_processed = true; + // if date is searched using direct filter, then do nothing here, otherwise search using LIKE clause + $field_processed = ($custom_search !== false) ? true : false; break; - - /*case 'kDateFormatter': // move to Custom Filters (by Alex) - $filter_value = Array(); - if ($field_name === false) { - $field_value = getArrayValue($custom_filter, $field_name.'_datefrom', 'submit_value'); - if ($field_value) { - $value = $this->processRangeField($event, $field_name, 'datefrom', $field_value, $formatter); - $filter_value[] = $table_name.'`'.$field_name.'` >= '.$value; - } - - $field_value = getArrayValue($custom_filter, $field_name.'_dateto', 'submit_value'); - if ($field_value) { - $value = $this->processRangeField($event, $field_name, 'dateto', $field_value, $formatter); - $filter_value[] = $table_name.'`'.$field_name.'` <= '.$value; - } - - $filter_value = $filter_value ? '('.implode(') AND (', $filter_value).')' : ''; - } - - $field_processed = true; - break;*/ default: $field_processed = false; @@ -299,7 +282,8 @@ $grid_name = $this->Application->GetVar('grid_name'); // update "custom filter" with values from submit: begin - $custom_filters = $this->Application->RecallVar($event->getPrefixSpecial().'_custom_filter'); + $view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view'); + $custom_filters = $this->Application->RecallPersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name); if ($custom_filters) { $custom_filters = unserialize($custom_filters); $custom_filter = isset($custom_filters[$grid_name]) ? $custom_filters[$grid_name] : Array (); @@ -344,50 +328,102 @@ if (!$custom_filter) { // in case when no filters specified, there are nothing to process - $this->Application->StoreVar($event->getPrefixSpecial().'_custom_filter', serialize($custom_filters) ); + $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->StoreVar($event->getPrefixSpecial().'_custom_filter', serialize($custom_filters) ); + $this->Application->StorePersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name, serialize($custom_filters) ); return $custom_filter; } + /** + * Return numeric range filter value + checking that it's number + * + * @param Array $value array containing range filter value + * @return unknown + */ + function getRangeValue($value) + { + return $value && is_numeric($value) ? $this->Conn->qstr($value) : false; + } + function getCustomFilterSearchClause(&$object, $field_name, $filter_type, $field_options) { + if ($filter_type == 'date_range') { + // use timestamp field, not formatted one + $field_name = $field_options['grid_options']['sort_field']; + } + extract( $this->getFieldInformation($object, $field_name) ); // see getFieldInformation for more details $filter_value = ''; switch ($filter_type) { case 'range': - $from = $field_options['submit_value']['from'] ? $this->Conn->qstr($field_options['submit_value']['from']) : false; - $to = $field_options['submit_value']['to'] ? $this->Conn->qstr($field_options['submit_value']['to']) : false; + $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 && $to === false) { + elseif ($from !== false) { // add equals filter on $from $filter_value = $table_name.'`'.$field_name.'` = '.$from; } - elseif ($from === false && $to !== false) { + 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) { + $to = $from + $day_seconds; + } + elseif ($from === false && $to !== false) { + $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': @@ -415,33 +451,36 @@ /** * Enter description here... * - * @param kEvent $event + * @param kdbItem $object * @param string $search_field - * @param string $type * @param string $value - * @param string $formatter_class + * @param string $type */ - function processRangeField(&$event, $search_field, $type, $value, $formatter_class) + function processRangeField(&$object, $search_field, $value, $type) { - $field = $search_field.'_'.$type; + if (!$value[$type]) { + return false; + } + $lang_current =& $this->Application->recallObject('lang.current'); + $dt_separator = getArrayValue($object->GetFieldOptions($search_field), 'date_time_separator'); + if (!$dt_separator) { + $dt_separator = ' '; + } + + $time = ($type == 'from') ? adodb_mktime(0, 0, 0) : adodb_mktime(23, 59, 59); + $time = adodb_date($lang_current->GetDBField('InputTimeFormat'), $time); + + $full_value = $value[$type].$dt_separator.$time; - $object =& $event->getObject(); - $dt_separator = getArrayValue( $object->GetFieldOptions($search_field), 'date_time_separator' ); - if(!$dt_separator) $dt_separator = ' '; + $formatter =& $this->Application->recallObject($object->Fields[$search_field]['formatter']); - $time = ($type == 'datefrom') ? adodb_mktime(0,0,0) : adodb_mktime(23,59,59); - $time = adodb_date( $lang_current->GetDBField('InputTimeFormat'), $time); - $full_value = $value.$dt_separator.$time; - - $formatter =& $this->Application->recallObject($formatter_class); - $value_ts = $formatter->Parse($full_value, $search_field, $object); $pseudo = getArrayValue($object->FieldErrors, $search_field, 'pseudo'); - if($pseudo) - { - $this->Application->StoreVar($event->getPrefixSpecial().'_'.$field.'_error', $pseudo); - return -1; + if ($pseudo) { + unset($object->FieldErrors[$search_field]); // remove error! + // invalid format -> ignore this date in search + return false; } return $value_ts; } @@ -456,7 +495,8 @@ $this->Application->RemoveVar($event->getPrefixSpecial().'_search_filter'); $this->Application->RemoveVar($event->getPrefixSpecial().'_search_keyword'); - $this->Application->RemoveVar($event->getPrefixSpecial().'_custom_filter'); + $view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view'); + $this->Application->RemovePersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name); }