Tab delimited exports
dmuth - April 3, 2006 - 00:35
| Project: | Webform |
| Version: | 4.6.x-1.x-dev |
| Component: | Code |
| Category: | feature request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | closed |
Jump to:
Description
I had some problems when trying to do comma-delimited exports and load them into NeoOffice. There were issues with commas in the data, and issues with people having commas in IP addresses, which happens when a submission comes from someone behind a proxy.
Anyway, I've written patches that now export data into tab delimited files, and put quotes around the IP addresses. Let me know if these work out for you.
-- Doug
--- webform.module 2006/03/24 18:26:01 1.1
+++ webform.module 2006/03/31 04:45:44
@@ -1,5 +1,5 @@
<?php
-// $Id: webform.module,v 1.1 2006/03/24 18:26:01 me Exp $
+// $Id: webform.module,v 1.2 2006/03/31 04:45:20 doug Exp doug $
/** This module provides a simple way to create forms and questionnaires
* for your website.
@@ -377,6 +377,10 @@
$items[] = array('path' => 'node/'.$node->nid.'/results/download', 'title' => t('download'),
'callback' => 'webform_results', 'access' => user_access('maintain webforms'),
'type' => MENU_LOCAL_TASK, 'weight' => 7);
+
+ $items[] = array('path' => 'node/'.$node->nid.'/results/download-tsv', 'title' => t('download (tsv)'),
+ 'callback' => 'webform_results', 'access' => user_access('maintain webforms'),
+ 'type' => MENU_LOCAL_TASK, 'weight' => 8);
}
}
@@ -1119,6 +1123,9 @@
break;
case 'download':
$content = _webform_results_download($nid);
+ break;
+ case 'download-tsv':
+ $content = _webform_results_download_tab($nid);
break;
case 'submissions':
default:--- webform.inc 2006/03/24 18:26:01 1.1
+++ webform.inc 2006/03/31 04:45:42
@@ -1,5 +1,5 @@
<?php
- // $Id: webform.inc,v 1.1 2006/03/24 18:26:01 me Exp $
+ // $Id: webform.inc,v 1.2 2006/03/31 04:45:20 doug Exp doug $
/**
* @author Pontus Ullgren <ullgren@user.sourceforge.net>
@@ -119,6 +119,44 @@
exit(0);
}
+/**
+* This function is basically a copy of _webform_results_download() except
+* it sends back a file that is tab-delimited.
+*/
+function _webform_results_download_tab($nid) {
+ $node_info = _webform_get_node_info($nid);
+ $title_string = $node_info->title;
+
+ $file_name = _webform_records_string($title_string, $nid, 'file', "\r\n",
+ "\t");
+
+ drupal_set_header("Content-type: text/plain; charset=utf-8");
+ //
+ // The file will have a .csv extension, despite being tab delimited,
+ // because NeoOffice/J 1.1 for OX/S 10.4 loads a .tsv file into its
+ // word processor for some reason. It has no problem with a tab-delimieted
+ // file that ends in .csv, however.
+ //
+ drupal_set_header("Content-Disposition: attachment; filename="
+ . preg_replace('/\.$/', '', str_replace(' ', '_', $title_string))
+ . ".csv");
+
+ //
+ // Dump the contents of the file to the browser and then delete the
+ // file.
+ //
+ @readfile($file_name); // The @ makes it silent
+ @unlink($file_name); // Clean up, the @ makes it silent
+
+ //
+ // Exit after the download is done so that nothing else gets
+ // into the file.
+ //
+ exit(0);
+
+} // End of _webform_results_download_tab()
+
+
/** function _webform_results_submissions() is a database accessor function designed to return lists
* of submissions and data.
* @param $nid the node id of the webform
@@ -184,10 +222,12 @@
* @param $nid - The drupal node id representing the webform data that is to be extracted.
* @param $print_now Whether to print the result as it is formed or store it to a string and return it.
* @param $new_line - A string to be used to render a new line. Defaults for print on windows based systems
+ * @param $delimiter - A string or character to seperate fields
* @return a reference to a string representing the file in csv format.
**/
-function _webform_records_string($title_string,$nid,$mode = 'file',$new_line = "\r\n"){
+function _webform_records_string($title_string, $nid, $mode = 'file',
+ $new_line = "\r\n", $delimiter = ","){
// Because the components may have changed during the lifestyle of the form
// and because we may be using a low version of MySQL et al. The query is done in two
@@ -214,9 +254,13 @@
$record_array[0]['components'] = array();
$record_array[0]['index'] = array(); // Converts between name and index;
- $header[0] = "$title_string,,,,"; // The inner quotes allow the title to include commas
- $header[1] .= "Submission Details,,,,";
- $header[2] .= "Serial,Timestamp,SID,User,Host";
+// The inner quotes allow the title to include commas
+ $header[0] = "$title_string" . $delimiter . $delimiter . $delimiter
+ . $delimiter;
+ $header[1] .= "Submission Details" . $delimiter . $delimiter . $delimiter
+ . $delimiter;
+ $header[2] .= "Serial" . $delimiter . "Timestamp" . $delimiter . "SID"
+ . $delimiter . "User" . $delimiter . "Host";
$index = 0; // Ensures they retain the correct order
@@ -229,8 +273,8 @@
$record_array[0]['components'][$index]['type'] = $record->type;
$record_array[0]['components'][$index]['value'] = $record->value;
- $header[0] .= ',';
- $header[1] .= ',' . $record->name;
+ $header[0] .= $delimiter;
+ $header[1] .= $delimiter . $record->name;
if($record->type == 'select'){
@@ -242,17 +286,17 @@
$record_array[0]['components'][$index]['options']['items'][$key] = trim($item); // Trim off any linefeeds etc. and put them back in the same place
}
- $header[0] .= str_pad('', count($items) - 1,',');
- $header[1] .= str_pad('', count($items) - 1,',');
+ $header[0] .= str_pad('', count($items) - 1, $delimiter);
+ $header[1] .= str_pad('', count($items) - 1, $delimiter);
foreach($items as $item){
//print trim($item);
- $header[2] .= ',' . '"'.trim($item) . '"'; // The quotes are added so the items can contain commas.
+ $header[2] .= $delimiter . '"'.trim($item) . '"'; // The quotes are added so the items can contain commas.
}
} else {
$record_array[0]['components'][$index]['data'][0] = '';
- $header[2] .= ',';
+ $header[2] .= $delimiter;
}
$record_array[0]['components'][$index]['extra'] = $record->extra;
@@ -324,14 +368,16 @@
break;
case 'print':
- print _webform_make_record_csv_string($record_array,$new_line);
+ print _webform_make_record_csv_string($record_array, $new_line,
+ $delimiter);
break;
case 'string':
- $records .= _webform_make_record_csv_string($record_array,$new_line);
+ $records .= _webform_make_record_csv_string($record_array,
+ $new_line, $delimiter);
break;
case 'file':
default:
- $file_record = _webform_make_record_csv_string($record_array,$new_line);
+ $file_record = _webform_make_record_csv_string($record_array,$new_line, $delimiter);
@fwrite($handle,$file_record);
}
}
@@ -392,14 +438,17 @@
$submission_list_array[] = array($record_count,$record_array[1]['sid'],$record_array[1]['__timestamp'],$record_array[1]['__userid'],$record_array[1]['__remotehost'],$print_view_ref,$print_delete_ref);
break;
case 'print':
- print _webform_make_record_csv_string($record_array,$new_line);
+ print _webform_make_record_csv_string($record_array,
+ $new_line, $delimiter);
break;
case 'string':
- $records .= _webform_make_record_csv_string($record_array,$new_line);
+ $records .= _webform_make_record_csv_string($record_array,
+ $new_line, $delimiter);
break;
case 'file':
default:
- $file_record = _webform_make_record_csv_string($record_array,$new_line);
+ $file_record = _webform_make_record_csv_string($record_array,
+ $new_line, $delimiter);
@fwrite($handle,$file_record);
}
} // end if ($serial != 0)
@@ -422,17 +471,26 @@
}
/** _webform_make_record_csv_string - Decomposes a single session ID to a flat structure.
+ *
+ * NOTE: Since $delimiter was added, this function's name is misleading.
+ * It should probably be changed at some point.
+ *
* @param &$record_array - A reference to the filled record array element.
* @param $new_line - A string to be used to render a new line.
+ * @param $delimiter - A character or string that is our field seperator
* @return a string representing the file in csv format.
**/
-function _webform_make_record_csv_string(&$ra,$new_line){
+function _webform_make_record_csv_string(&$ra, $new_line, $delimiter = ",") {
- $output = $ra[1]['serial'] . ",";
- $output .= $ra[1]['__timestamp'] . ",";
- $output .= $ra[1]['sid'] . ",";
- $output .= $ra[1]['__userid'] . ",";
- $output .= $ra[1]['__remotehost'];
+ $output = $ra[1]['serial'] . $delimiter;
+ $output .= $ra[1]['__timestamp'] . $delimiter;
+ $output .= $ra[1]['sid'] . $delimiter;
+ $output .= $ra[1]['__userid'] . $delimiter;
+ //
+ // Put quotes around the IP as connections through a proxy sometimes
+ // have the internal IP, a comma, and then the external IP.
+ //
+ $output .= '"' . $ra[1]['__remotehost'] . '"';
foreach($ra[0]['index'] as $name => $index){
@@ -448,24 +506,33 @@
foreach($ra[0]['components'][$index]['options']['items'] as $choice){
if(is_array($ra[1]['components'][$index]['data'])){ // When all null, then not array?
if(in_array($choice,$ra[1]['components'][$index]['data'])){ // This was throwing a warning! [Wrong datatype for second argument]
- $output .= ',YES';
+ $output .= $delimiter . 'YES';
} else {
- $output .= ',no';
+ $output .= $delimiter . 'no';
}
} else {
- $output .= ',no';
+ $output .= $delimiter . 'no';
}
}
} else {
$d = $ra[1]['components'][$index]['data'][0];
- $output .= ",\"$d\""; // The internal slashed quotes allow the field to include commas
+ //
+ // Strip newlines and carriage returns. They cause major problems
+ // when trying to import a CSV or TSV file.
+ //
+ $d = str_replace("\n", "", $d);
+ $d = str_replace("\r", "", $d);
+
+ $output .= $delimiter . "\"$d\""; // The internal slashed quotes allow the field to include commas
}
}
}
$output .= $new_line;
return $output;
-}
+
+} // End of _webform_make_record_csv_string()
+
/**
* Pulls the information block for a given node| Attachment | Size |
|---|---|
| webform.inc.diff.txt | 8.74 KB |

#1