# HG changeset patch # User Franck Deroche # Date 1249651212 -7200 # Node ID 5635080385bd618ad306997fa3e7b4376f334f77 # Parent cedf71edacf52ad652b339bf4c5727ee621207bf# Parent b0a976e17cc738b6686bfba5ac7e828b3a617940 Merge patch with 1.x-dev diff -r cedf71edacf5 -r 5635080385bd CHANGELOG.txt --- a/CHANGELOG.txt Thu Aug 06 19:09:42 2009 +0200 +++ b/CHANGELOG.txt Fri Aug 07 15:20:12 2009 +0200 @@ -1,4 +1,4 @@ -// $Id: CHANGELOG.txt,v 1.15 2009/05/17 11:27:42 karens Exp $ +// $Id: CHANGELOG.txt,v 1.17 2009/06/12 16:38:30 karens Exp $ Version 6.1-dev ================= diff -r cedf71edacf5 -r 5635080385bd views_calc.info --- a/views_calc.info Thu Aug 06 19:09:42 2009 +0200 +++ b/views_calc.info Fri Aug 07 15:20:12 2009 +0200 @@ -5,9 +5,9 @@ package = Views dependencies[] = views -; Information added by drupal.org packaging script on 2009-05-17 -version = "6.x-1.3" +; Information added by drupal.org packaging script on 2009-06-14 +version = "6.x-1.x-dev" core = "6.x" project = "views_calc" -datestamp = "1242559869" +datestamp = "1244939275" diff -r cedf71edacf5 -r 5635080385bd views_calc.install --- a/views_calc.install Thu Aug 06 19:09:42 2009 +0200 +++ b/views_calc.install Fri Aug 07 15:20:12 2009 +0200 @@ -1,5 +1,5 @@ array('type' => 'varchar', 'length' => '255', 'not null' => TRUE, 'default' => ''), 'format' => array('type' => 'varchar', 'length' => '255', 'not null' => TRUE, 'default' => ''), 'custom' => array('type' => 'varchar', 'length' => '255', 'not null' => TRUE, 'default' => ''), + 'base' => array('type' => 'varchar', 'length' => '255', 'not null' => TRUE, 'default' => ''), 'tablelist' => array('type' => 'text', 'not null' => TRUE), 'fieldlist' => array('type' => 'text', 'not null' => TRUE), 'calc' => array('type' => 'text', 'not null' => TRUE), @@ -125,20 +126,8 @@ return $ret; } -/** - * TODO - * Use these values to create new default views, then delete them. - * function views_calc_update_6000() { - $view_calcs = (array) variable_get('views_calc_vid',''); - foreach ($view_calcs as $view_id) { - variable_del('views_calc_'. $view_id .'_col'); - variable_del('views_calc_'. $view_id .'_col_calc'); - variable_del('views_calc_'. $view_id .'_row'); - variable_del('views_calc_'. $view_id .'_row_calc'); - } - variable_del('views_calc_vid'); - variable_del('views_calc_operators'); - -} - */ + $ret = array(); + db_add_field($ret, 'views_calc_fields', 'base', array('type' => 'varchar', 'length' => '255', 'not null' => TRUE, 'default' => 'node')); + return $ret; +} \ No newline at end of file diff -r cedf71edacf5 -r 5635080385bd views_calc.module --- a/views_calc.module Thu Aug 06 19:09:42 2009 +0200 +++ b/views_calc.module Fri Aug 07 15:20:12 2009 +0200 @@ -1,5 +1,4 @@ t('Settings'), 'type' => MENU_LOCAL_TASK, - 'weight' => 10, + 'weight' => 6, 'priority' => 1, 'page callback' => 'drupal_get_form', 'page arguments' => array('views_calc_settings_form'), 'access arguments' => array('administer views calc'), ); + $items['admin/settings/views_calc/export'] = array( + 'title' => 'Export fields', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('views_calc_export_form'), + 'access arguments' => array('create views calc'), + 'type' => MENU_LOCAL_TASK, + 'weight' => 7, + ); + $items['admin/settings/views_calc/import'] = array( + 'title' => 'Import fields', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('views_calc_import_form'), + 'access arguments' => array('create views calc'), + 'type' => MENU_LOCAL_TASK, + 'weight' => 8, + ); + return $items; } @@ -152,8 +168,21 @@ */ function views_calc_fields_form() { $i = 0; - $substitutions = _views_calc_substitutions(); - $reverse = array_flip($substitutions); + $substitutions = array(); + $help = t('

The specific fields that are available in any view depend on the base table used for that view.

