source: sipes/modules_contrib/views/plugins/views_plugin_style.inc @ a8b1f3f

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

se actualizo la version del modulo views

  • Propiedad mode establecida a 100644
File size: 10.7 KB
Línea 
1<?php
2
3/**
4 * @defgroup views_style_plugins Views' style plugins
5 * @{
6 * Style plugins control how a view is rendered. For example, they
7 * can choose to display a collection of fields, node_view() output,
8 * table output, or any kind of crazy output they want.
9 *
10 * Many style plugins can have an optional 'row' plugin, that displays
11 * a single record. Not all style plugins can utilize this, so it is
12 * up to the plugin to set this up and call through to the row plugin.
13 *
14 * @see hook_views_plugins
15 */
16
17/**
18 * Base class to define a style plugin handler.
19 */
20class views_plugin_style extends views_plugin {
21  /**
22   * Store all availible tokens row rows.
23   */
24  var $row_tokens = array();
25
26  /**
27   * Contains the row plugin, if it's initialized
28   * and the style itself supports it.
29   *
30   * @var views_plugin_row
31   */
32  var $row_plugin;
33
34  /**
35   * Initialize a style plugin.
36   *
37   * @param $view
38   * @param $display
39   * @param $options
40   *   The style options might come externally as the style can be sourced
41   *   from at least two locations. If it's not included, look on the display.
42   */
43  function init(&$view, &$display, $options = NULL) {
44    $this->view = &$view;
45    $this->display = &$display;
46
47    // Overlay incoming options on top of defaults
48    $this->unpack_options($this->options, isset($options) ? $options : $display->handler->get_option('style_options'));
49
50    if ($this->uses_row_plugin() && $display->handler->get_option('row_plugin')) {
51      $this->row_plugin = $display->handler->get_plugin('row');
52    }
53
54    $this->options += array(
55      'grouping' => '',
56    );
57
58    $this->definition += array(
59      'uses grouping' => TRUE,
60    );
61  }
62
63  function destroy() {
64    parent::destroy();
65
66    if (isset($this->row_plugin)) {
67      $this->row_plugin->destroy();
68    }
69  }
70
71  /**
72   * Return TRUE if this style also uses a row plugin.
73   */
74  function uses_row_plugin() {
75    return !empty($this->definition['uses row plugin']);
76  }
77
78  /**
79   * Return TRUE if this style also uses a row plugin.
80   */
81  function uses_row_class() {
82    return !empty($this->definition['uses row class']);
83  }
84
85  /**
86   * Return TRUE if this style also uses fields.
87   */
88  function uses_fields() {
89    // If we use a row plugin, ask the row plugin. Chances are, we don't
90    // care, it does.
91    if ($this->uses_row_plugin() && !empty($this->row_plugin)) {
92      return $this->row_plugin->uses_fields();
93    }
94    // Otherwise, maybe we do.
95    return !empty($this->definition['uses fields']);
96  }
97
98  /**
99   * Return TRUE if this style uses tokens.
100   *
101   * Used to ensure we don't fetch tokens when not needed for performance.
102   */
103  function uses_tokens() {
104    if ($this->uses_row_class()) {
105      $class = $this->options['row_class'];
106      if (strpos($class, '[') !== FALSE || strpos($class, '!') !== FALSE || strpos($class, '%') !== FALSE) {
107        return TRUE;
108      }
109    }
110  }
111
112  /**
113   * Return the token replaced row class for the specified row.
114   */
115  function get_row_class($row_index) {
116    if ($this->uses_row_class()) {
117      $class = $this->options['row_class'];
118      if ($this->uses_fields() && $this->view->field) {
119        $class = strip_tags($this->tokenize_value($class, $row_index));
120      }
121
122      return views_css_safe($class);
123    }
124  }
125
126  /**
127   * Take a value and apply token replacement logic to it.
128   */
129  function tokenize_value($value, $row_index) {
130    if (strpos($value, '[') !== FALSE || strpos($value, '!') !== FALSE || strpos($value, '%') !== FALSE) {
131      $fake_item = array(
132        'alter_text' => TRUE,
133        'text' => $value,
134      );
135
136      // Row tokens might be empty, for example for node row style.
137      $tokens = isset($this->row_tokens[$row_index]) ? $this->row_tokens[$row_index] : array();
138      if (!empty($this->view->build_info['substitutions'])) {
139        $tokens += $this->view->build_info['substitutions'];
140      }
141
142      if ($tokens) {
143        $value = strtr($value, $tokens);
144      }
145    }
146
147    return $value;
148  }
149
150  /**
151   * Should the output of the style plugin be rendered even if it's a empty view.
152   */
153  function even_empty() {
154    return !empty($this->definition['even empty']);
155  }
156
157  function option_definition() {
158    $options = parent::option_definition();
159    $options['grouping'] = array('default' => '');
160    if ($this->uses_row_class()) {
161      $options['row_class'] = array('default' => '');
162    }
163
164    return $options;
165  }
166
167  function options_form(&$form, &$form_state) {
168    // Only fields-based views can handle grouping.  Style plugins can also exclude
169    // themselves from being groupable by setting their "use grouping" definiton
170    // key to FALSE.
171    // @TODO: Document "uses grouping" in docs.php when docs.php is written.
172    if ($this->uses_fields() && $this->definition['uses grouping']) {
173      $options = array('' => t('- None -'));
174      $options += $this->display->handler->get_field_labels();
175
176      // If there are no fields, we can't group on them.
177      if (count($options) > 1) {
178        $form['grouping'] = array(
179          '#type' => 'select',
180          '#title' => t('Grouping field'),
181          '#options' => $options,
182          '#default_value' => $this->options['grouping'],
183          '#description' => t('You may optionally specify a field by which to group the records. Leave blank to not group.'),
184        );
185      }
186    }
187
188    if ($this->uses_row_class()) {
189      $form['row_class'] = array(
190        '#title' => t('Row class'),
191        '#description' => t('The class to provide on each row.'),
192        '#type' => 'textfield',
193        '#default_value' => $this->options['row_class'],
194      );
195
196      if ($this->uses_fields()) {
197        $form['row_class']['#description'] .= ' ' . t('You may use field tokens from as per the "Replacement patterns" used in "Rewrite the output of this field" for all fields.');
198      }
199    }
200  }
201
202  /**
203   * Called by the view builder to see if this style handler wants to
204   * interfere with the sorts. If so it should build; if it returns
205   * any non-TRUE value, normal sorting will NOT be added to the query.
206   */
207  function build_sort() { return TRUE; }
208
209  /**
210   * Called by the view builder to let the style build a second set of
211   * sorts that will come after any other sorts in the view.
212   */
213  function build_sort_post() { }
214
215  /**
216   * Allow the style to do stuff before each row is rendered.
217   *
218   * @param $result
219   *   The full array of results from the query.
220   */
221  function pre_render($result) {
222    if (!empty($this->row_plugin)) {
223      $this->row_plugin->pre_render($result);
224    }
225  }
226
227  /**
228   * Render the display in this style.
229   */
230  function render() {
231    if ($this->uses_row_plugin() && empty($this->row_plugin)) {
232      vpr('views_plugin_style_default: Missing row plugin');
233      return;
234    }
235
236    // Group the rows according to the grouping field, if specified.
237    $sets = $this->render_grouping($this->view->result, $this->options['grouping']);
238
239    // Render each group separately and concatenate.  Plugins may override this
240    // method if they wish some other way of handling grouping.
241    $output = '';
242    foreach ($sets as $title => $records) {
243      if ($this->uses_row_plugin()) {
244        $rows = array();
245        foreach ($records as $row_index => $row) {
246          $this->view->row_index = $row_index;
247          $rows[$row_index] = $this->row_plugin->render($row);
248        }
249      }
250      else {
251        $rows = $records;
252      }
253
254      $output .= theme($this->theme_functions(), $this->view, $this->options, $rows, $title);
255    }
256    unset($this->view->row_index);
257    return $output;
258  }
259
260  /**
261   * Group records as needed for rendering.
262   *
263   * @param $records
264   *   An array of records from the view to group.
265   * @param $grouping_field
266   *   The field id on which to group.  If empty, the result set will be given
267   *   a single group with an empty string as a label.
268   * @return
269   *   The grouped record set.
270   */
271  function render_grouping($records, $grouping_field = '') {
272    // Make sure fields are rendered
273    $this->render_fields($this->view->result);
274    $sets = array();
275    if ($grouping_field) {
276      foreach ($records as $index => $row) {
277        $grouping = '';
278        // Group on the rendered version of the field, not the raw.  That way,
279        // we can control any special formatting of the grouping field through
280        // the admin or theme layer or anywhere else we'd like.
281        if (isset($this->view->field[$grouping_field])) {
282          $grouping = $this->get_field($index, $grouping_field);
283          if ($this->view->field[$grouping_field]->options['label']) {
284            $grouping = $this->view->field[$grouping_field]->options['label'] . ': ' . $grouping;
285          }
286        }
287        $sets[$grouping][$index] = $row;
288      }
289    }
290    else {
291      // Create a single group with an empty grouping field.
292      $sets[''] = $records;
293    }
294    return $sets;
295  }
296
297  /**
298   * Render all of the fields for a given style and store them on the object.
299   *
300   * @param $result
301   *   The result array from $view->result
302   */
303  function render_fields($result) {
304    if (!$this->uses_fields()) {
305      return;
306    }
307
308    if (!isset($this->rendered_fields)) {
309      $this->rendered_fields = array();
310      $this->view->row_index = 0;
311      $keys = array_keys($this->view->field);
312
313      // If all fields have a field::access FALSE there might be no fields, so
314      // there is no reason to execute this code.
315      if (!empty($keys)) {
316        foreach ($result as $count => $row) {
317          $this->view->row_index = $count;
318          foreach ($keys as $id) {
319            $this->rendered_fields[$count][$id] = $this->view->field[$id]->theme($row);
320          }
321
322          $this->row_tokens[$count] = $this->view->field[$id]->get_render_tokens(array());
323        }
324      }
325      unset($this->view->row_index);
326    }
327
328    return $this->rendered_fields;
329  }
330
331  /**
332   * Get a rendered field.
333   *
334   * @param $index
335   *   The index count of the row.
336   * @param $field
337   *    The id of the field.
338   */
339  function get_field($index, $field) {
340    if (!isset($this->rendered_fields)) {
341      $this->render_fields($this->view->result);
342    }
343
344    if (isset($this->rendered_fields[$index][$field])) {
345      return $this->rendered_fields[$index][$field];
346    }
347  }
348
349  function validate() {
350    $errors = parent::validate();
351
352    if ($this->uses_row_plugin()) {
353      $plugin = $this->display->handler->get_plugin('row');
354      if (empty($plugin)) {
355        $errors[] = t('Style @style requires a row style but the row plugin is invalid.', array('@style' => $this->definition['title']));
356      }
357      else {
358        $result = $plugin->validate();
359        if (!empty($result) && is_array($result)) {
360          $errors = array_merge($errors, $result);
361        }
362      }
363    }
364    return $errors;
365  }
366
367  function query() {
368    parent::query();
369    if (isset($this->row_plugin)) {
370      $this->row_plugin->query();
371    }
372  }
373}
374
375/**
376 * @}
377 */
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.