cms/drupal/modules/search/search.extender.inc
author ymh <ymh.work@gmail.com>
Fri, 08 Sep 2017 12:04:21 +0200
changeset 542 343675b8cc97
parent 541 e756a8c72c3d
permissions -rw-r--r--
Added tag 0.0.21 for changeset e756a8c72c3d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
541
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
<?php
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
/**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
 * @file
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
 * Search query extender and helper functions.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
 */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
/**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
 * Do a query on the full-text search index for a word or words.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
 *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
 * This function is normally only called by each module that supports the
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
 * indexed search (and thus, implements hook_update_index()).
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
 *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
 * Results are retrieved in two logical passes. However, the two passes are
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
 * joined together into a single query. And in the case of most simple
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
 * queries the second pass is not even used.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
 *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
 * The first pass selects a set of all possible matches, which has the benefit
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
 * of also providing the exact result set for simple "AND" or "OR" searches.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
 *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
 * The second portion of the query further refines this set by verifying
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
 * advanced text conditions (such as negative or phrase matches).
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
 *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
 * The used query object has the tag 'search_$module' and can be further
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
 * extended with hook_query_alter().
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
 */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
class SearchQuery extends SelectQueryExtender {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
   * The search query that is used for searching.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
   * @var string
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
  protected $searchExpression;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
   * Type of search (search module).
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
   * This maps to the value of the type column in search_index, and is equal
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
   * to the machine-readable name of the module that implements
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
   * hook_search_info().
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
   * @var string
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
  protected $type;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
   * Positive and negative search keys.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
   * @var array
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
  protected $keys = array('positive' => array(), 'negative' => array());
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
   * Indicates whether the first pass query requires complex conditions (LIKE).
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
   * @var boolean.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
  protected $simple = TRUE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
   * Conditions that are used for exact searches.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
   * This is always used for the second pass query but not for the first pass,
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
   * unless $this->simple is FALSE.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
   * @var DatabaseCondition
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
  protected $conditions;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
   * Indicates how many matches for a search query are necessary.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
   * @var int
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
  protected $matches = 0;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
   * Array of search words.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
   * These words have to match against {search_index}.word.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
   * @var array
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
  protected $words = array();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
   * Multiplier for the normalized search score.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
   * This value is calculated by the first pass query and multiplied with the
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
   * actual score of a specific word to make sure that the resulting calculated
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
   * score is between 0 and 1.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
   * @var float
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
  protected $normalize;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
   * Indicates whether the first pass query has been executed.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
   * @var boolean
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
  protected $executedFirstPass = FALSE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   103
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
   * Stores score expressions.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
   * @var array
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
   * @see addScore()
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
  protected $scores = array();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
   * Stores arguments for score expressions.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
   * @var array
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
  protected $scoresArguments = array();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
   * Stores multipliers for score expressions.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
   * @var array
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   125
  protected $multiply = array();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   128
   * Whether or not search expressions were ignored.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   129
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   130
   * The maximum number of AND/OR combinations exceeded can be configured to
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   131
   * avoid Denial-of-Service attacks. Expressions beyond the limit are ignored.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   132
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   133
   * @var boolean
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   134
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   135
  protected $expressionsIgnored = FALSE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   136
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   137
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   138
   * Sets up the search query expression.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   139
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   140
   * @param $query
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   141
   *   A search query string, which can contain options.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   142
   * @param $module
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   143
   *   The search module. This maps to {search_index}.type in the database.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   144
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   145
   * @return
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   146
   *   The SearchQuery object.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   147
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   148
  public function searchExpression($expression, $module) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   149
    $this->searchExpression = $expression;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   150
    $this->type = $module;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   151
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   152
    // Add a search_* tag. This needs to be added before any preExecute methods
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   153
    // for decorated queries are called, as $this->prepared will be set to TRUE
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   154
    // and tags added in the execute method will never get used. For example,
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   155
    // if $query is extended by 'SearchQuery' then 'PagerDefault', the
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   156
    // search-specific tag will be added too late (when preExecute() has
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   157
    // already been called from the PagerDefault extender), and as a
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   158
    // consequence will not be available to hook_query_alter() implementations,
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   159
    // nor will the correct hook_query_TAG_alter() implementations get invoked.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   160
    // See node_search_execute().
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   161
    $this->addTag('search_' . $module);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   162
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   163
    return $this;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   164
  }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   165
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   166
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   167
   * Applies a search option and removes it from the search query string.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   168
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   169
   * These options are in the form option:value,value2,value3.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   170
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   171
   * @param $option
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   172
   *   Name of the option.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   173
   * @param $column
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   174
   *   Name of the database column to which the value should be applied.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   175
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   176
   * @return
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   177
   *   TRUE if a value for that option was found, FALSE if not.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   178
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   179
  public function setOption($option, $column) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   180
    if ($values = search_expression_extract($this->searchExpression, $option)) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   181
      $or = db_or();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   182
      foreach (explode(',', $values) as $value) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   183
        $or->condition($column, $value);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   184
      }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   185
      $this->condition($or);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   186
      $this->searchExpression = search_expression_insert($this->searchExpression, $option);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   187
      return TRUE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   188
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   189
    return FALSE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   190
  }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   191
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   192
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   193
   * Parses the search query into SQL conditions.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   194
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   195
   * We build two queries that match the dataset bodies.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   196
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   197
  protected function parseSearchExpression() {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   198
    // Matchs words optionally prefixed by a dash. A word in this case is
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   199
    // something between two spaces, optionally quoted.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   200
    preg_match_all('/ (-?)("[^"]+"|[^" ]+)/i', ' ' .  $this->searchExpression , $keywords, PREG_SET_ORDER);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   201
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   202
    if (count($keywords) ==  0) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   203
      return;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   204
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   205
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   206
    // Classify tokens.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   207
    $or = FALSE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   208
    $warning = '';
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   209
    $limit_combinations = variable_get('search_and_or_limit', 7);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   210
    // The first search expression does not count as AND.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   211
    $and_count = -1;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   212
    $or_count = 0;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   213
    foreach ($keywords as $match) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   214
      if ($or_count && $and_count + $or_count >= $limit_combinations) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   215
        // Ignore all further search expressions to prevent Denial-of-Service
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   216
        // attacks using a high number of AND/OR combinations.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   217
        $this->expressionsIgnored = TRUE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   218
        break;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   219
      }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   220
      $phrase = FALSE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   221
      // Strip off phrase quotes.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   222
      if ($match[2]{0} == '"') {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   223
        $match[2] = substr($match[2], 1, -1);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   224
        $phrase = TRUE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   225
        $this->simple = FALSE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   226
      }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   227
      // Simplify keyword according to indexing rules and external
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   228
      // preprocessors. Use same process as during search indexing, so it
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   229
      // will match search index.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   230
      $words = search_simplify($match[2]);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   231
      // Re-explode in case simplification added more words, except when
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   232
      // matching a phrase.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   233
      $words = $phrase ? array($words) : preg_split('/ /', $words, -1, PREG_SPLIT_NO_EMPTY);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   234
      // Negative matches.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   235
      if ($match[1] == '-') {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   236
        $this->keys['negative'] = array_merge($this->keys['negative'], $words);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   237
      }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   238
      // OR operator: instead of a single keyword, we store an array of all
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   239
      // OR'd keywords.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   240
      elseif ($match[2] == 'OR' && count($this->keys['positive'])) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   241
        $last = array_pop($this->keys['positive']);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   242
        // Starting a new OR?
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   243
        if (!is_array($last)) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   244
          $last = array($last);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   245
        }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   246
        $this->keys['positive'][] = $last;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   247
        $or = TRUE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   248
        $or_count++;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   249
        continue;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   250
      }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   251
      // AND operator: implied, so just ignore it.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   252
      elseif ($match[2] == 'AND' || $match[2] == 'and') {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   253
        $warning = $match[2];
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   254
        continue;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   255
      }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   256
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   257
      // Plain keyword.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   258
      else {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   259
        if ($match[2] == 'or') {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   260
          $warning = $match[2];
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   261
        }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   262
        if ($or) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   263
          // Add to last element (which is an array).
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   264
          $this->keys['positive'][count($this->keys['positive']) - 1] = array_merge($this->keys['positive'][count($this->keys['positive']) - 1], $words);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   265
        }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   266
        else {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   267
          $this->keys['positive'] = array_merge($this->keys['positive'], $words);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   268
          $and_count++;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   269
        }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   270
      }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   271
      $or = FALSE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   272
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   273
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   274
    // Convert keywords into SQL statements.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   275
    $this->conditions = db_and();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   276
    $simple_and = FALSE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   277
    $simple_or = FALSE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   278
    // Positive matches.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   279
    foreach ($this->keys['positive'] as $key) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   280
      // Group of ORed terms.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   281
      if (is_array($key) && count($key)) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   282
        $simple_or = TRUE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   283
        $any = FALSE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   284
        $queryor = db_or();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   285
        foreach ($key as $or) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   286
          list($num_new_scores) = $this->parseWord($or);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   287
          $any |= $num_new_scores;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   288
          $queryor->condition('d.data', "% $or %", 'LIKE');
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   289
        }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   290
        if (count($queryor)) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   291
          $this->conditions->condition($queryor);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   292
          // A group of OR keywords only needs to match once.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   293
          $this->matches += ($any > 0);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   294
        }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   295
      }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   296
      // Single ANDed term.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   297
      else {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   298
        $simple_and = TRUE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   299
        list($num_new_scores, $num_valid_words) = $this->parseWord($key);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   300
        $this->conditions->condition('d.data', "% $key %", 'LIKE');
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   301
        if (!$num_valid_words) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   302
          $this->simple = FALSE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   303
        }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   304
        // Each AND keyword needs to match at least once.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   305
        $this->matches += $num_new_scores;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   306
      }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   307
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   308
    if ($simple_and && $simple_or) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   309
      $this->simple = FALSE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   310
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   311
    // Negative matches.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   312
    foreach ($this->keys['negative'] as $key) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   313
      $this->conditions->condition('d.data', "% $key %", 'NOT LIKE');
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   314
      $this->simple = FALSE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   315
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   316
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   317
    if ($warning == 'or') {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   318
      drupal_set_message(t('Search for either of the two terms with uppercase <strong>OR</strong>. For example, <strong>cats OR dogs</strong>.'));
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   319
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   320
  }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   321
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   322
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   323
   * Helper function for parseQuery().
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   324
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   325
  protected function parseWord($word) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   326
    $num_new_scores = 0;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   327
    $num_valid_words = 0;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   328
    // Determine the scorewords of this word/phrase.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   329
    $split = explode(' ', $word);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   330
    foreach ($split as $s) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   331
      $num = is_numeric($s);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   332
      if ($num || drupal_strlen($s) >= variable_get('minimum_word_size', 3)) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   333
        if (!isset($this->words[$s])) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   334
          $this->words[$s] = $s;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   335
          $num_new_scores++;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   336
        }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   337
        $num_valid_words++;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   338
      }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   339
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   340
    // Return matching snippet and number of added words.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   341
    return array($num_new_scores, $num_valid_words);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   342
  }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   343
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   344
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   345
   * Executes the first pass query.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   346
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   347
   * This can either be done explicitly, so that additional scores and
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   348
   * conditions can be applied to the second pass query, or implicitly by
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   349
   * addScore() or execute().
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   350
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   351
   * @return
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   352
   *   TRUE if search items exist, FALSE if not.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   353
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   354
  public function executeFirstPass() {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   355
    $this->parseSearchExpression();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   356
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   357
    if (count($this->words) == 0) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   358
      form_set_error('keys', 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.'));
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   359
      return FALSE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   360
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   361
    if ($this->expressionsIgnored) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   362
      drupal_set_message(t('Your search used too many AND/OR expressions. Only the first @count terms were included in this search.', array('@count' => variable_get('search_and_or_limit', 7))), 'warning');
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   363
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   364
    $this->executedFirstPass = TRUE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   365
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   366
    if (!empty($this->words)) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   367
      $or = db_or();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   368
      foreach ($this->words as $word) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   369
        $or->condition('i.word', $word);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   370
      }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   371
      $this->condition($or);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   372
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   373
    // Build query for keyword normalization.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   374
    $this->join('search_total', 't', 'i.word = t.word');
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   375
    $this
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   376
      ->condition('i.type', $this->type)
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   377
      ->groupBy('i.type')
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   378
      ->groupBy('i.sid')
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   379
      ->having('COUNT(*) >= :matches', array(':matches' => $this->matches));
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   380
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   381
    // Clone the query object to do the firstPass query;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   382
    $first = clone $this->query;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   383
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   384
    // For complex search queries, add the LIKE conditions to the first pass query.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   385
    if (!$this->simple) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   386
      $first->join('search_dataset', 'd', 'i.sid = d.sid AND i.type = d.type');
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   387
      $first->condition($this->conditions);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   388
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   389
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   390
    // Calculate maximum keyword relevance, to normalize it.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   391
    $first->addExpression('SUM(i.score * t.count)', 'calculated_score');
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   392
    $this->normalize = $first
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   393
      ->range(0, 1)
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   394
      ->orderBy('calculated_score', 'DESC')
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   395
      ->execute()
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   396
      ->fetchField();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   397
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   398
    if ($this->normalize) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   399
      return TRUE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   400
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   401
    return FALSE;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   402
  }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   403
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   404
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   405
   * Adds a custom score expression to the search query.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   406
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   407
   * Score expressions are used to order search results. If no calls to
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   408
   * addScore() have taken place, a default keyword relevance score will be
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   409
   * used. However, if at least one call to addScore() has taken place, the
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   410
   * keyword relevance score is not automatically added.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   411
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   412
   * Note that you must use this method to add ordering to your searches, and
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   413
   * not call orderBy() directly, when using the SearchQuery extender. This is
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   414
   * because of the two-pass system the SearchQuery class uses to normalize
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   415
   * scores.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   416
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   417
   * @param $score
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   418
   *   The score expression, which should evaluate to a number between 0 and 1.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   419
   *   The string 'i.relevance' in a score expression will be replaced by a
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   420
   *   measure of keyword relevance between 0 and 1.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   421
   * @param $arguments
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   422
   *   Query arguments needed to provide values to the score expression.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   423
   * @param $multiply
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   424
   *   If set, the score is multiplied with this value. However, all scores
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   425
   *   with multipliers are then divided by the total of all multipliers, so
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   426
   *   that overall, the normalization is maintained.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   427
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   428
   * @return object
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   429
   *   The updated query object.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   430
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   431
  public function addScore($score, $arguments = array(), $multiply = FALSE) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   432
    if ($multiply) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   433
      $i = count($this->multiply);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   434
      // Modify the score expression so it is multiplied by the multiplier,
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   435
      // with a divisor to renormalize.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   436
      $score = "CAST(:multiply_$i AS DECIMAL) * COALESCE(( " . $score . "), 0) / CAST(:total_$i AS DECIMAL)";
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   437
      // Add an argument for the multiplier. The :total_$i argument is taken
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   438
      // care of in the execute() method, which is when the total divisor is
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   439
      // calculated.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   440
      $arguments[':multiply_' . $i] = $multiply;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   441
      $this->multiply[] = $multiply;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   442
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   443
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   444
    $this->scores[] = $score;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   445
    $this->scoresArguments += $arguments;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   446
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   447
    return $this;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   448
  }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   449
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   450
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   451
   * Executes the search.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   452
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   453
   * If not already done, this executes the first pass query. Then the complex
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   454
   * conditions are applied to the query including score expressions and
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   455
   * ordering.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   456
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   457
   * @return
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   458
   *   FALSE if the first pass query returned no results, and a database result
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   459
   *   set if there were results.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   460
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   461
  public function execute()
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   462
  {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   463
    if (!$this->executedFirstPass) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   464
      $this->executeFirstPass();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   465
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   466
    if (!$this->normalize) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   467
      return new DatabaseStatementEmpty();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   468
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   469
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   470
    // Add conditions to query.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   471
    $this->join('search_dataset', 'd', 'i.sid = d.sid AND i.type = d.type');
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   472
    $this->condition($this->conditions);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   473
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   474
    if (empty($this->scores)) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   475
      // Add default score.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   476
      $this->addScore('i.relevance');
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   477
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   478
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   479
    if (count($this->multiply)) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   480
      // Re-normalize scores with multipliers by dividing by the total of all
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   481
      // multipliers. The expressions were altered in addScore(), so here just
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   482
      // add the arguments for the total.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   483
      $i = 0;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   484
      $sum = array_sum($this->multiply);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   485
      foreach ($this->multiply as $total) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   486
        $this->scoresArguments[':total_' . $i] = $sum;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   487
        $i++;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   488
      }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   489
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   490
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   491
    // Replace the pseudo-expression 'i.relevance' with a measure of keyword
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   492
    // relevance in all score expressions, using string replacement. Careful
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   493
    // though! If you just print out a float, some locales use ',' as the
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   494
    // decimal separator in PHP, while SQL always uses '.'. So, make sure to
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   495
    // set the number format correctly.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   496
    $relevance = number_format((1.0 / $this->normalize), 10, '.', '');
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   497
    $this->scores = str_replace('i.relevance', '(' . $relevance . ' * i.score * t.count)', $this->scores);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   498
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   499
    // Add all scores together to form a query field.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   500
    $this->addExpression('SUM(' . implode(' + ', $this->scores) . ')', 'calculated_score', $this->scoresArguments);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   501
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   502
    // If an order has not yet been set for this query, add a default order
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   503
    // that sorts by the calculated sum of scores.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   504
    if (count($this->getOrderBy()) == 0) {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   505
      $this->orderBy('calculated_score', 'DESC');
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   506
    }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   507
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   508
    // Add useful metadata.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   509
    $this
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   510
      ->addMetaData('normalize', $this->normalize)
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   511
      ->fields('i', array('type', 'sid'));
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   512
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   513
    return $this->query->execute();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   514
  }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   515
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   516
  /**
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   517
   * Builds the default count query for SearchQuery.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   518
   *
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   519
   * Since SearchQuery always uses GROUP BY, we can default to a subquery. We
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   520
   * also add the same conditions as execute() because countQuery() is called
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   521
   * first.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   522
   */
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   523
  public function countQuery() {
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   524
    // Clone the inner query.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   525
    $inner = clone $this->query;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   526
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   527
    // Add conditions to query.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   528
    $inner->join('search_dataset', 'd', 'i.sid = d.sid AND i.type = d.type');
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   529
    $inner->condition($this->conditions);
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   530
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   531
    // Remove existing fields and expressions, they are not needed for a count
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   532
    // query.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   533
    $fields =& $inner->getFields();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   534
    $fields = array();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   535
    $expressions =& $inner->getExpressions();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   536
    $expressions = array();
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   537
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   538
    // Add the sid as the only field and count them as a subquery.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   539
    $count = db_select($inner->fields('i', array('sid')), NULL, array('target' => 'slave'));
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   540
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   541
    // Add the COUNT() expression.
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   542
    $count->addExpression('COUNT(*)');
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   543
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   544
    return $count;
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   545
  }
e756a8c72c3d integrate drupal and correct build process. update version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   546
}