• Main Page
  • Related Pages
  • Modules
  • Classes
  • Files
  • File List
  • File Members

modules/search/views_handler_filter_search.inc

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     // Since attachment views don't validate the exposed input, parse the search
00100     // expression if required.
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       // Create a new join to relate the 'serach_total' table to our current 'search_index' table.
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           // Take sure we just look at real conditions.
00144           if (is_numeric($key)) {
00145             // Replace the conditions with the table alias of views.
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         // Stores each condition, so and/or on the filter level will still work.
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     // Set to NULL to prevent PDO exception when views object is cached.
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 }

Generated on Sun Feb 26 2012 12:52:51 for Views by  doxygen 1.7.1