Projet

Général

Profil

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

root / drupal7 / sites / all / modules / views / handlers / views_handler_filter_string.inc @ 4003efde

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
        'not_regular_expression' => array(
139
          'title' => t('Not regular expression'),
140
          'short' => t('not regex'),
141
          'method' => 'op_not_regex',
142
          'values' => 1,
143
        ),
144
      );
145
    }
146

    
147
    return $operators;
148
  }
149

    
150
  /**
151
   * Build strings from the operators() for 'select' options.
152
   */
153
  public function operator_options($which = 'title') {
154
    $options = array();
155
    foreach ($this->operators() as $id => $info) {
156
      $options[$id] = $info[$which];
157
    }
158

    
159
    return $options;
160
  }
161

    
162
  /**
163
   * {@inheritdoc}
164
   */
165
  public function admin_summary() {
166
    if ($this->is_a_group()) {
167
      return t('grouped');
168
    }
169
    if (!empty($this->options['exposed'])) {
170
      return t('exposed');
171
    }
172

    
173
    $options = $this->operator_options('short');
174
    $output = '';
175
    if (!empty($options[$this->operator])) {
176
      $output = check_plain($options[$this->operator]);
177
    }
178
    if (in_array($this->operator, $this->operator_values(1))) {
179
      $output .= ' ' . check_plain($this->value);
180
    }
181
    return $output;
182
  }
183

    
184
  /**
185
   * {@inheritdoc}
186
   */
187
  public function operator_values($values = 1) {
188
    $options = array();
189
    foreach ($this->operators() as $id => $info) {
190
      if (isset($info['values']) && $info['values'] == $values) {
191
        $options[] = $id;
192
      }
193
    }
194

    
195
    return $options;
196
  }
197

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

    
212
      if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator_id'])) {
213
        // exposed and locked.
214
        $which = in_array($this->operator, $this->operator_values(1)) ? 'value' : 'none';
215
      }
216
      else {
217
        $source = 'edit-' . drupal_html_id($this->options['expose']['operator_id']);
218
      }
219
    }
220

    
221
    if ($which == 'all' || $which == 'value') {
222
      $form['value'] = array(
223
        '#type' => 'textfield',
224
        '#title' => t('Value'),
225
        '#size' => 30,
226
        '#default_value' => $this->value,
227
      );
228
      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) {
229
        $form_state['input'][$identifier] = $this->value;
230
      }
231

    
232
      if ($which == 'all') {
233
        $form['value'] += array(
234
          '#dependency' => array($source => $this->operator_values(1)),
235
        );
236
      }
237
    }
238

    
239
    if (!isset($form['value'])) {
240
      // Ensure there is something in the 'value'.
241
      $form['value'] = array(
242
        '#type' => 'value',
243
        '#value' => NULL,
244
      );
245
    }
246
  }
247

    
248
  /**
249
   * {@inheritdoc}
250
   */
251
  public function operator() {
252
    return $this->operator == '=' ? 'LIKE' : 'NOT LIKE';
253
  }
254

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

    
266
    $info = $this->operators();
267
    if (!empty($info[$this->operator]['method'])) {
268
      $this->{$info[$this->operator]['method']}($field);
269
    }
270
  }
271

    
272
  /**
273
   * {@inheritdoc}
274
   */
275
  public function op_equal($field) {
276
    $this->query->add_where($this->options['group'], $field, $this->value, $this->operator());
277
  }
278

    
279
  /**
280
   * {@inheritdoc}
281
   */
282
  public function op_contains($field) {
283
    if (!empty($this->value)) {
284
      $this->query->add_where($this->options['group'], $field, '%' . db_like($this->value) . '%', 'LIKE');
285
    }
286
  }
287

    
288
  /**
289
   * {@inheritdoc}
290
   */
291
  public function op_word($field) {
292
    $where = $this->operator == 'word' ? db_or() : db_and();
293

    
294
    // Don't filter on empty strings.
295
    if (empty($this->value)) {
296
      return;
297
    }
298

    
299
    preg_match_all('/ (-?)("[^"]+"|[^" ]+)/i', ' ' . $this->value, $matches, PREG_SET_ORDER);
300
    foreach ($matches as $match) {
301
      $phrase = FALSE;
302
      // Strip off phrase quotes
303
      if ($match[2][0] == '"') {
304
        $match[2] = substr($match[2], 1, -1);
305
        $phrase = TRUE;
306
      }
307
      $words = trim($match[2], ',?!();:-');
308
      $words = $phrase ? array($words) : preg_split('/ /', $words, -1, PREG_SPLIT_NO_EMPTY);
309
      foreach ($words as $word) {
310
        $placeholder = $this->placeholder();
311
        $where->condition($field, '%' . db_like(trim($word, " ,!?")) . '%', 'LIKE');
312
      }
313
    }
314

    
315
    if (!$where) {
316
      return;
317
    }
318

    
319
    // Previously this was a call_user_func_array but that's unnecessary as
320
    // Views will unpack an array that is a single arg.
321
    $this->query->add_where($this->options['group'], $where);
322
  }
323

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

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

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

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

    
352
  /**
353
   * {@inheritdoc}
354
   */
355
  public function op_not($field) {
356
    $this->query->add_where($this->options['group'], $field, '%' . db_like($this->value) . '%', 'NOT LIKE');
357
  }
358

    
359
  /**
360
   * {@inheritdoc}
361
   */
362
  public function op_shorter($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_longer($field) {
371
    $placeholder = $this->placeholder();
372
    $this->query->add_where_expression($this->options['group'], "LENGTH($field) > $placeholder", array($placeholder => $this->value));
373
  }
374

    
375
  /**
376
   * {@inheritdoc}
377
   */
378
  public function op_regex($field) {
379
    $this->query->add_where($this->options['group'], $field, $this->value, 'RLIKE');
380
  }
381

    
382
  /**
383
   * {@inheritdoc}
384
   */
385
  public function op_not_regex($field) {
386
    $this->query->add_where($this->options['group'], $field, $this->value, 'NOT RLIKE');
387
  }
388

    
389
  /**
390
   * {@inheritdoc}
391
   */
392
  public function op_empty($field) {
393
    if ($this->operator == 'empty') {
394
      $operator = "IS NULL";
395
    }
396
    else {
397
      $operator = "IS NOT NULL";
398
    }
399

    
400
    $this->query->add_where($this->options['group'], $field, NULL, $operator);
401
  }
402

    
403
}