Projet

Général

Profil

Paste
Télécharger (10,1 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / views / handlers / views_handler_filter_string.inc @ 5d12d676

1
<?php
2

    
3
/**
4
 * @file
5
 * Definition of views_handler_filter_string.
6
 */
7

    
8
/**
9
 * Basic textfield filter to handle string filtering commands
10
 * including equality, like, not like, etc.
11
 *
12
 * @ingroup views_filter_handlers
13
 */
14
class views_handler_filter_string extends views_handler_filter {
15

    
16
  /**
17
   * Exposed filter options.
18
   */
19
  public $always_multiple = TRUE;
20

    
21
  /**
22
   * {@inheritdoc}
23
   */
24
  public function option_definition() {
25
    $options = parent::option_definition();
26

    
27
    $options['expose']['contains']['required'] = array('default' => FALSE, 'bool' => TRUE);
28

    
29
    return $options;
30
  }
31

    
32
  /**
33
   * This kind of construct makes it relatively easy for a child class to add or
34
   * remove functionality by overriding this function and adding/removing items
35
   * from this array.
36
   */
37
  public function operators() {
38
    $operators = array(
39
      '=' => array(
40
        'title' => t('Is equal to'),
41
        'short' => t('='),
42
        'method' => 'op_equal',
43
        'values' => 1,
44
      ),
45
      '!=' => array(
46
        'title' => t('Is not equal to'),
47
        'short' => t('!='),
48
        'method' => 'op_equal',
49
        'values' => 1,
50
      ),
51
      'contains' => array(
52
        'title' => t('Contains'),
53
        'short' => t('contains'),
54
        'method' => 'op_contains',
55
        'values' => 1,
56
      ),
57
      'word' => array(
58
        'title' => t('Contains any word'),
59
        'short' => t('has word'),
60
        'method' => 'op_word',
61
        'values' => 1,
62
      ),
63
      'allwords' => array(
64
        'title' => t('Contains all words'),
65
        'short' => t('has all'),
66
        'method' => 'op_word',
67
        'values' => 1,
68
      ),
69
      'starts' => array(
70
        'title' => t('Starts with'),
71
        'short' => t('begins'),
72
        'method' => 'op_starts',
73
        'values' => 1,
74
      ),
75
      'not_starts' => array(
76
        'title' => t('Does not start with'),
77
        'short' => t('not_begins'),
78
        'method' => 'op_not_starts',
79
        'values' => 1,
80
      ),
81
      'ends' => array(
82
        'title' => t('Ends with'),
83
        'short' => t('ends'),
84
        'method' => 'op_ends',
85
        'values' => 1,
86
      ),
87
      'not_ends' => array(
88
        'title' => t('Does not end with'),
89
        'short' => t('not_ends'),
90
        'method' => 'op_not_ends',
91
        'values' => 1,
92
      ),
93
      'not' => array(
94
        'title' => t('Does not contain'),
95
        'short' => t('!has'),
96
        'method' => 'op_not',
97
        'values' => 1,
98
      ),
99
      'shorterthan' => array(
100
        'title' => t('Length is shorter than'),
101
        'short' => t('shorter than'),
102
        'method' => 'op_shorter',
103
        'values' => 1,
104
      ),
105
      'longerthan' => array(
106
        'title' => t('Length is longer than'),
107
        'short' => t('longer than'),
108
        'method' => 'op_longer',
109
        'values' => 1,
110
      ),
111
    );
112
    // If the definition allows for the empty operator, add it.
113
    if (!empty($this->definition['allow empty'])) {
114
      $operators += array(
115
        'empty' => array(
116
          'title' => t('Is empty (NULL)'),
117
          'method' => 'op_empty',
118
          'short' => t('empty'),
119
          'values' => 0,
120
        ),
121
        'not empty' => array(
122
          'title' => t('Is not empty (NOT NULL)'),
123
          'method' => 'op_empty',
124
          'short' => t('not empty'),
125
          'values' => 0,
126
        ),
127
      );
128
    }
129
    // Add regexp support for MySQL.
130
    if (Database::getConnection()->databaseType() == 'mysql') {
131
      $operators += array(
132
        'regular_expression' => array(
133
          'title' => t('Regular expression'),
134
          'short' => t('regex'),
135
          'method' => 'op_regex',
136
          'values' => 1,
137
        ),
138
      );
139
    }
140

    
141
    return $operators;
142
  }
143

    
144
  /**
145
   * Build strings from the operators() for 'select' options.
146
   */
147
  public function operator_options($which = 'title') {
148
    $options = array();
149
    foreach ($this->operators() as $id => $info) {
150
      $options[$id] = $info[$which];
151
    }
152

    
153
    return $options;
154
  }
155

    
156
  /**
157
   * {@inheritdoc}
158
   */
159
  public function admin_summary() {
160
    if ($this->is_a_group()) {
161
      return t('grouped');
162
    }
163
    if (!empty($this->options['exposed'])) {
164
      return t('exposed');
165
    }
166

    
167
    $options = $this->operator_options('short');
168
    $output = '';
169
    if (!empty($options[$this->operator])) {
170
      $output = check_plain($options[$this->operator]);
171
    }
172
    if (in_array($this->operator, $this->operator_values(1))) {
173
      $output .= ' ' . check_plain($this->value);
174
    }
175
    return $output;
176
  }
177

    
178
  /**
179
   * {@inheritdoc}
180
   */
181
  public function operator_values($values = 1) {
182
    $options = array();
183
    foreach ($this->operators() as $id => $info) {
184
      if (isset($info['values']) && $info['values'] == $values) {
185
        $options[] = $id;
186
      }
187
    }
188

    
189
    return $options;
190
  }
191

    
192
  /**
193
   * Provide a simple textfield for equality.
194
   */
195
  public function value_form(&$form, &$form_state) {
196
    // We have to make some choices when creating this as an exposed filter
197
    // form. For example, if the operator is locked and thus not rendered, we
198
    // can't render dependencies; instead we only render the form items we need.
199
    $which = 'all';
200
    if (!empty($form['operator'])) {
201
      $source = ($form['operator']['#type'] == 'radios') ? 'radio:options[operator]' : 'edit-options-operator';
202
    }
203
    if (!empty($form_state['exposed'])) {
204
      $identifier = $this->options['expose']['identifier'];
205

    
206
      if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator_id'])) {
207
        // exposed and locked.
208
        $which = in_array($this->operator, $this->operator_values(1)) ? 'value' : 'none';
209
      }
210
      else {
211
        $source = 'edit-' . drupal_html_id($this->options['expose']['operator_id']);
212
      }
213
    }
214

    
215
    if ($which == 'all' || $which == 'value') {
216
      $form['value'] = array(
217
        '#type' => 'textfield',
218
        '#title' => t('Value'),
219
        '#size' => 30,
220
        '#default_value' => $this->value,
221
      );
222
      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) {
223
        $form_state['input'][$identifier] = $this->value;
224
      }
225

    
226
      if ($which == 'all') {
227
        $form['value'] += array(
228
          '#dependency' => array($source => $this->operator_values(1)),
229
        );
230
      }
231
    }
232

    
233
    if (!isset($form['value'])) {
234
      // Ensure there is something in the 'value'.
235
      $form['value'] = array(
236
        '#type' => 'value',
237
        '#value' => NULL,
238
      );
239
    }
240
  }
