? views_calc.patch Index: views_customfield.views.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views_customfield/Attic/views_customfield.views.inc,v retrieving revision 1.1.2.6 diff -u -p -r1.1.2.6 views_customfield.views.inc --- views_customfield.views.inc 15 Jun 2009 06:16:25 -0000 1.1.2.6 +++ views_customfield.views.inc 13 Sep 2009 19:24:25 -0000 @@ -68,3 +68,39 @@ function views_customfield_views_data() return $data; } + +/** + * Implementation of hook_views_plugins(). + */ +function views_customfield_views_plugins() { + if (!module_exists('views_calc')) return array(); + + return array( + 'style' => array( + 'views_customfield_calc_parent' => array( + // this isn't really a display but is necessary so the file can + // be included. + 'no ui' => TRUE, + 'handler' => 'views_calc_table', + 'path' => drupal_get_path('module', 'views_calc'), + 'parent' => '', + ), + 'views_customfield_calc' => array( + 'title' => t('Views Custom Field Calc Table'), + 'help' => t('Creates a table with column calculations (including custom fields).'), + 'handler' => 'views_customfield_calc_table', + 'path' => drupal_get_path('module', 'views_customfield') .'/includes', + 'parent' => 'views_calc', + 'theme' => 'views_calc_table', + 'theme file' => 'theme.inc', + 'theme path' => drupal_get_path('module', 'views_calc'), + 'uses row plugin' => FALSE, + 'uses fields' => TRUE, + 'uses options' => TRUE, + 'type' => 'normal', + 'even empty' => FALSE, + ), + ), + ); +} + Index: includes/views_customfield_calc_table.inc =================================================================== RCS file: includes/views_customfield_calc_table.inc diff -N includes/views_customfield_calc_table.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ includes/views_customfield_calc_table.inc 13 Sep 2009 19:24:25 -0000 @@ -0,0 +1,114 @@ +view->totals)) { + $totals =& $this->view->totals; + $i = 0; + foreach ($this->get_calc_fields() as $calc => $fields) { + foreach ($fields as $field) { + $view_field = $this->view->field[$field]; + if ($view_field->table == 'customfield') { + $total = $this->customfield_totals($view_field, $calc); + $totals[$i]->{$view_field->field_alias} = $total; + } + } + $i++; + } + } + return parent::render(); + } + + function customfield_totals($field, $calc) { + static $totals = array(); + if (!isset($totals[$field->field_alias])) { + $totals[$field->field_alias] = array( + 'SUM' => 0.0, + 'COUNT' => count($this->view->result), + 'MIN' => $this->view->result[0]->{$field->field_alias}, + 'MAX' => $this->view->result[0]->{$field->field_alias}, + 'AVG' => 0.0, + ); + if (!empty($this->view->result)) { + foreach ($this->view->result as $row) { + if (!isset($row->{$field->field_alias})) { + $totals[$field->field_alias]['COUNT']--; + } + else { + $value = $row->{$field->field_alias}; + $totals[$field->field_alias]['SUM'] += $value; + if ($totals[$field->field_alias]['MAX'] < $value) $totals[$field->field_alias]['MAX'] = $value; + if ($totals[$field->field_alias]['MIN'] > $value) $totals[$field->field_alias]['MIN'] = $value; + } + } + $totals[$field->field_alias]['AVG'] = $totals[$field->field_alias]['SUM'] / $totals[$field->field_alias]['COUNT']; + } + } + return $totals[$field->field_alias][$calc]; + } + + function query_sub_total() { + // Create summary rows. + $calc_fields = $this->get_calc_fields(); + $calc = $this->view->views_calc_calculation; + $fields = $calc_fields[$calc]; + + // Empty out any fields that have been added to the query, + // we don't need them for the summary totals. + $this->view->query->fields = array(); + foreach ($this->view->field as $field) { + if ($field->table == 'customfield') continue; + + $query_field = substr($field->field, 0, 3) == 'cid' ? $field->definition['calc'] : $field->table .'.'. $field->field; + $query_alias = $field->field_alias; + if (in_array($field->field, $fields)) { + // Calculated fields. + $this->view->query->add_field(NULL, "$calc($query_field)", $query_alias); + } + else { + // Empty fields that have no calculations. + $this->view->query->add_field(NULL, "MAX('')", $query_alias); + } + // Add a dummy field for the groupby. + $this->view->query->add_field(NULL, "MAX('". $calc ."')", "TOTAL_". $calc); + } + // TODO This won't work right with relationships, need a fix here. + if (!empty($this->view->views_calc_nids)) { + $this->view->query->add_where(NULL, "node.nid IN (%s)", implode(',', $this->view->views_calc_nids)); + } + } + + function query_total() { + // Create summary rows. + $calc_fields = $this->get_calc_fields(); + $calc = $this->view->views_calc_calculation; + $fields = $calc_fields[$calc]; + + // Empty out any fields that have been added to the query, + // we don't need them for the summary totals. + $this->view->query->fields = array(); + // Clear out any sorting and grouping, it can create unexpected results + // when Views adds aggregation values for the sorts. + $this->view->query->orderby = array(); + $this->view->query->groupby = array(); + + foreach ($this->view->field as $field) { + if ($field->table == 'customfield') continue; + + $query_field = substr($field->field, 0, 3) == 'cid' ? $field->definition['calc'] : $field->table .'.'. $field->field; + $query_alias = $field->field_alias; + if (!empty($fields) && in_array($field->field, $fields)) { + // Calculated fields. + $this->view->query->add_field(NULL, "$calc($query_field)", $query_alias); + } + else { + // Empty fields that have no calculations. + $this->view->query->add_field(NULL, "MAX('')", $query_alias); + } + // Add a dummy field for the groupby. + $this->view->query->add_field(NULL, "MAX('". $calc ."')", "TOTAL_". $calc); + } + } +} + Index: includes/views_customfield_handler_field_phpcode.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views_customfield/includes/Attic/views_customfield_handler_field_phpcode.inc,v retrieving revision 1.1.2.7 diff -u -p -r1.1.2.7 views_customfield_handler_field_phpcode.inc --- includes/views_customfield_handler_field_phpcode.inc 16 Jul 2009 16:22:21 -0000 1.1.2.7 +++ includes/views_customfield_handler_field_phpcode.inc 13 Sep 2009 19:24:25 -0000 @@ -26,6 +26,7 @@ class views_customfield_handler_field_ph function option_definition() { $options = parent::option_definition(); $options['value'] = array('default' => ''); + $options['format'] = array('default' => ''); $options['sortable'] = array('default' => VIEWS_CUSTOMFIELD_SORTABLE_NO); return $options; } @@ -40,13 +41,23 @@ class views_customfield_handler_field_ph '#title' => t('Value'), '#default_value' => $this->options['value'], '#rows' => 5, - '#description' => - t('The text that should be displayed.') - .' '.t('Include <?php ?> delimiters when using PHP code.') - .' '.t('Available variables:').'
' - .t('$data: contains the retrieved record from the database (e.g. $data->nid).').'
' - .t('$static: can be used to store reusable data per row.') - , + '#description' => t('The code used to compute the value of this field, enclosed within <?php ?> delimiters. '. + 'Available variables:' + ), + ); + $form['format'] = array( + '#type' => 'textarea', + '#title' => t('Format'), + '#default_value' => $this->options['format'], + '#rows' => 5, + '#description' => t('The code used to format the value computed above. Available variables:' + ), ); $form['sortable'] = array( '#type' => 'radios', @@ -130,7 +141,8 @@ class views_customfield_handler_field_ph } function render($values) { - return $values->{$this->field_alias}; + $value = $values->{$this->field_alias}; + return empty($this->options['format']) ? $value : $this->render_phpcode($this->options['format'], array('static' => &$this->static, 'value' => $value)); } /** @@ -159,7 +171,7 @@ class views_customfield_handler_field_ph } } - return $this->render_phpcode($this->options['value'], $this->static, $values); + return $this->render_phpcode($this->options['value'], array('static' => &$this->static, 'data' => $values)); } /** @@ -172,7 +184,7 @@ class views_customfield_handler_field_ph * @param array $data * @return string */ - function render_phpcode($code, &$static, $data) { + function render_phpcode($code, $variables) { global $theme_path, $theme_info, $conf; // Store current theme path. @@ -188,27 +200,16 @@ class views_customfield_handler_field_ph $theme_path = dirname($theme_info->filename); } - $output = $this->eval_phpcode($code, $static, $data); + extract($variables, EXTR_REFS); + ob_start(); + print eval('?>'. $code); + $output = ob_get_clean(); // Recover original theme path. $theme_path = $old_theme_path; return $output; } - - /** - * Evaluate a string of PHP code. - * - * @param string $code - * @param mixed $static - * @param array $data - * @return string - */ - function eval_phpcode($code, &$static, $data) { - ob_start(); - print eval('?>'. $code); - return ob_get_clean(); - } } class views_customfield_sorter {