$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.'%"'; break; case '-': foreach ($fields as $field) { $condition[] = $field.' NOT LIKE "%'.$keyword.'%" OR '.$field.' IS NULL'; } $minus_conditions[] = '('.implode(') AND (', $condition).')'; break; case '': $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) { $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 : ''; return Array ('field_name' => $field_name, 'field_type' => $field_type, 'table_name' => $table_name, 'sql_filter_type' => $sql_filter_type); } /** * 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; } } $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) { $search_keywords = $this->splitKeyword($search_keyword); extract( $this->getFieldInformation($object, $field_name) ); // see getFieldInformation for more details $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': $field_processed = true; 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; 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 $custom_filters = $this->Application->RecallVar($event->getPrefixSpecial().'_custom_filter'); 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 = is_array($field_value) ? !implode('', $field_value) : !$field_value; 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->StoreVar($event->getPrefixSpecial().'_custom_filter', serialize($custom_filters) ); return false; } $object =& $event->getObject(); // don't recall it each time in getCustomFilterSearchClause foreach ($custom_filter as $field_name => $field_options) { list ($filter_type, $field_options) = each($field_options); $field_options = $this->getCustomFilterSearchClause($object, $field_name, $filter_type, $field_options); if ($field_options['value']) { $custom_filter[$field_name][$filter_type] = $field_options; } } $custom_filters[$grid_name] = $custom_filter; $this->Application->StoreVar($event->getPrefixSpecial().'_custom_filter', serialize($custom_filters) ); return $custom_filter; } function getCustomFilterSearchClause(&$object, $field_name, $filter_type, $field_options) { 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; 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) { // add equals filter on $from $filter_value = $table_name.'`'.$field_name.'` = '.$from; } elseif ($from === false && $to !== false) { // add equals filter on $to $filter_value = $table_name.'`'.$field_name.'` = '.$to; } break; case 'date_range': break; case 'equals': case 'options': $field_value = $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 '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 kEvent $event * @param string $search_field * @param string $type * @param string $value * @param string $formatter_class */ function processRangeField(&$event, $search_field, $type, $value, $formatter_class) { $field = $search_field.'_'.$type; $lang_current =& $this->Application->recallObject('lang.current'); $object =& $event->getObject(); $dt_separator = getArrayValue( $object->GetFieldOptions($search_field), 'date_time_separator' ); if(!$dt_separator) $dt_separator = ' '; $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; } return $value_ts; } /** * Resets current search * * @param kEvent $event */ function resetSearch(&$event) { $this->Application->RemoveVar($event->getPrefixSpecial().'_search_filter'); $this->Application->RemoveVar($event->getPrefixSpecial().'_search_keyword'); $this->Application->RemoveVar($event->getPrefixSpecial().'_custom_filter'); } } ?>