[dev] [framework-patch] csv export: Outlook friendly

Francois Marier francois at nit.ca
Fri Aug 6 16:17:25 PDT 2004


Here's another updated patch to make CSV export Outlook-friendly.

This one creates a separate outlookcsv export type.

The CSV import code will handle both types automatically, but the
export type is different:

1- uses \r\n as an EOL
2- doubles quotation marks
3- maps the Horde fields to Outlook ones

Francois
-------------- next part --------------
diff -rpuN -X ../ignorelist ../build/framework/Data/Data/csv.php framework/Data/Data/csv.php
--- ../build/framework/Data/Data/csv.php	Fri Apr 16 13:20:03 2004
+++ framework/Data/Data/csv.php	Fri Aug  6 18:45:03 2004
@@ -56,7 +56,7 @@ class Horde_Data_csv extends Horde_Data 
      *                           If $header was true the rows are associative arrays
      *                           with the field/column names as the keys.
      */
-    function importFile($filename, $header = false, $sep = '', $quote = '', $fields = null)
+    function importFile($filename, $header = false, $sep = '', $quote = '', $fields = null, $import_mapping = array())
     {
         @include_once('File/CSV.php');
 
@@ -93,7 +93,12 @@ class Horde_Data_csv extends Horde_Data 
                 } else {
                     $newline = array();
                     for ($i = 0; $i < count($head); $i++) {
-                        $newline[$head[$i]] = empty($line[$i]) ? '' : $line[$i];
+                        if (array_key_exists($head[$i], $import_mapping)) {
+                            $head[$i] = $import_mapping[$head[$i]];
+                        }
+                        $cell = $line[$i];
+                        $cell = preg_replace("/\"\"/", "\"", $cell);
+                        $newline[$head[$i]] = empty($cell) ? '' : $cell;
                     }
                     $data[] = $newline;
                 }
@@ -122,7 +127,12 @@ class Horde_Data_csv extends Horde_Data 
                 } else {
                     $newline = array();
                     for ($i = 0; $i < count($head); $i++) {
-                        $newline[$head[$i]] = empty($line[$i]) ? '' : $line[$i];
+                        if (array_key_exists($head[$i], $import_mapping)) {
+                            $head[$i] = $import_mapping[$head[$i]];
+                        }
+                        $cell = $line[$i];
+                        $cell = preg_replace("/\"/", "\"\"", $cell);
+                        $newline[$head[$i]] = empty($cell) ? '' : $cell;
                     }
                     $data[] = $newline;
                 }
@@ -146,22 +156,26 @@ class Horde_Data_csv extends Horde_Data 
      *
      * @return string  The CSV data.
      */
-    function exportData($data, $header = false)
+    function exportData($data, $header = false, $export_mapping = array())
     {
         if (!is_array($data) || count($data) == 0) {
             return '';
         }
 
         $export = '';
+        $eol = "\n";
         if ($header) {
             $head = current($data);
             foreach (array_keys($head) as $key) {
                 if (!empty($key)) {
+                    if (array_key_exists($key, $export_mapping)) {
+                        $key = $export_mapping[$key];
+                    }
                     $export .= '"' . $key . '"';
                 }
                 $export .= ',';
             }
-            $export = substr($export, 0, -1) . "\n";
+            $export = substr($export, 0, -1) . $eol;
         }
 
         foreach ($data as $row) {
@@ -171,7 +185,7 @@ class Horde_Data_csv extends Horde_Data 
                 }
                 $export .= ',';
             }
-            $export = substr($export, 0, -1) . "\n";
+            $export = substr($export, 0, -1) . $eol;
         }
 
         return $export;
@@ -189,9 +203,9 @@ class Horde_Data_csv extends Horde_Data 
      * @param boolean $header     If true, the rows of $data are associative arrays
      *                            with field names as their keys.
      */
-    function exportFile($filename, $data, $header = false)
+    function exportFile($filename, $data, $header = false, $export_mapping = array())
     {
-        $export = $this->exportData($data, $header);
+        $export = $this->exportData($data, $header, $export_mapping);
         $GLOBALS['browser']->downloadHeaders($filename, 'application/csv', false, strlen($export));
         echo $export;
     }
@@ -250,11 +264,16 @@ class Horde_Data_csv extends Horde_Data 
 
         case IMPORT_CSV:
             $_SESSION['import_data']['header'] = Util::getFormData('header');
+            $import_mapping = array();
+            if (array_key_exists('import_mapping', $param)) {
+                $import_mapping = $param['import_mapping'];
+            }
             $import_data = $this->importFile($_SESSION['import_data']['file_name'],
                                              $_SESSION['import_data']['header'],
                                              Util::getFormData('sep'),
                                              Util::getFormData('quote'),
-                                             Util::getFormData('fields'));
+                                             Util::getFormData('fields'),
+                                             $import_mapping);
             $_SESSION['import_data']['data'] = $import_data;
             unset($_SESSION['import_data']['map']);
             return IMPORT_MAPPED;
