comparison views_calc_table.inc @ 0:0651c02e6ed7

views_calc 1.3
author Franck Deroche <franck@defr.org>
date Wed, 05 Aug 2009 18:20:29 +0200
parents
children cedf71edacf5 b0a976e17cc7
comparison
equal deleted inserted replaced
-1:000000000000 0:0651c02e6ed7
1 <?php
2 // $Id: views_calc_table.inc,v 1.15 2009/04/22 02:21:41 karens Exp $
3 /**
4 * @file
5 * Copied from the table style plugin.
6 */
7
8 /**
9 * Style plugin to render each item as a row in a table.
10 *
11 * @ingroup views_style_plugins
12 */
13 class views_calc_table extends views_plugin_style_table {
14
15 function option_definition() {
16 $options = parent::option_definition();
17
18 $options['detailed_values'] = array('default' => 0);
19 return $options;
20 }
21
22 /**
23 * Render the given style.
24 */
25 function options_form(&$form, &$form_state) {
26 parent::options_form($form, $form_state);
27 $form['#theme'] = 'views_calc_ui_table';
28
29 $form['detailed_values'] = array(
30 '#title' => t('Show details'),
31 '#type' => 'select',
32 '#options' => array(0 => t('Yes'), 1 => t('No')),
33 '#default_value' => $this->options['detailed_values'],
34 '#description' => t("Select 'Yes' to show detailed values followed by column calculations, 'No' to surpress details and show only calculated column totals."),
35 );
36
37 $handlers = $this->display->handler->get_handlers('field');
38 $columns = $this->sanitize_columns($this->options['columns']);
39
40 foreach ($columns as $field => $column) {
41 $safe = str_replace(array('][', '_', ' '), '-', $field);
42 $id = 'edit-style-options-columns-' . $safe;
43 $form['info'][$field]['justification'] = array(
44 '#type' => 'select',
45 '#default_value' => isset($this->options['info'][$field]['justification']) ? $this->options['info'][$field]['justification'] : 'views_calc_justify_none',
46 '#options' => array(
47 'views_calc_justify_none' => t('None'),
48 'views_calc_justify_left' => t('Left'),
49 'views_calc_justify_right' => t('Right'),
50 'views_calc_justify_center' => t('Center'),
51 ),
52 '#process' => array('views_process_dependency'),
53 '#dependency' => array($id => array($field)),
54 );
55 $form['info'][$field]['has_calc'] = array(
56 '#type' => 'checkbox',
57 '#title' => t('Display calculation'),
58 '#default_value' => isset($this->options['info'][$field]['has_calc']) ? $this->options['info'][$field]['has_calc'] : 0,
59 '#process' => array('views_process_dependency'),
60 '#dependency' => array($id => array($field)),
61 );
62
63 $options = _views_calc_calc_options();
64 $form['info'][$field]['calc'] = array(
65 '#type' => 'select',
66 '#options' => $options,
67 '#default_value' => isset($this->options['info'][$field]['calc']) ? $this->options['info'][$field]['calc'] : array(),
68 '#process' => array('views_process_dependency'),
69 '#dependency' => array('edit-style-options-info-'. $safe .'-has-calc' => array(TRUE)),
70 '#multiple' => TRUE,
71 );
72 }
73 }
74
75 /**
76 * TODO
77 * figure out what changes are needed so Views field groups will work.
78 */
79 function pre_render($results) {
80 parent::pre_render($results);
81
82 // If there are no calc fields, do nothing.
83 if (!$calc_fields = $this->get_calc_fields()) {
84 return;
85 }
86 // If we're not getting a summary row, do nothing.
87 if (!empty($this->view->views_calc_calculation)) {
88 return;
89 }
90
91 $this->view->totals = array();
92 $this->view->sub_totals = array();
93
94 // Subtotals and pager totals require a list of the specific
95 // values to include.
96 $paged = FALSE;
97 if (!empty($this->view->pager)
98 && !empty($this->view->pager['use_pager'])
99 && !empty($this->view->pager['items_per_page'])) {
100 $nids = array();
101 foreach ($this->view->result as $delta => $value) {
102 $nids[] = $value->nid;
103 }
104 // Add sub_total rows to the results.
105 foreach ($calc_fields as $calc => $field) {
106 if ($summary_view = views_get_view($this->view->name)) {
107 $summary_view->set_display($this->view->current_display);
108 $summary_view->set_arguments($this->view->args);
109 $summary_view->views_calc_calculation = $calc;
110 $summary_view->views_calc_nids = $nids;
111 $summary_view->views_calc_sub_total = TRUE;
112 $summary_view->is_cacheable = FALSE;
113 $summary_view->execute();
114 $this->view->sub_totals[] = array_shift($summary_view->result);
115 }
116 }
117 }
118
119 // Add grand totals to the results.
120 foreach ($calc_fields as $calc => $field) {
121 if ($summary_view = views_get_view($this->view->name)) {
122 $summary_view->set_display($this->view->current_display);
123 $summary_view->set_arguments($this->view->args);
124 $summary_view->pager['items_per_page'] = 0;
125 $summary_view->views_calc_calculation = $calc;
126 $summary_view->views_calc_nids = array();
127 $summary_view->views_calc_sub_total = FALSE;
128 $summary_view->is_cacheable = FALSE;
129 $summary_view->execute();
130 $this->view->totals[] = array_shift($summary_view->result);
131 }
132 }
133 }
134
135 function query() {
136 parent::query();
137
138 // If we're not getting a summary row, do nothing.
139 if (empty($this->view->views_calc_calculation)) {
140 return;
141 }
142 // If there are no calc fields, do nothing.
143 if (!$calc_fields = $this->get_calc_fields()) {
144 return;
145 }
146
147 if (!empty($this->view->views_calc_sub_total)) {
148 $this->query_sub_total();
149 }
150 else {
151 $this->query_total();
152 }
153 }
154
155 /**
156 *
157 */
158 function query_sub_total() {
159 // Create summary rows.
160 $calc_fields = $this->get_calc_fields();
161 $calc = $this->view->views_calc_calculation;
162 $fields = $calc_fields[$calc];
163
164 // Empty out any fields that have been added to the query,
165 // we don't need them for the summary totals.
166 $this->view->query->fields = array();
167 foreach ($this->view->field as $field) {
168 $query_field = substr($field->field, 0, 3) == 'cid' ? $field->definition['calc'] : $field->table .'.'. $field->field;
169 $query_alias = $field->field_alias;
170 if (in_array($field->field, $fields)) {
171 // Calculated fields.
172 $this->view->query->add_field(NULL, "$calc($query_field)", $query_alias);
173 $this->view->query->add_table($field->table, NULL, NULL, $field->table);
174 }
175 else {
176 // Empty fields that have no calculations.
177 $this->view->query->add_field(NULL, "MAX('')", $query_alias);
178 }
179 // Add a dummy field for the groupby.
180 $this->view->query->add_field(NULL, "MAX('". $calc ."')", "TOTAL_". $calc);
181 }
182 // TODO This won't work right with relationships, need a fix here.
183 if (!empty($this->view->views_calc_nids)) {
184 $this->view->query->add_where(NULL, "node.nid IN (%s)", implode(',', $this->view->views_calc_nids));
185 }
186 }
187
188 /**
189 * The grand total can be computed using GROUPBY without regard
190 * to pager values.
191 */
192 function query_total() {
193 // Create summary rows.
194 $calc_fields = $this->get_calc_fields();
195 $calc = $this->view->views_calc_calculation;
196 $fields = $calc_fields[$calc];
197
198 // Empty out any fields that have been added to the query,
199 // we don't need them for the summary totals.
200 $this->view->query->fields = array();
201 // Clear out any sorting and grouping, it can create unexpected results
202 // when Views adds aggregation values for the sorts.
203 $this->view->query->orderby = array();
204 $this->view->query->groupby = array();
205
206 foreach ($this->view->field as $field) {
207 $query_field = substr($field->field, 0, 3) == 'cid' ? $field->definition['calc'] : $field->table .'.'. $field->field;
208 $query_alias = $field->field_alias;
209 $this->view->query->add_table($field->table, NULL, NULL, $field->table);
210 if (!empty($fields) && in_array($field->field, $fields)) {
211 // Calculated fields.
212 $this->view->query->add_field(NULL, "$calc($query_field)", $query_alias);
213 }
214 else {
215 // Empty fields that have no calculations.
216 $this->view->query->add_field(NULL, "MAX('')", $query_alias);
217 }
218 // Add a dummy field for the groupby.
219 $this->view->query->add_field(NULL, "MAX('". $calc ."')", "TOTAL_". $calc);
220 }
221 }
222
223 function get_calc_fields() {
224 $options = $this->view->style_plugin->options;
225 $handler = $this->view->style_plugin;
226 $fields = $this->view->field;
227 $columns = $handler->sanitize_columns($options['columns'], $fields);
228 $calcs = array_keys(_views_calc_calc_options());
229
230 $calc_fields = array();
231 foreach ($columns as $field => $column) {
232 if ($field == $column && empty($fields[$field]->options['exclude'])) {
233 if ($options['info'][$field]['has_calc']) {
234 foreach ($calcs as $calc) {
235 if (isset($this->options['info'][$field]['calc'][$calc])) {
236 $calc_fields[$calc][] = $field;
237 }
238 }
239 }
240 }
241 }
242 return $calc_fields;
243 }
244 }