Mercurial > defr > drupal > views_calc
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 } |