'); + require_once(drupal_get_path('module', 'views') .'/includes/admin.inc'); + $base_tables = views_fetch_base_tables(); + foreach ($base_tables as $base => $data) { + $base_subs = _views_calc_substitutions($base); + $substitutions += $base_subs; + $fieldset = array( + '#title' => t('Base table: !name', array('!name' => t($data['title']))), + '#value' => theme('item_list', $base_subs), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $help .= theme('fieldset', $fieldset); + } // display current views calcs fields $fields = _views_calc_fields(); @@ -167,7 +196,7 @@ $form[] = views_calc_field_form_item($i, $field, $substitutions); } $form['#prefix'] = '
'; - $form['#suffix'] = '
Field Substitutions
'. theme('item_list', _views_calc_substitutions()) .'
'; + $form['#suffix'] = '
Field Substitutions
'. $help .'
'; $form['submit'] = array( '#type' => 'submit', '#value' => t('Save'), @@ -182,6 +211,12 @@ if (empty($field)) { $field = array('cid' => 0, 'label' => '', 'tablelist' => '', 'calc' => '', 'format' => '', 'custom' => ''); } + require_once(drupal_get_path('module', 'views') .'/includes/admin.inc'); + $options = array(); + $base_tables = views_fetch_base_tables(); + foreach ($base_tables as $base => $data) { + $options[$base] = t($data['title']); + } $form['group'][$i] = array( '#type' => 'fieldset', '#tree' => TRUE, @@ -197,6 +232,13 @@ '#type' => 'hidden', '#value' => $field['tablelist'], ); + $form['group'][$i]['base'] = array( + '#type' => 'select', + '#title' => t('Base table'), + '#options' => $options, + '#default_value' => !empty($field['base']) && array_key_exists($field['base'], $options) ? $field['base'] : 'node', + '#description' => t('The base table for this field.'), + ); $form['group'][$i]['label'] = array( '#type' => 'textfield', '#title' => t('Label'), @@ -208,7 +250,7 @@ '#type' => 'textarea', '#title' => t('Calculation'), '#default_value' => strtr($field['calc'], $substitutions), - '#description' => t('

The query operation to be performed, using numbers, field substitutions, and '. implode(' ', _views_calc_operators()) .'.

'), + '#description' => t("

The query operation to be performed, using numbers, field substitutions, and ". implode(' ', _views_calc_operators()) .". Leave spaces between parentheses and field names, i.e. 'CONCAT( %field1, ' ', %field2 )'. ". t('Note that all fields must be from the base table selected above! You cannot combine fields from different base tables.') ."

"), ); $form['group'][$i]['format'] = array( '#type' => 'select', @@ -235,14 +277,16 @@ foreach ($edit as $delta => $item) { if ($item['calc'] == '' || !is_numeric($delta)) { // remove blank fields, don't save them - unset($form_values[$delta]); - } else { + continue; + } + else { // Remove all valid values from calc, if anything is left over, it is invalid. // First, remove all field names. $repl = array(); $patterns = array(); - foreach (_views_calc_substitutions() as $key => $value) { + $base = $item['base']; + foreach (_views_calc_substitutions($base) as $key => $value) { $key = trim($value); $count = strlen($value); $replace = preg_quote($value); @@ -250,6 +294,7 @@ $repl[] = '${1}'; } $remaining = trim(preg_replace($patterns, $repl, $item['calc'])); + // Next, remove functions and numbers. $repl = array(); $patterns = array(); @@ -269,12 +314,19 @@ * Save the views calc field settings */ function views_calc_fields_form_submit($form, &$form_state) { - $form_values = $form_state['values']; - $edit = $form_values; + $edit = $form_state['values']; + $form_values = array(); foreach ($edit as $delta => $value) { - if ($value['calc'] == '' || !is_numeric($delta)) { + // If this is some form item we don't care about, skip it. + if (!is_array($value) || !is_numeric($delta)) { + continue; + } + $value['calc'] = trim($value['calc']); + if (empty($value['calc'])) { // remove blank fields, don't save them - unset($form_values[$delta]); + if (!empty($value['cid'])) { + db_query("DELETE FROM {views_calc_fields} WHERE cid=%d", $value['cid']); + } } else { @@ -283,10 +335,12 @@ $form_values[$delta]['format'] = $value['format']; $form_values[$delta]['custom'] = $value['custom']; $form_values[$delta]['calc'] = $value['calc']; + $form_values[$delta]['base'] = $value['base']; // Substitute field names back into the calculation. $matches = array(); - foreach (_views_calc_substitutions() as $key => $value) { + $base = $value['base']; + foreach (_views_calc_substitutions($base) as $key => $value) { $label_patterns[] = "`(^|[^\\\\\\\\])". preg_quote($value) ."`"; $value_patterns[] = "`(^|[^\\\\\\\\])". preg_quote($key) ."`"; $repl[] = '${1}'. $key; @@ -298,7 +352,7 @@ $fields = array(); foreach ($value_patterns as $pattern) { if (preg_match($pattern, $form_values[$delta]['calc'], $results)) { - $fields[] = trim($results[0]); + $fields[trim($results[0])] = trim($results[0]); $tmp = explode('.', trim($results[0])); if (trim($tmp[0])) { $tables[trim($tmp[0])] = trim($tmp[0]); @@ -309,8 +363,9 @@ $form_values[$delta]['fieldlist'] = implode(',', $fields); } } - foreach ($form_values as $delta => $value) { - if ($value['cid'] == 0) { + + foreach ((array) $form_values as $delta => $value) { + if (empty($value['cid'])) { drupal_write_record('views_calc_fields', $value); } else { @@ -365,4 +420,83 @@ $operators = array_filter(_views_calc_operators(), 'trim'); $numbers = range(0, 9); return array_merge($operators, $numbers); +} + + +/** + * Field export form. + */ +function views_calc_export_form() { + + $fields = _views_calc_fields(); + $string = ''; + while ($field = db_fetch_array($fields)) { + $base = $field['base']; + $substitutions = _views_calc_substitutions($base); + $field['calc'] = strtr($field['calc'], $substitutions); + $string .= "\$fields[] = ". var_export((array) $field, TRUE) .";\n"; + } + + $form['#prefix'] = t('This form will export Views Calc custom fields.'); + $form['macro'] = array( + '#type' => 'textarea', + '#rows' => 20, + '#title' => t('Export data'), + '#default_value' => $string, + '#description' => t('This is an export of the custom Views Calc fields. Paste this text into a Views Calc import box to import these fields into another installation. This will only work if the other installation uses the same base tables required by these fields.'), + ); + return $form; +} + +/** + * Field import form. + */ +function views_calc_import_form(&$form_state, $type_name = '') { + $form['#prefix'] = t('This form will import Views Calc custom fields.'); + $form['macro'] = array( + '#type' => 'textarea', + '#rows' => 20, + '#title' => t('Import data'), + '#required' => TRUE, + '#description' => t('Paste the text created by a Views Calc export into this field.'), + ); + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Import'), + ); + // Read in a file if there is one and set it as the default macro value. + if (isset($_REQUEST['macro_file']) && $file = file_get_contents($_REQUEST['macro_file'])) { + $form['macro']['#default_value'] = $file; + if (isset($_REQUEST['type_name'])) { + $form['type_name']['#default_value'] = $_REQUEST['type_name']; + } + $form['#prefix'] .= '

