diff views_calc.module @ 3:5635080385bd tip

Merge patch with 1.x-dev
author Franck Deroche <franck@defr.org>
date Fri, 07 Aug 2009 15:20:12 +0200
parents b0a976e17cc7
children
line wrap: on
line diff
--- 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 @@
 <?php
-
 /**
  * @file
  * This module will allow you to add calculated fields to views tables
@@ -114,12 +113,29 @@
   $items['admin/settings/views_calc/settings'] = array(
     'title' => 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('<p>The specific fields that are available in any view depend on the base table used for that view.</p>');
+  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'] = '<div class="views-calc-field-settings">';
-  $form['#suffix'] = '</div><div class="views-calc-field-names"><strong>Field Substitutions</strong><div class="form-item">'. theme('item_list', _views_calc_substitutions()) .'</div></div>';
+  $form['#suffix'] = '</div><div class="views-calc-field-names"><strong>Field Substitutions</strong><div class="form-item">'. $help .'</div></div>';
   $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('<p>The query operation to be performed, using numbers, field substitutions, and '. implode(' ', _views_calc_operators()) .'.</p>'),
+    '#description' => t("<p>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 )'. <strong>". t('Note that all fields must be from the base table selected above! You cannot combine fields from different base tables.') ."</strong></p>"),
     );
   $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'] .= '<p class="error">'. t('A file has been pre-loaded for import.') .'</p>';
+  }
+  $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