[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/views/plugins/ -> views_plugin_style.inc (source)

   1  <?php
   2  // $Id: views_plugin_style.inc,v 1.8.2.8 2010/04/29 18:21:52 merlinofchaos Exp $
   3  
   4  /**
   5   * @defgroup views_style_plugins Views' style plugins
   6   * @{
   7   * Style plugins control how a view is rendered. For example, they
   8   * can choose to display a collection of fields, node_view() output,
   9   * table output, or any kind of crazy output they want.
  10   *
  11   * Many style plugins can have an optional 'row' plugin, that displays
  12   * a single record. Not all style plugins can utilize this, so it is
  13   * up to the plugin to set this up and call through to the row plugin.
  14   *
  15   * @see hook_views_plugins
  16   */
  17  
  18  /**
  19   * Base class to define a style plugin handler.
  20   */
  21  class views_plugin_style extends views_plugin {
  22    /**
  23     * Initialize a style plugin.
  24     *
  25     * @param $view
  26     * @param $display
  27     * @param $options
  28     *   The style options might come externally as the style can be sourced
  29     *   from at least two locations. If it's not included, look on the display.
  30     */
  31    function init(&$view, &$display, $options = NULL) {
  32      $this->view = &$view;
  33      $this->display = &$display;
  34  
  35      // Overlay incoming options on top of defaults
  36      $this->unpack_options($this->options, isset($options) ? $options : $display->handler->get_option('style_options'));
  37  
  38      if ($this->uses_row_plugin() && $display->handler->get_option('row_plugin')) {
  39        $this->row_plugin = $display->handler->get_plugin('row');
  40      }
  41  
  42      $this->options += array(
  43        'grouping' => '',
  44      );
  45  
  46      $this->definition += array(
  47        'uses grouping' => TRUE,
  48      );
  49    }
  50  
  51    function destroy() {
  52      parent::destroy();
  53  
  54      if (isset($this->row_plugin)) {
  55        $this->row_plugin->destroy();
  56      }
  57    }
  58  
  59    /**
  60     * Return TRUE if this style also uses a row plugin.
  61     */
  62    function uses_row_plugin() {
  63      return !empty($this->definition['uses row plugin']);
  64    }
  65  
  66    /**
  67     * Return TRUE if this style also uses fields.
  68     */
  69    function uses_fields() {
  70      // If we use a row plugin, ask the row plugin. Chances are, we don't
  71      // care, it does.
  72      if ($this->uses_row_plugin() && !empty($this->row_plugin)) {
  73        return $this->row_plugin->uses_fields();
  74      }
  75      // Otherwise, maybe we do.
  76      return !empty($this->definition['uses fields']);
  77    }
  78  
  79    function option_definition() {
  80      $options = parent::option_definition();
  81      $options['grouping'] = array('default' => '');
  82      return $options;
  83    }
  84  
  85    function options_form(&$form, &$form_state) {
  86      // Only fields-based views can handle grouping.  Style plugins can also exclude
  87      // themselves from being groupable by setting their "use grouping" definiton
  88      // key to FALSE.
  89      // @TODO: Document "uses grouping" in docs.php when docs.php is written.
  90      if ($this->uses_fields() && $this->definition['uses grouping']) {
  91        $options = array('' => t('<None>'));
  92        $options += $this->display->handler->get_field_labels();
  93  
  94        // If there are no fields, we can't group on them.
  95        if (count($options) > 1) {
  96          $form['grouping'] = array(
  97            '#type' => 'select',
  98            '#title' => t('Grouping field'),
  99            '#options' => $options,
 100            '#default_value' => $this->options['grouping'],
 101            '#description' => t('You may optionally specify a field by which to group the records. Leave blank to not group.'),
 102          );
 103        }
 104      }
 105    }
 106  
 107    /**
 108     * Called by the view builder to see if this style handler wants to
 109     * interfere with the sorts. If so it should build; if it returns
 110     * any non-TRUE value, normal sorting will NOT be added to the query.
 111     */
 112    function build_sort() { return TRUE; }
 113  
 114    /**
 115     * Called by the view builder to let the style build a second set of
 116     * sorts that will come after any other sorts in the view.
 117     */
 118    function build_sort_post() { }
 119  
 120    /**
 121     * Allow the style to do stuff before each row is rendered.
 122     *
 123     * @param $result
 124     *   The full array of results from the query.
 125     */
 126    function pre_render($result) {
 127      if (!empty($this->row_plugin)) {
 128        $this->row_plugin->pre_render($result);
 129      }
 130    }
 131  
 132    /**
 133     * Render the display in this style.
 134     */
 135    function render() {
 136      if ($this->uses_row_plugin() && empty($this->row_plugin)) {
 137        vpr('views_plugin_style_default: Missing row plugin');
 138        return;
 139      }
 140  
 141      // Group the rows according to the grouping field, if specified.
 142      $sets = $this->render_grouping($this->view->result, $this->options['grouping']);
 143  
 144      // Render each group separately and concatenate.  Plugins may override this
 145      // method if they wish some other way of handling grouping.
 146      $output = '';
 147      foreach ($sets as $title => $records) {
 148        if ($this->uses_row_plugin()) {
 149          $rows = array();
 150          foreach ($records as $row_index => $row) {
 151            $this->view->row_index = $row_index;
 152            $rows[] = $this->row_plugin->render($row);
 153          }
 154        }
 155        else {
 156          $rows = $records;
 157        }
 158  
 159        $output .= theme($this->theme_functions(), $this->view, $this->options, $rows, $title);
 160      }
 161      unset($this->view->row_index);
 162      return $output;
 163    }
 164  
 165    /**
 166     * Group records as needed for rendering.
 167     *
 168     * @param $records
 169     *   An array of records from the view to group.
 170     * @param $grouping_field
 171     *   The field id on which to group.  If empty, the result set will be given
 172     *   a single group with an empty string as a label.
 173     * @return
 174     *   The grouped record set.
 175     */
 176    function render_grouping($records, $grouping_field = '') {
 177      // Make sure fields are rendered
 178      $this->render_fields($this->view->result);
 179      $sets = array();
 180      if ($grouping_field) {
 181        foreach ($records as $index => $row) {
 182          $grouping = '';
 183          // Group on the rendered version of the field, not the raw.  That way,
 184          // we can control any special formatting of the grouping field through
 185          // the admin or theme layer or anywhere else we'd like.
 186          if (isset($this->view->field[$grouping_field])) {
 187            $grouping = $this->get_field($index, $grouping_field);
 188            if ($this->view->field[$grouping_field]->options['label']) {
 189              $grouping = $this->view->field[$grouping_field]->options['label'] . ': ' . $grouping;
 190            }
 191          }
 192          $sets[$grouping][$index] = $row;
 193        }
 194      }
 195      else {
 196        // Create a single group with an empty grouping field.
 197        $sets[''] = $records;
 198      }
 199      return $sets;
 200    }
 201  
 202    /**
 203     * Render all of the fields for a given style and store them on the object.
 204     *
 205     * @param $result
 206     *   The result array from $view->result
 207     */
 208    function render_fields($result) {
 209      if (!$this->uses_fields()) {
 210        return;
 211      }
 212  
 213      $start = views_microtime();
 214      if (isset($this->rendered_fields)) {
 215        return $this->rendered_fields;
 216      }
 217  
 218      $this->view->row_index = 0;
 219      $keys = array_keys($this->view->field);
 220      foreach ($result as $count => $row) {
 221        $this->view->row_index = $count;
 222        foreach ($keys as $id) {
 223          $this->rendered_fields[$count][$id] = $this->view->field[$id]->theme($row);
 224        }
 225      }
 226      unset($this->view->row_index);
 227    }
 228  
 229    /**
 230     * Get a rendered field.
 231     *
 232     * @param $index
 233     *   The index count of the row.
 234     * @param $field
 235     *    The id of the field.
 236     */
 237    function get_field($index, $field) {
 238      if (!isset($this->rendered_fields)) {
 239        $this->render_fields($this->view->result);
 240      }
 241  
 242      if (isset($this->rendered_fields[$index][$field])) {
 243        return $this->rendered_fields[$index][$field];
 244      }
 245    }
 246  
 247    function validate() {
 248      $errors = parent::validate();
 249  
 250      if ($this->uses_row_plugin()) {
 251        $plugin = $this->display->handler->get_plugin('row');
 252        if (empty($plugin)) {
 253          $errors[] = t('Style @style requires a row style but the row plugin is invalid.', array('@style' => $this->definition['title']));
 254        }
 255        else {
 256          $result = $plugin->validate();
 257          if (!empty($result) && is_array($result)) {
 258            $errors = array_merge($errors, $result);
 259          }
 260        }
 261      }
 262      return $errors;
 263    }
 264  
 265    function query() {
 266      parent::query();
 267      if (isset($this->row_plugin)) {
 268        $this->row_plugin->query();
 269      }
 270    }
 271  }
 272  
 273  /**
 274   * @}
 275   */
 276  


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7