241

    
242
  /**
243
   * {@inheritdoc}
244
   */
245
  public function operator() {
246
    return $this->operator == '=' ? 'LIKE' : 'NOT LIKE';
247
  }
248

    
249
  /**
250
   * Add this filter to the query.
251
   *
252
   * Due to the nature of FAPI, the value and the operator have an unintended
253
   * level of indirection. You will find them in $this->operator and
254
   * $this->value respectively.
255
   */
256
  public function query() {
257
    $this->ensure_my_table();
258
    $field = "$this->table_alias.$this->real_field";
259

    
260
    $info = $this->operators();
261
    if (!empty($info[$this->operator]['method'])) {
262
      $this->{$info[$this->operator]['method']}($field);
263
    }
264
  }
265

    
266
  /**
267
   * {@inheritdoc}
268
   */
269
  public function op_equal($field) {
270
    $this->query->add_where($this->options['group'], $field, $this->value, $this->operator());
271
  }
272

    
273
  /**
274
   * {@inheritdoc}
275
   */
276
  public function op_contains($field) {
277
    $this->query->add_where($this->options['group'], $field, '%' . db_like($this->value) . '%', 'LIKE');
278
  }
279

    
280
  /**
281
   * {@inheritdoc}
282
   */
283
  public function op_word($field) {
284
    $where = $this->operator == 'word' ? db_or() : db_and();
285

    
286
    // Don't filter on empty strings.
287
    if (empty($this->value)) {
288
      return;
289
    }
290

    
291
    preg_match_all('/ (-?)("[^"]+"|[^" ]+)/i', ' ' . $this->value, $matches, PREG_SET_ORDER);
292
    foreach ($matches as $match) {
293
      $phrase = FALSE;
294
      // Strip off phrase quotes
295
      if ($match[2]{0} == '"') {
296
        $match[2] = substr($match[2], 1, -1);
297
        $phrase = TRUE;
298
      }
299
      $words = trim($match[2], ',?!();:-');
300
      $words = $phrase ? array($words) : preg_split('/ /', $words, -1, PREG_SPLIT_NO_EMPTY);
301
      foreach ($words as $word) {
302
        $placeholder = $this->placeholder();
303
        $where->condition($field, '%' . db_like(trim($word, " ,!?")) . '%', 'LIKE');
304
      }
305
    }
306

    
307
    if (!$where) {
308
      return;
309
    }
310

    
311
    // Previously this was a call_user_func_array but that's unnecessary as
312
    // Views will unpack an array that is a single arg.
313
    $this->query->add_where($this->options['group'], $where);
314
  }
