From 4f669300a465918301a92907fd1b688a153f8777 Mon Sep 17 00:00:00 2001 From: Nathan Gray Date: Mon, 13 Feb 2012 18:59:00 +0000 Subject: [PATCH] When merging into a spreadsheet document, convert dates into SS dates --- etemplate/inc/class.bo_merge.inc.php | 136 ++++++++++++++++++------ infolog/inc/class.infolog_merge.inc.php | 8 ++ 2 files changed, 113 insertions(+), 31 deletions(-) diff --git a/etemplate/inc/class.bo_merge.inc.php b/etemplate/inc/class.bo_merge.inc.php index edebc39d9b..e8824d3008 100644 --- a/etemplate/inc/class.bo_merge.inc.php +++ b/etemplate/inc/class.bo_merge.inc.php @@ -29,6 +29,11 @@ abstract class bo_merge */ var $datetime_format = 'Y-m-d H:i'; + /** + * Fields that are to be treated as datetimes, when merged into spreadsheets + */ + var $date_fields = array(); + /** * Mimetype of document processed by merge * @@ -903,43 +908,24 @@ abstract class bo_merge } // Look for numbers, set their value if needed - $format = $replacement = ''; if($this->numeric_fields || count($names)) { foreach((array)$this->numeric_fields as $fieldname) { $names[] = preg_quote($fieldname,'/'); } - switch($mimetype.$mso_application_progid) - { - case 'application/vnd.oasis.opendocument.spreadsheet': // open office calc - $format = '/]+?)office:value-type="[^"]+"([^>]*?)>.?<([a-z].*?)[^>]*>('.implode('|',$names).')<\/\3>.?<\/table:table-cell>/s'; - $replacement = '$4'; - break; - case 'application/xmlExcel.Sheet': // Excel 2003 - $format = '/'.preg_quote('','/').'('.implode('|',$names).')'.preg_quote('','/').'/'; - $replacement = '$1'; - - break; - } - if($format && $names) - { - // Dealing with backtrack limit per AmigoJack 10-Jul-2010 comment on php.net preg-replace docs - $increase = 0; - while($increase < 10) { - $result = preg_replace($format, $replacement, $content, -1, $count); - if( preg_last_error()== PREG_BACKTRACK_LIMIT_ERROR ) { // Only check on backtrack limit failure - ini_set( 'pcre.backtrack_limit', (int)ini_get( 'pcre.backtrack_limit' )+ 10000 ); // Get current limit and increase - $increase++; // Do not overkill the server - } else { // No fail - $content = $result; // On failure $result would be NULL - break; // Exit loop - } - } - if($increase == 10) { - error_log('Backtrack limit exceeded @ ' . ini_get('pcre.backtrack_limit') . ', some cells left as text.'); - } - } + $this->format_spreadsheet_numbers($content, $names, $mimetype.$mso_application_progid); } + + // Look for dates, set their value if needed + if($this->date_fields || count($names)) + { + $names = array(); + foreach((array)$this->date_fields as $fieldname) { + $names[] = preg_quote($fieldname,'/'); + } + $this->format_spreadsheet_dates($content, $names, $replacements, $mimetype.$mso_application_progid); + } + // replace CRLF with linebreak tag of given type switch($mimetype.$mso_application_progid) { @@ -973,6 +959,94 @@ abstract class bo_merge return str_replace(array_keys($replacements),array_values($replacements),$content); } + /** + * Convert numeric values in spreadsheets into actual numeric values + */ + protected function format_spreadsheet_numbers(&$content, $names, $mimetype) + { + foreach((array)$this->numeric_fields as $fieldname) { + $names[] = preg_quote($fieldname,'/'); + } + switch($mimetype) + { + case 'application/vnd.oasis.opendocument.spreadsheet': // open office calc + $format = '/]+?)office:value-type="[^"]+"([^>]*?)>.?<([a-z].*?)[^>]*>('.implode('|',$names).')<\/\3>.?<\/table:table-cell>/s'; + $replacement = '$4'; + break; + case 'application/xmlExcel.Sheet': // Excel 2003 + $format = '/'.preg_quote('','/').'('.implode('|',$names).')'.preg_quote('','/').'/'; + $replacement = '$1'; + + break; + } + if($format && $names) + { + // Dealing with backtrack limit per AmigoJack 10-Jul-2010 comment on php.net preg-replace docs + $increase = 0; + while($increase < 10) { + $result = preg_replace($format, $replacement, $content, -1, $count); + if( preg_last_error()== PREG_BACKTRACK_LIMIT_ERROR ) { // Only check on backtrack limit failure + ini_set( 'pcre.backtrack_limit', (int)ini_get( 'pcre.backtrack_limit' )+ 10000 ); // Get current limit and increase + $increase++; // Do not overkill the server + } else { // No fail + $content = $result; // On failure $result would be NULL + break; // Exit loop + } + } + if($increase == 10) { + error_log('Backtrack limit exceeded @ ' . ini_get('pcre.backtrack_limit') . ', some cells left as text.'); + } + } + } + + /** + * Convert date / timestamp values in spreadsheets into actual date / timestamp values + */ + protected function format_spreadsheet_dates(&$content, $names, &$values, $mimetype) + { + switch($mimetype) + { + case 'application/vnd.oasis.opendocument.spreadsheet': // open office calc + $format = '/]+?)office:value-type="[^"]+"([^>]*?)>.?<([a-z].*?)[^>]*>..('.implode('|',$names).')..<\/\3>.?<\/table:table-cell>/s'; + $replacement = '<$3>\$\$$4\$\$'; + break; + case 'application/xmlExcel.Sheet': // Excel 2003 + $format = '/'.preg_quote('','/').'..('.implode('|',$names).')..'.preg_quote('','/').'/'; + $replacement = '\$\$$1\$\$'; + + break; + } + if($format && $names) + { + // Dealing with backtrack limit per AmigoJack 10-Jul-2010 comment on php.net preg-replace docs + $increase = 0; + while($increase < 10) { + $result = preg_replace($format, $replacement, $content, -1, $count); + if( preg_last_error()== PREG_BACKTRACK_LIMIT_ERROR ) { // Only check on backtrack limit failure + ini_set( 'pcre.backtrack_limit', (int)ini_get( 'pcre.backtrack_limit' )+ 10000 ); // Get current limit and increase + $increase++; // Do not overkill the server + } else { // No fail + $content = $result; // On failure $result would be NULL + break; // Exit loop + } + } + if($increase == 10) { + error_log('Backtrack limit exceeded @ ' . ini_get('pcre.backtrack_limit') . ', some cells left as text.'); + } + } + + // Properly format values for spreadsheet + foreach($names as $field) + { + $key = '$$'.$field.'$$'; + if($values[$key]) + { + $date = egw_time::createFromFormat($this->datetime_format,$values[$key]); + $values[$key] = date('Y-m-d\TH:i:s',egw_time::to($date,'ts')); + } + } + } + /** * Process special flags, such as IF or NELF * diff --git a/infolog/inc/class.infolog_merge.inc.php b/infolog/inc/class.infolog_merge.inc.php index 363977ec69..5da4193d28 100644 --- a/infolog/inc/class.infolog_merge.inc.php +++ b/infolog/inc/class.infolog_merge.inc.php @@ -39,6 +39,14 @@ class infolog_merge extends bo_merge { parent::__construct(); $this->bo = new infolog_bo(); + + $this->date_fields += array( + 'info_startdate', + 'info_enddate', + 'info_datecompleted', + 'info_datemodified', + 'info_created', + ); } /**