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 } |