diff -rpuN -X ../ignorelist ../build/framework/Data/Data/outlookcsv.php framework/Data/Data/outlookcsv.php
--- ../build/framework/Data/Data/outlookcsv.php	Wed Dec 31 19:00:00 1969
+++ framework/Data/Data/outlookcsv.php	Fri Aug  6 18:53:22 2004
@@ -0,0 +1,56 @@
+<?php
+
+require_once 'Horde/Data/csv.php';
+
+class Horde_Data_outlookcsv extends Horde_Data_csv {
+
+    /**
+     * Builds a CSV file from a given data structure and returns it as
+     * a string.
+     *
+     * @access public
+     *
+     * @param array   $data       A two-dimensional array containing the data
+     *                            set.
+     * @param boolean $header     If true, the rows of $data are associative
+     *                            arrays with field names as their keys.
+     *
+     * @return string  The CSV data.
+     */
+    function exportData($data, $header = false, $export_mapping = array())
+    {
+        if (!is_array($data) || count($data) == 0) {
+            return '';
+        }
+
+        $export = '';
+        $eol = "\r\n";
+        if ($header) {
+            $head = current($data);
+            foreach (array_keys($head) as $key) {
+                if (!empty($key)) {
+                    if (array_key_exists($key, $export_mapping)) {
+                        $key = $export_mapping[$key];
+                    }
+                    $export .= '"' . $key . '"';
+                }
+                $export .= ',';
+            }
+            $export = substr($export, 0, -1) . $eol;
+        }
+
+        foreach ($data as $row) {
+            foreach ($row as $cell) {
+                if (!empty($cell) || $cell === 0) {
+                    $cell = preg_replace("/\"/", "\"\"", $cell);
+                    $export .= '"' . $cell . '"';
+                }
+                $export .= ',';
+            }
+            $export = substr($export, 0, -1) . $eol;
+        }
+
+        return $export;
+    }
+
+}
diff -rpuN -X ../ignorelist ../build/framework/Data/Data.php framework/Data/Data.php
--- ../build/framework/Data/Data.php	Tue May 25 11:52:43 2004
+++ framework/Data/Data.php	Fri Aug  6 18:50:26 2004
@@ -21,6 +21,7 @@ require_once 'PEAR.php';
 /** @const EXPORT_ICALENDAR Export iCalendar data. */ define('EXPORT_ICALENDAR', 101);
 /** @const EXPORT_VCARD Export vCards.             */ define('EXPORT_VCARD', 102);
 /** @const EXPORT_TSV Export TSV data.             */ define('EXPORT_TSV', 103);
+/** @const EXPORT_CSV Export Outlook CSV data.     */ define('EXPORT_OUTLOOKCSV', 104);
 
 /**
  * Abstract class to handle different kinds of Data formats and to
-------------- next part --------------
diff -rpuN -X ../ignorelist ../build/turba/templates/data/export.inc turba/templates/data/export.inc
--- ../build/turba/templates/data/export.inc	Fri Aug  6 18:55:41 2004
+++ turba/templates/data/export.inc	Fri Aug  6 18:49:25 2004
@@ -14,6 +14,7 @@
     <?php echo _("Select the export format:") ?><br />
     <select name="exportID">
       <option value="<?php echo EXPORT_CSV ?>"><?php echo _("Comma separated values") ?></option>
+      <option value="<?php echo EXPORT_OUTLOOKCSV ?>"><?php echo _("Comma separated values (Microsoft Outlook)") ?></option>
       <option value="<?php echo EXPORT_TSV ?>"><?php echo _("Tab separated values") ?></option>
       <!-- not (yet) implemented -->
       <!--<option value="<?php echo EXPORT_VCARD ?>"><?php echo _("vCard") ?></option>-->
diff -rpuN -X ../ignorelist ../build/turba/data.php turba/data.php
--- ../build/turba/data.php	Fri Aug  6 18:55:41 2004
+++ turba/data.php	Fri Aug  6 18:51:03 2004
@@ -48,8 +48,29 @@ $next_step = IMPORT_FILE;
 $app_fields = array();
 $time_fields = array();
 $error = false;
+$outlook_mapping = array(
+    'firstname' => 'first_name',
+    'middlename' => 'middle_name',
+    'lastname' => 'last_name',
+    'e-mail' => 'email',
+    'homeaddress' => 'homeAddress',
+    'businessaddress' => 'workAddress',
+    'homephone' => 'homePhone',
+    'businessphone' => 'workPhone',
+    'mobilephone' => 'cellPhone',
+    'businessfax' => 'fax',
+    'jobtitle' => 'title',
+    'company' => 'company',
+    'notes' => 'notes',
+    'name' => 'name',
+    'internetfreebusy' => 'freebusyUrl',
+    'nickname' => 'alias',
+    'pgpPublicKey' => 'pgpPublicKey',
+    'smimePublicKey' => 'smimePublicKey',
+    );
 $param = array('time_fields' => $time_fields,
-               'file_types'  => $file_types);
+               'file_types'  => $file_types,
+               'import_mapping' => $outlook_mapping);
 $import_format = Util::getFormData('import_format', '');
 $driver = $import_format;
 if ($driver == 'mulberry' || $driver == 'pine') {
@@ -106,6 +127,10 @@ case 'export':
                 $csv = &Horde_Data::singleton('csv');
                 $csv->exportFile(_("contacts.csv"), $data, true);
                 exit;
+            case EXPORT_OUTLOOKCSV:
+                $csv = &Horde_Data::singleton('outlookcsv');
+                $csv->exportFile(_("contacts.csv"), $data, true, array_flip($outlook_mapping));
+                exit;
             case EXPORT_TSV:
                 $tsv = &Horde_Data::singleton('tsv');
                 $tsv->exportFile(_("contacts.tsv"), $data, true);


More information about the dev mailing list