source: sipes/modules_contrib/views_or/views_or_handler_filter.inc @ c43ea01

stableversion-3.0
Last change on this file since c43ea01 was 177a560, checked in by José Gregorio Puentes <jpuentes@…>, 8 años ago

se agrego el directorio de modulos contribuidos de drupal

  • Propiedad mode establecida a 100644
File size: 6.6 KB
Línea 
1<?php
2
3/**
4 * @file
5 * Filter classes.
6 *
7 * These classes are always used together, so we keep them in the same file.
8 */
9
10/**
11 * Generic views handler filter to add code to manipulate the query object.
12 */
13class views_or_handler_filter extends views_handler_filter {
14  // Don't display empty space where the operator would be.
15  var $no_operator = TRUE;
16
17  function options_form(&$form, &$form_state) {
18    $form['relationship']['#access'] = FALSE;
19  }
20
21  /**
22   * Create a new array on the object to store data, and return a referrence to
23   * it.
24   */
25  function &query_new_alternative() {
26    if (empty($this->query->views_or)) {
27      $this->query->views_or = array();
28      $id = 0;
29    }
30    else {
31      $id = max(array_keys($this->query->views_or)) + 1;
32    }
33    $this->query->views_or[$id] = array();
34    return $this->query->views_or[$id];
35  }
36
37  /**
38   * Return the current alternative block.
39   */
40  function &query_current_alternative() {
41    if (empty($this->query->views_or)) {
42      return $this->query_new_alternative();
43    }
44    return $this->query->views_or[max(array_keys($this->query->views_or))];
45  }
46
47  /**
48   * Pop the current alternative block.
49   */
50  function query_pop_alternative() {
51    unset($this->query->views_or[max(array_keys($this->query->views_or))]);
52  }
53
54  /**
55   * Return the data structure from a given group.
56   */
57  function query_get_where_group($group) {
58    if (isset($this->query->where[$group])) {
59      return $this->query->where[$group];
60    }
61  }
62
63  /**
64   * Add a new group, with the given data structure, and return the id of the
65   * group. If $as_default is true, this group becomes the default group and the
66   * id returned is that of the old default group.
67   */
68  function query_add_where_group($group, $as_default = FALSE) {
69    $new_group = $this->query->set_where_group('AND');
70    if ($as_default) {
71      $this->query->where[$new_group] = $this->query->where[0];
72      $this->query->where[0] = $group;
73    }
74    else {
75      $this->query->where[$new_group] = $group;
76    }
77    return $new_group;
78  }
79
80  /**
81   * Removes a given group. If this is the default group, replace it with a new
82   * empty group.
83   */
84  function query_remove_where_group($group) {
85    if (isset($this->query->where[$group])) {
86      if ($group == 0) {
87        $group = $this->query->set_where_group('AND');
88        $this->query->where[0] = $this->query->where[$group];
89      }
90      unset($this->query->where[$group]);
91    }
92  }
93
94  /**
95   * Compact the query such that there is only one where group. If $full is
96   * TRUE, compacts such that there is only one clause in the group.
97   */
98  function query_compact($full = FALSE) {
99    if (!empty($this->query->where)) {
100      $new_group = array(
101        'clauses' => array(),
102        'args'    => array(),
103        'type'    => $this->query->group_operator,
104      );
105      foreach ($this->query->where as $id => $content) {
106        if (count($content['clauses'])) {
107          if (count($content['clauses']) == 1) {
108            $new_group['clauses'] = array_merge($new_group['clauses'], $content['clauses']);
109          }
110          else {
111            $new_group['clauses'][] = '('. implode(') '. $content['type'] .' (', $content['clauses']) .')';
112          }
113          $new_group['args'] = array_merge($new_group['args'], $content['args']);
114        }
115      }
116      if ($full && count($new_group['clauses']) > 1) {
117        $new_clause = '('. implode(') '. $new_group['type'] .' (', $new_group['clauses']) .')';
118        $new_group['clauses'] = array($new_clause);
119      }
120      $this->query->where = array(0 => $new_group);
121    }
122  }
123
124  /* Finish an alternative. This is called to process the data whenever an
125   * alternative statement finishes (ie. either from the "next alternative" or
126   * "end alternatives" filters).
127   */
128  function finish_alternative() {
129    $alt = &$this->query_current_alternative();
130    // Compact the query
131    $this->query_compact(TRUE);
132    // Look for INNER joins in the new tables, and make them LEFT joins + where condition instead
133    $clauses = array();
134    foreach (array_diff(array_keys($this->query->table_queue), $alt['tables']) as $table) {
135      $alt['tables'][] = $table;
136      $def = $this->query->table_queue[$table];
137      if (!empty($def['join']) && $def['join']->type == 'INNER') {
138        $this->query->table_queue[$table]['join']->type = 'LEFT';
139        $field = $def['alias'] .'.'. $def['join']->field;
140        $clauses[] = $field .' IS NOT NULL';
141      }
142    }
143    if (count($clauses)) {
144      // Add a new group with our clauses
145      $grp = $this->query->set_where_group('AND');
146      foreach ($clauses as $c) {
147        $this->query->add_where($grp, $c);
148      }
149      // Make sure this will be ANDed, and compact again. The query
150      // has already been compacted, so we know this will work.
151      $old_group_operator = $this->query->group_operator;
152      $this->query->group_operator = 'AND';
153      $this->query_compact(TRUE);
154      $this->query->group_operator = $old_group_operator;
155    }
156    // Now store it for later
157    $alt['alternatives'][] = $this->query_get_where_group(0);
158    $this->query_remove_where_group(0);
159  }
160}
161
162/**
163 * Filter handler to start a block of alternatives.
164 */
165class views_or_handler_filter_begin_alternatives extends views_or_handler_filter {
166  function query() {
167    $this->query_compact();
168    $alt = &$this->query_new_alternative();
169    $alt['tables'] = array_keys($this->query->table_queue);
170    $alt['pre'] = $this->query_get_where_group(0);
171    $alt['alternatives'] = array();
172    $this->query_remove_where_group(0);
173  }
174}
175
176/**
177 * Filter handler to indicate the next block of alternatives
178 */
179class views_or_handler_filter_next_alternative extends views_or_handler_filter {
180  function query() {
181    $this->finish_alternative();
182  }
183}
184
185/**
186 * Filter handler to indicate the end of a block of alternatives.
187 */
188class views_or_handler_filter_end_alternatives extends views_or_handler_filter {
189  function query() {
190    $this->finish_alternative();
191    $alt = &$this->query_current_alternative();
192    $new_group = array(
193      'clauses' => array(),
194      'args'    => array(),
195      'type'    => 'OR',
196    );
197    foreach ($alt['alternatives'] as $alternative) {
198      if (empty($alternative['clauses'])) continue;
199      $new_group['clauses'][] = $alternative['clauses'][0];
200      $new_group['args'] = array_merge($new_group['args'], $alternative['args']);
201    }
202    $old = $this->query_add_where_group($alt['pre'], TRUE);
203    $this->query_remove_where_group($old);
204    if (count($new_group['clauses'])) {
205      $this->query_add_where_group($new_group);
206    }
207    if (!isset($alt['pre'])) {
208      unset($this->query->where[0]);
209    }
210    $this->query_pop_alternative();
211  }
212}
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.