From d0b7155cfa63f98d3fcca2c1d569a8b94f53ed7a Mon Sep 17 00:00:00 2001 From: Henry Clayton Date: Sun, 16 Feb 2014 03:12:52 -0700 Subject: [PATCH] Issue #140665 by rhclayto: Added grouping. --- theme.inc | 18 ++++++++-- views-calc-table.tpl.php | 10 +++++ views_calc.css | 14 ++++++++ views_calc_table.inc | 84 ++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 109 insertions(+), 17 deletions(-) diff --git a/theme.inc b/theme.inc index 491d141..c5174bc 100644 --- a/theme.inc +++ b/theme.inc @@ -220,11 +220,15 @@ function template_preprocess_views_calc_table(&$vars) { // Add totals. $vars['totals'] = array(); $vars['sub_totals'] = array(); + $vars['group_totals'] = array(); + if (isset($view->group_total)) { + views_calc_table_total($vars, 'group_totals', $view->group_total); + } if ($view->query->pager->get_total_items() > $view->get_items_per_page() && isset($view->sub_totals)) { views_calc_table_total($vars, 'sub_totals', $view->sub_totals); } - if (isset($view->totals)) { + if (isset($view->totals) && $view->last_group) { views_calc_table_total($vars, 'totals', $view->totals); } @@ -336,10 +340,18 @@ function views_calc_table_total(&$vars, $key, $totals) { // when both are provided. if (empty($added_label[$calc])) { if ($key == 'sub_totals') { - $label = t("Page !Calculation", array("!Calculation" => $calc)); + $Total_and_Calc = "Page Total" . ' ' . $calc; + $label = t($Total_and_Calc, array("!Calculation" => $calc)); } else { - $label = t("Total !Calculation", array("!Calculation" => $calc)); + if ($view->group_total && $key != 'totals') { + $Total_and_Calc = "Subtotal" . ' ' . $calc; + $label = t($Total_and_Calc, array("!Calculation" => $calc)); + } + else { + $Total_and_Calc = "Total" . ' ' . $calc; + $label = t($Total_and_Calc, array("!Calculation" => $calc)); + } } $vars[$key][$calc][$column] = $label; $added_label[$calc] = TRUE; diff --git a/views-calc-table.tpl.php b/views-calc-table.tpl.php index 6d3618e..657e3f7 100644 --- a/views-calc-table.tpl.php +++ b/views-calc-table.tpl.php @@ -41,6 +41,16 @@ if (empty($rows) && empty($totals)) { + $row): ?> + + $content): ?> + + + + + + + $row): ?> $content): ?> diff --git a/views_calc.css b/views_calc.css index d272f75..50394da 100644 --- a/views_calc.css +++ b/views_calc.css @@ -11,6 +11,20 @@ td.view-footer-number { border-bottom:3px #000 double; border-top:1px #000 solid; } + +td.view-groupfooter, +td.view-groupfooter-number { + font-weight:normal; + background-color:#fff; + } + +td.view-groupfooter, +td.view-groupfooter-number { + border-bottom:1px #000 solid; + border-top:1px #000 solid; + margin-bottom: 10px; + } + td.view-subfooter, td.view-subfooter-number { font-weight:normal; diff --git a/views_calc_table.inc b/views_calc_table.inc index 7e17548..3c6c797 100644 --- a/views_calc_table.inc +++ b/views_calc_table.inc @@ -122,6 +122,7 @@ class views_calc_table extends views_plugin_style_table { $this->view->totals = array(); $this->view->sub_totals = array(); + $this->view->group_totals = array(); $this->view->views_calc_fields = $calc_fields; $this->view->views_calc_calculation = FALSE; @@ -143,13 +144,12 @@ class views_calc_table extends views_plugin_style_table { $this->execute_summary_view(); } - function execute_summary_view($ids = array()) { + function execute_summary_view($ids = array(), $is_group = FALSE) { // Clone view for local subquery. $summary_view = $this->view->clone_view(); $summary_view->set_display($this->view->current_display); // copy the query object by value not by reference! $summary_view->query = clone $this->view->query; - $summary_view->set_display($this->view->current_display); // Make sure the view is completely valid. $errors = $summary_view->validate(); @@ -192,7 +192,10 @@ class views_calc_table extends views_plugin_style_table { $summary_view->post_execute(); if (!empty($summary_view->result)) { - if ($is_subtotal) { + if ($is_group) { + $this->view->group_totals[] = array_shift($summary_view->result); + } + elseif ($is_subtotal) { $this->view->sub_totals = array_shift($summary_view->result); } else { @@ -215,9 +218,6 @@ class views_calc_table extends views_plugin_style_table { $view->query->orderby = array(); $view->query->groupby = array(); - // See if this view has any calculations. - $has_calcs = TRUE; - $calc_fields = $view->views_calc_fields; foreach ($calc_fields as $calc => $fields) { foreach ($view->field as $field) { @@ -244,7 +244,6 @@ class views_calc_table extends views_plugin_style_table { if (in_array($field->options['id'], $fields)) { // Calculated fields. $view->query->add_field(NULL, $calc . '(' . $query_field . ')', $ext_alias); - $has_calcs = TRUE; } } } @@ -254,13 +253,6 @@ class views_calc_table extends views_plugin_style_table { //$view->query->add_where(NULL, $view->base_table . "." . $view->base_field . " IN (%s)", implode(',', $view->views_calc_ids)); $view->query->add_where(NULL, $view->base_table . "." . $view->base_field, $view->views_calc_ids); } - - // TODO We may need to ask which field to group by. - // Some databases are going to complain if we don't have a groupby field with using aggregation. - if ($has_calcs) { - $this->view->query->add_groupby($this->view->base_table . '.' . $this->view->base_field); - } - } /** @@ -288,4 +280,68 @@ class views_calc_table extends views_plugin_style_table { } return $calc_fields; } + + /** + * Override of the default style render, to include group totals. + */ + function render() { + if ($this->uses_row_plugin() && empty($this->row_plugin)) { + vpr('views_plugin_style_default: Missing row plugin'); + return; + } + + // Group the rows according to the grouping field, if specified. + $sets = $this->render_grouping($this->view->result, $this->options['grouping']); + + if (count($sets) > 1 ) { + $this->calc_group_totals($sets); + } + + // Render each group separately and concatenate. + $output = ''; + $group_index = 0; + $last_group_index = count($sets) - 1; + foreach ($sets as $title => $records) { + if ($this->uses_row_plugin()) { + $rows = array(); + foreach ($records as $row_index => $row) { + $this->view->row_index = $row_index; + $rows[] = $this->row_plugin->render($row); + } + } + else { + $rows = $records; + } + + $group_total = NULL; + if (isset($this->view->group_totals[$group_index])) { + $group_total = $this->view->group_totals[$group_index]; + } + $this->view->group_total = $group_total; + $this->view->last_group = ($group_index >= $last_group_index); + + $output .= theme($this->theme_functions(), array('view'=>$this->view, 'options'=>$this->options, 'rows'=>$rows, 'title'=>$title)); + $group_index++; + } + unset($this->view->row_index); + return $output; + } + + /** + * Calculates group totals. + * + * Should only be called if $sets has at least two sets in it. + */ + function calc_group_totals($sets) { + $field = $this->view->base_field; + $this->view->group_totals = array(); + foreach ($sets as $set) { + $ids = array(); + foreach ($set as $value) { + $ids[] = $value->$field; + } + $this->execute_summary_view($ids, TRUE); + } + } + } -- 1.7.6