'. t('A file has been pre-loaded for import.') .'

'; + } + $form['#redirect'] = 'admin/settings/views_calc'; + return $form; +} + +/** + * Submit handler for import form. + */ +function views_calc_import_form_submit($form, &$form_state) { + $form_values = $form_state['values']; + $fields = NULL; + + // Use '@' to suppress errors about undefined constants in the macro. + @eval($form_values['macro']); + + if (empty($fields) || !is_array($fields)) { + return; + } + + foreach ($fields as $delta => $field) { + // Don't over-write existing fields, create new ones. + $fields[$delta]['cid'] = NULL; + } + + // Run the values thru drupal_execute() so they are properly validated. + $form_state = array('values' => $fields); + drupal_execute('views_calc_fields_form', $form_state); + } \ No newline at end of file diff -r cedf71edacf5 -r 5635080385bd views_calc.views.inc --- a/views_calc.views.inc Thu Aug 06 19:09:42 2009 +0200 +++ b/views_calc.views.inc Fri Aug 07 15:20:12 2009 +0200 @@ -1,5 +1,5 @@ t('Views Calc'), 'title' => t($field['label']), 'help' => $field['calc'], diff -r cedf71edacf5 -r 5635080385bd views_calc_table.inc --- a/views_calc_table.inc Thu Aug 06 19:09:42 2009 +0200 +++ b/views_calc_table.inc Fri Aug 07 15:20:12 2009 +0200 @@ -1,5 +1,5 @@ get_calc_fields()) { return; @@ -87,7 +87,6 @@ if (!empty($this->view->views_calc_calculation)) { return; } - $this->view->totals = array(); $this->view->sub_totals = array(); @@ -114,6 +113,8 @@ } function do_calculation($calc, $sub_total, $nids = array()) { + // TODO Looks like we have problems unless we + // force a non-page display, need to keep an eye on this. if ($summary_view = views_get_view($this->view->name)) { $summary_view->set_display($this->view->current_display); $summary_view->set_arguments($this->view->args); @@ -122,7 +123,7 @@ $summary_view->views_calc_nids = $nids; $summary_view->views_calc_sub_total = $sub_total; $summary_view->is_cacheable = FALSE; - $summary_view->execute(); + $summary_view->preview(); return array_shift($summary_view->result); } return ''; @@ -168,6 +169,10 @@ foreach ($this->view->field as $field) { $query_field = substr($field->field, 0, 3) == 'cid' ? $field->definition['calc'] : $field->table .'.'. $field->field; $query_alias = $field->field_alias; + // Bail if we have a broken handler. + if ($query_alias == 'unknown') { + continue; + } if (in_array($field->field, $fields)) { // Calculated fields. $this->view->query->add_field(NULL, "$calc($query_field)", $query_alias); @@ -207,6 +212,10 @@ foreach ($this->view->field as $field) { $query_field = substr($field->field, 0, 3) == 'cid' ? $field->definition['calc'] : $field->table .'.'. $field->field; $query_alias = $field->field_alias; + // Bail if we have a broken handler. + if ($query_alias == 'unknown') { + continue; + } $this->view->query->add_table($field->table, NULL, NULL, $field->table); if (!empty($fields) && in_array($field->field, $fields)) { // Calculated fields.