00001 <?php
00002
00008 class views_handler_filter_search extends views_handler_filter {
00009 var $always_multiple = TRUE;
00010
00016 var $search_query = NULL;
00017
00021 var $parsed = FALSE;
00022
00023 function option_definition() {
00024 $options = parent::option_definition();
00025
00026 $options['operator']['default'] = 'optional';
00027
00028 return $options;
00029 }
00030
00034 function operator_form(&$form, &$form_state) {
00035 $form['operator'] = array(
00036 '#type' => 'radios',
00037 '#title' => t('On empty input'),
00038 '#default_value' => $this->operator,
00039 '#options' => array(
00040 'optional' => t('Show All'),
00041 'required' => t('Show None'),
00042 ),
00043 );
00044 }
00045
00049 function value_form(&$form, &$form_state) {
00050 $form['value'] = array(
00051 '#type' => 'textfield',
00052 '#size' => 15,
00053 '#default_value' => $this->value,
00054 '#attributes' => array('title' => t('Enter the terms you wish to search for.')),
00055 '#title' => empty($form_state['exposed']) ? t('Value') : '',
00056 );
00057 }
00058
00062 function exposed_validate(&$form, &$form_state) {
00063 if (!isset($this->options['expose']['identifier'])) {
00064 return;
00065 }
00066
00067 $key = $this->options['expose']['identifier'];
00068 if (!empty($form_state['values'][$key])) {
00069 $this->query_parse_search_expression($form_state['values'][$key]);
00070 if (count($this->search_query->words()) == 0) {
00071 form_set_error($key, format_plural(variable_get('minimum_word_size', 3), 'You must include at least one positive keyword with 1 character or more.', 'You must include at least one positive keyword with @count characters or more.'));
00072 }
00073 }
00074 }
00075
00082 function query_parse_search_expression($input) {
00083 if (!isset($this->search_query)) {
00084 $this->parsed = TRUE;
00085 $this->search_query = db_select('search_index', 'i', array('target' => 'slave'))->extend('viewsSearchQuery');
00086 $this->search_query->searchExpression($input, $this->view->base_table);
00087 $this->search_query->publicParseSearchExpression();
00088 }
00089 }
00090
00098 function query() {
00099
00100
00101 if (!$this->parsed) {
00102 $this->query_parse_search_expression($this->value);
00103 }
00104 $required = FALSE;
00105 if (!isset($this->search_query)) {
00106 $required = TRUE;
00107 }
00108 else {
00109 $words = $this->search_query->words();
00110 if (empty($words)) {
00111 $required = TRUE;
00112 }
00113 }
00114 if ($required) {
00115 if ($this->operator == 'required') {
00116 $this->query->add_where($this->options['group'], 'FALSE');
00117 }
00118 }
00119 else {
00120 $search_index = $this->ensure_my_table();
00121
00122 $search_condition = db_and();
00123
00124
00125 $join = new views_join;
00126 $join->construct('search_total', $search_index, 'word', 'word');
00127 $search_total = $this->query->add_relationship('search_total', $join, $search_index);
00128
00129 $this->search_score = $this->query->add_field('', "SUM($search_index.score * $search_total.count)", 'score', array('aggregate' => TRUE));
00130
00131 if (empty($this->query->relationships[$this->relationship])) {
00132 $base_table = $this->query->base_table;
00133 }
00134 else {
00135 $base_table = $this->query->relationships[$this->relationship]['base'];
00136 }
00137 $search_condition->condition("$search_index.type", $base_table);
00138 if (!$this->search_query->simple()) {
00139 $search_dataset = $this->query->add_table('search_dataset');
00140 $conditions = $this->search_query->conditions();
00141 $condition_conditions =& $conditions->conditions();
00142 foreach ($condition_conditions as $key => &$condition) {
00143
00144 if (is_numeric($key)) {
00145
00146 $this->search_query->condition_replace_string('d.', "$search_dataset.", $condition);
00147 }
00148 }
00149 $search_conditions =& $search_condition->conditions();
00150 $search_conditions = array_merge($search_conditions, $condition_conditions);
00151 }
00152 else {
00153
00154 $or = db_or();
00155 foreach ($words as $word) {
00156 $or->condition("$search_index.word", $word);
00157 }
00158
00159 $search_condition->condition($or);
00160 }
00161
00162 $this->query->add_where($this->options['group'], $search_condition);
00163 $this->query->add_groupby("$search_index.sid");
00164 $matches = $this->search_query->matches();
00165 $placeholder = $this->placeholder();
00166 $this->query->add_having_expression($this->options['group'], "COUNT(*) >= $placeholder", array($placeholder => $matches));
00167 }
00168
00169 $this->search_query = NULL;
00170 }
00171 }
00172
00173 class viewsSearchQuery extends SearchQuery {
00174 public function &conditions() {
00175 return $this->conditions;
00176 }
00177 public function words() {
00178 return $this->words;
00179 }
00180
00181 public function simple() {
00182 return $this->simple;
00183 }
00184
00185 public function matches() {
00186 return $this->matches;
00187 }
00188
00189 public function publicParseSearchExpression() {
00190 return $this->parseSearchExpression();
00191 }
00192
00193 function condition_replace_string($search, $replace, &$condition) {
00194 if ($condition['field'] instanceof DatabaseCondition) {
00195 $conditions =& $condition['field']->conditions();
00196 foreach ($conditions as $key => &$subcondition) {
00197 if (is_numeric($key)) {
00198 $this->condition_replace_string($search, $replace, $subcondition);
00199 }
00200 }
00201 }
00202 else {
00203 $condition['field'] = str_replace($search, $replace, $condition['field']);
00204 }
00205 }
00206 }