315

    
316
  /**
317
   * {@inheritdoc}
318
   */
319
  public function op_starts($field) {
320
    $this->query->add_where($this->options['group'], $field, db_like($this->value) . '%', 'LIKE');
321
  }
322

    
323
  /**
324
   * {@inheritdoc}
325
   */
326
  public function op_not_starts($field) {
327
    $this->query->add_where($this->options['group'], $field, db_like($this->value) . '%', 'NOT LIKE');
328
  }
329

    
330
  /**
331
   * {@inheritdoc}
332
   */
333
  public function op_ends($field) {
334
    $this->query->add_where($this->options['group'], $field, '%' . db_like($this->value), 'LIKE');
335
  }
336

    
337
  /**
338
   * {@inheritdoc}
339
   */
340
  public function op_not_ends($field) {
341
    $this->query->add_where($this->options['group'], $field, '%' . db_like($this->value), 'NOT LIKE');
342
  }
343

    
344
  /**
345
   * {@inheritdoc}
346
   */
347
  public function op_not($field) {
348
    $this->query->add_where($this->options['group'], $field, '%' . db_like($this->value) . '%', 'NOT LIKE');
349
  }
350

    
351
  /**
352
   * {@inheritdoc}
353
   */
354
  public function op_shorter($field) {
355
    $placeholder = $this->placeholder();
356
    $this->query->add_where_expression($this->options['group'], "LENGTH($field) < $placeholder", array($placeholder => $this->value));
357
  }
358

    
359
  /**
360
   * {@inheritdoc}
361
   */
362
  public function op_longer($field) {
363
    $placeholder = $this->placeholder();
364
    $this->query->add_where_expression($this->options['group'], "LENGTH($field) > $placeholder", array($placeholder => $this->value));
365
  }
366

    
367
  /**
368
   * {@inheritdoc}
369
   */
370
  public function op_regex($field) {
371
    $this->query->add_where($this->options['group'], $field, $this->value, 'RLIKE');
372
  }
373

    
374
  /**
375
   * {@inheritdoc}
376
   */
377
  public function op_empty($field) {
378
    if ($this->operator == 'empty') {
379
      $operator = "IS NULL";
380
    }
381
    else {
382
      $operator = "IS NOT NULL";
383
    }
384

    
385
    $this->query->add_where($this->options['group'], $field, NULL, $operator);
386
  }
387

    
388
}