source: sipes/modules_contrib/views_or/views_or_handler_argument.inc @ 6e81fb4

stableversion-3.0
Last change on this file since 6e81fb4 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: 8.2 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 argument to add code to manipulate the query object.
12 */
13class views_or_handler_argument extends views_handler_argument {
14  // Don't display empty space where the operator would be.
15  var $no_operator = TRUE;
16
17  function option_definition() {
18    $options = parent::option_definition();
19    $options['default_argument_fixed'] = array('default' => '');
20    $options['default_action'] = array('default' => 'default');
21    return $options;
22  }
23
24  function options_form(&$form, &$form_state) {
25    $form['relationship']['#access'] = FALSE;
26  }
27
28  function validate_arg($arg) {
29    return TRUE;
30  }
31
32  /**
33   * Create a new array on the object to store data, and return a referrence to
34   * it.
35   */
36  function &query_new_alternative() {
37    if (empty($this->query->views_or)) {
38      $this->query->views_or = array();
39      $id = 0;
40    }
41    else {
42      $id = max(array_keys($this->query->views_or)) + 1;
43    }
44    $this->query->views_or[$id] = array();
45    return $this->query->views_or[$id];
46  }
47
48  /**
49   * Return the current alternative block.
50   */
51  function &query_current_alternative() {
52    if (empty($this->query->views_or)) {
53      return $this->query_new_alternative();
54    }
55    return $this->query->views_or[max(array_keys($this->query->views_or))];
56  }
57
58  /**
59   * Pop the current alternative block.
60   */
61  function query_pop_alternative() {
62    unset($this->query->views_or[max(array_keys($this->query->views_or))]);
63  }
64
65  /**
66   * Return the data structure from a given group.
67   */
68  function query_get_where_group($group) {
69    if (isset($this->query->where[$group])) {
70      return $this->query->where[$group];
71    }
72  }
73
74  /**
75   * Add a new group, with the given data structure, and return the id of the
76   * group. If $as_default is true, this group becomes the default group and the
77   * id returned is that of the old default group.
78   */
79  function query_add_where_group($group, $as_default = FALSE) {
80    $new_group = $this->query->set_where_group('AND');
81    if ($as_default) {
82      $this->query->where[$new_group] = $this->query->where[0];
83      $this->query->where[0] = $group;
84    }
85    else {
86      $this->query->where[$new_group] = $group;
87    }
88    return $new_group;
89  }
90
91  /**
92   * Removes a given group. If this is the default group, replace it with a new
93   * empty group.
94   */
95  function query_remove_where_group($group) {
96    if (isset($this->query->where[$group])) {
97      if ($group == 0) {
98        $group = $this->query->set_where_group('AND');
99        $this->query->where[0] = $this->query->where[$group];
100      }
101      unset($this->query->where[$group]);
102    }
103  }
104
105  /**
106   * Compact the query such that there is only one where group. If $full is
107   * TRUE, compacts such that there is only one clause in the group.
108   */
109  function query_compact($full = FALSE) {
110    if (!empty($this->query->where)) {
111      $new_group = array(
112        'clauses' => array(),
113        'args'    => array(),
114        'type'    => $this->query->group_operator,
115      );
116      foreach ($this->query->where as $id => $content) {
117        if (count($content['clauses'])) {
118          if (count($content['clauses']) == 1) {
119            $new_group['clauses'] = array_merge($new_group['clauses'], $content['clauses']);
120          }
121          else {
122            $new_group['clauses'][] = '('. implode(') '. $content['type'] .' (', $content['clauses']) .')';
123          }
124          $new_group['args'] = array_merge($new_group['args'], $content['args']);
125        }
126      }
127      if ($full && count($new_group['clauses']) > 1) {
128        $new_clause = '('. implode(') '. $new_group['type'] .' (', $new_group['clauses']) .')';
129        $new_group['clauses'] = array($new_clause);
130      }
131      $this->query->where = array(0 => $new_group);
132    }
133  }
134
135  /* Finish an alternative. This is called to process the data whenever an
136   * alternative statement finishes (ie. either from the "next alternative" or
137   * "end alternatives" arguments).
138   */
139  function finish_alternative() {
140    $alt = &$this->query_current_alternative();
141    // Compact the query
142    $this->query_compact(TRUE);
143    // Look for INNER joins in the new tables, and make them LEFT joins + where condition instead
144    $clauses = array();
145    foreach (array_diff(array_keys($this->query->table_queue), $alt['tables']) as $table) {
146      $alt['tables'][] = $table;
147      $def = $this->query->table_queue[$table];
148      if (!empty($def['join']) && $def['join']->type == 'INNER') {
149        $this->query->table_queue[$table]['join']->type = 'LEFT';
150        $field = $def['alias'] .'.'. $def['join']->field;
151        $clauses[] = $field .' IS NOT NULL';
152      }
153    }
154    if (count($clauses)) {
155      // Add a new group with our clauses
156      $grp = $this->query->set_where_group('AND');
157      foreach ($clauses as $c) {
158        $this->query->add_where($grp, $c);
159      }
160      // Make sure this will be ANDed, and compact again. The query
161      // has already been compacted, so we know this will work.
162      $old_group_operator = $this->query->group_operator;
163      $this->query->group_operator = 'AND';
164      $this->query_compact(TRUE);
165      $this->query->group_operator = $old_group_operator;
166    }
167    // Now store it for later
168    $alt['alternatives'][] = $this->query_get_where_group(0);
169    $this->query_remove_where_group(0);
170  }
171}
172
173/**
174 * Filter handler to start a block of alternatives.
175 */
176class views_or_handler_argument_begin_alternatives extends views_or_handler_argument {
177  function query() {
178    $this->query_compact();
179    $alt = &$this->query_new_alternative();
180    $alt['tables'] = array_keys($this->query->table_queue);
181    $alt['pre'] = $this->query_get_where_group(0);
182    $alt['alternatives'] = array();
183    $alt['position'] = $this->position;
184    $this->query_remove_where_group(0);
185    if ($this->view->args[$this->position] != '') {
186      array_splice($this->view->args, $this->position, 0, '');
187    }
188  }
189}
190
191/**
192 * Argument handler to indicate the next block of alternatives
193 */
194class views_or_handler_argument_next_alternative extends views_or_handler_argument {
195  function option_definition() {
196    $options = parent::option_definition();
197    $options['share_arguments'] = array('default' => TRUE);
198    return $options;
199  }
200
201  function options_form(&$form, &$form_state) {
202    parent::options_form($form, $form_state);
203    $form['share_arguments'] = array(
204      '#type' => 'checkbox',
205      '#title' => t('Share arguments'),
206      '#default_value' => $this->options['share_arguments'],
207      '#description' => t('Leave this checked to make this set of alternative arguments use the same arguments as the last set. This eliminates the need to repeat the same arguments in the URL for each set of alternatives.'),
208    );
209  }
210
211  function query() {
212    $this->finish_alternative();
213    $alt = &$this->query_current_alternative();
214    if ($this->view->args[$this->position] != '') {
215      if ($this->options['share_arguments']) {
216        array_splice($this->view->args, $this->position, 0, array_slice($this->view->args, $alt['position'], $this->position - $alt['position']));
217        $alt['position'] = $this->position;
218      }
219      else {
220        array_splice($this->view->args, $this->position, 0, '');
221      }
222    }
223  }
224}
225
226/**
227 * Argument handler to indicate the end of a block of alternatives.
228 */
229class views_or_handler_argument_end_alternatives extends views_or_handler_argument {
230  function query() {
231    $this->finish_alternative();
232    $alt = &$this->query_current_alternative();
233    $new_group = array(
234      'clauses' => array(),
235      'args'    => array(),
236      'type'    => 'OR',
237    );
238    foreach ($alt['alternatives'] as $alternative) {
239      if (empty($alternative['clauses'])) continue;
240      $new_group['clauses'][] = $alternative['clauses'][0];
241      $new_group['args'] = array_merge($new_group['args'], $alternative['args']);
242    }
243    $old = $this->query_add_where_group($alt['pre'], TRUE);
244    $this->query_remove_where_group($old);
245    if (count($new_group['clauses'])) {
246      $this->query_add_where_group($new_group);
247    }
248    if (!isset($alt['pre'])) {
249      unset($this->query->where[0]);
250    }
251    $this->query_pop_alternative();
252    if ($this->view->args[$this->position] != '') {
253      array_splice($this->view->args, $this->position, 0, '');
254    }
255  }
256}
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.