2 // $Id: views_plugin_style.inc,v 1.5 2009/03/24 22:22:11 merlinofchaos Exp $
4 * Base class to define a style plugin handler.
6 class views_plugin_style extends views_plugin {
8 * Initialize a style plugin.
13 * The style options might come externally as the style can be sourced
14 * from at least two locations. If it's not included, look on the display.
16 function init(&$view, &$display, $options = NULL) {
18 $this->display = &$display;
20 // Overlay incoming options on top of defaults
21 $this->unpack_options($this->options, isset($options) ? $options : $display->handler->get_option('style_options'));
23 if ($this->uses_row_plugin() && $display->handler->get_option('row_plugin')) {
24 $this->row_plugin = $display->handler->get_plugin('row');
27 $this->options += array(
31 $this->definition += array(
32 'uses grouping' => TRUE,
39 if (isset($this->row_plugin)) {
40 $this->row_plugin->destroy();
45 * Return TRUE if this style also uses a row plugin.
47 function uses_row_plugin() {
48 return !empty($this->definition['uses row plugin']);
52 * Return TRUE if this style also uses fields.
54 function uses_fields() {
55 // If we use a row plugin, ask the row plugin. Chances are, we don't
57 if ($this->uses_row_plugin() && !empty($this->row_plugin)) {
58 return $this->row_plugin->uses_fields();
60 // Otherwise, maybe we do.
61 return !empty($this->definition['uses fields']);
64 function option_definition() {
65 $options = parent::option_definition();
66 $options['grouping'] = array('default' => '');
70 function options_form(&$form, &$form_state) {
71 // Only fields-based views can handle grouping. Style plugins can also exclude
72 // themselves from being groupable by setting their "use grouping" definiton
74 // @TODO: Document "uses grouping" in docs.php when docs.php is written.
75 if ($this->uses_fields() && $this->definition['uses grouping']) {
76 $options = array('' => t('<None>'));
77 foreach ($this->display->handler->get_handlers('field') as $field => $handler) {
79 if ($label = $handler->label()) {
80 $options[$field] = $label;
83 $options[$field] = $handler->ui_name();
87 // If there are no fields, we can't group on them.
88 if (count($options) > 1) {
89 $form['grouping'] = array(
91 '#title' => t('Grouping field'),
92 '#options' => $options,
93 '#default_value' => $this->options['grouping'],
94 '#description' => t('You may optionally specify a field by which to group the records. Leave blank to not group.'),
101 * Called by the view builder to see if this style handler wants to
102 * interfere with the sorts. If so it should build; if it returns
103 * any non-TRUE value, normal sorting will NOT be added to the query.
105 function build_sort() { return TRUE; }
108 * Allow the style to do stuff before each row is rendered.
111 * The full array of results from the query.
113 function pre_render($result) {
114 if (!empty($this->row_plugin)) {
115 $this->row_plugin->pre_render($result);
120 * Render the display in this style.
123 if ($this->uses_row_plugin() && empty($this->row_plugin)) {
124 vpr('views_plugin_style_default: Missing row plugin');
128 // Group the rows according to the grouping field, if specified.
129 $sets = $this->render_grouping($this->view->result, $this->options['grouping']);
131 // Render each group separately and concatenate. Plugins may override this
132 // method if they wish some other way of handling grouping.
134 foreach ($sets as $title => $records) {
135 if ($this->uses_row_plugin()) {
137 foreach ($records as $label => $row) {
138 $rows[] = $this->row_plugin->render($row);
145 $output .= theme($this->theme_functions(), $this->view, $this->options, $rows, $title);
151 * Group records as needed for rendering.
154 * An array of records from the view to group.
155 * @param $grouping_field
156 * The field id on which to group. If empty, the result set will be given
157 * a single group with an empty string as a label.
159 * The grouped record set.
161 function render_grouping($records, $grouping_field = '') {
163 if ($grouping_field) {
164 foreach ($records as $row) {
166 // Group on the rendered version of the field, not the raw. That way,
167 // we can control any special formatting of the grouping field through
168 // the admin or theme layer or anywhere else we'd like.
169 if (isset($this->view->field[$grouping_field])) {
170 $grouping = $this->view->field[$grouping_field]->theme($row);
171 if ($this->view->field[$grouping_field]->options['label']) {
172 $grouping = $this->view->field[$grouping_field]->options['label'] . ': ' . $grouping;
175 $sets[$grouping][] = $row;
179 // Create a single group with an empty grouping field.
180 $sets[''] = $records;
185 function validate() {
186 $errors = parent::validate();
188 if ($this->uses_row_plugin()) {
189 $plugin = $this->display->handler->get_plugin('row');
190 if (empty($plugin)) {
191 $errors[] = t('Style @style requires a row style but the row plugin is invalid.', array('@style' => $this->definition['title']));
199 if (isset($this->row_plugin)) {
200 $this->row_plugin->query();