mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-24 00:43:20 +01:00
When merging into a spreadsheet document, convert dates into SS dates
r38021: Fix typo in Excel date processing r38111: Fix spreadsheet date/time formatting issue - incorrect parsing of users timer38167: Fix for empty spreadsheet dates in XML & OO.o getting a date anyway
This commit is contained in:
parent
618ff70e73
commit
41ecce19ac
@ -29,6 +29,11 @@ abstract class bo_merge
|
|||||||
*/
|
*/
|
||||||
var $datetime_format = 'Y-m-d H:i';
|
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
|
* Mimetype of document processed by merge
|
||||||
*
|
*
|
||||||
@ -902,43 +907,24 @@ abstract class bo_merge
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Look for numbers, set their value if needed
|
// Look for numbers, set their value if needed
|
||||||
$format = $replacement = '';
|
|
||||||
if($this->numeric_fields || count($names))
|
if($this->numeric_fields || count($names))
|
||||||
{
|
{
|
||||||
foreach((array)$this->numeric_fields as $fieldname) {
|
foreach((array)$this->numeric_fields as $fieldname) {
|
||||||
$names[] = preg_quote($fieldname,'/');
|
$names[] = preg_quote($fieldname,'/');
|
||||||
}
|
}
|
||||||
switch($mimetype.$mso_application_progid)
|
$this->format_spreadsheet_numbers($content, $names, $mimetype.$mso_application_progid);
|
||||||
{
|
|
||||||
case 'application/vnd.oasis.opendocument.spreadsheet': // open office calc
|
|
||||||
$format = '/<table:table-cell([^>]+?)office:value-type="[^"]+"([^>]*?)>.?<([a-z].*?)[^>]*>('.implode('|',$names).')<\/\3>.?<\/table:table-cell>/s';
|
|
||||||
$replacement = '<table:table-cell$1office:value-type="float" office:value="$4"$2>$4</table:table-cell>';
|
|
||||||
break;
|
|
||||||
case 'application/xmlExcel.Sheet': // Excel 2003
|
|
||||||
$format = '/'.preg_quote('<Data ss:Type="String">','/').'('.implode('|',$names).')'.preg_quote('</Data>','/').'/';
|
|
||||||
$replacement = '<Data ss:Type="Number">$1</Data>';
|
|
||||||
|
|
||||||
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.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
// replace CRLF with linebreak tag of given type
|
||||||
switch($mimetype.$mso_application_progid)
|
switch($mimetype.$mso_application_progid)
|
||||||
{
|
{
|
||||||
@ -972,6 +958,116 @@ abstract class bo_merge
|
|||||||
return str_replace(array_keys($replacements),array_values($replacements),$content);
|
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 = '/<table:table-cell([^>]+?)office:value-type="[^"]+"([^>]*?)>.?<([a-z].*?)[^>]*>('.implode('|',$names).')<\/\3>.?<\/table:table-cell>/s';
|
||||||
|
$replacement = '<table:table-cell$1office:value-type="float" office:value="$4"$2>$4</table:table-cell>';
|
||||||
|
break;
|
||||||
|
case 'application/xmlExcel.Sheet': // Excel 2003
|
||||||
|
$format = '/'.preg_quote('<Data ss:Type="String">','/').'('.implode('|',$names).')'.preg_quote('</Data>','/').'/';
|
||||||
|
$replacement = '<Data ss:Type="Number">$1</Data>';
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if(!in_array($mimetype, array(
|
||||||
|
'application/vnd.oasis.opendocument.spreadsheet', // open office calc
|
||||||
|
'application/xmlExcel.Sheet', // Excel 2003
|
||||||
|
//'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'//Excel WTF
|
||||||
|
))) return;
|
||||||
|
|
||||||
|
// Properly format values for spreadsheet
|
||||||
|
foreach($names as $idx => $field)
|
||||||
|
{
|
||||||
|
$key = '$$'.$field.'$$';
|
||||||
|
if($values[$key])
|
||||||
|
{
|
||||||
|
$date = new egw_time($values[$key]);
|
||||||
|
|
||||||
|
if($mimetype == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')//Excel WTF
|
||||||
|
{
|
||||||
|
$interval = $date->diff(new egw_time('1900-01-00 0:00'));
|
||||||
|
$values[$key] = $interval->format('%a')+1;// 1900-02-29 did not exist
|
||||||
|
// 1440 minutes in a day - fractional part
|
||||||
|
$values[$key] += ($date->format('H') * 60 + $date->format('i'))/1440;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$values[$key] = date('Y-m-d\TH:i:s',egw_time::to($date,'ts'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($names[$idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch($mimetype)
|
||||||
|
{
|
||||||
|
case 'application/vnd.oasis.opendocument.spreadsheet': // open office calc
|
||||||
|
$format = '/<table:table-cell([^>]+?)office:value-type="[^"]+"([^>]*?)>.?<([a-z].*?)[^>]*>\$\$('.implode('|',$names).')\$\$<\/\3>.?<\/table:table-cell>/s';
|
||||||
|
$replacement = '<table:table-cell$1office:value-type="date" office:date-value="\$\$$4\$\$"$2><$3>\$\$$4\$\$</$3></table:table-cell>';
|
||||||
|
break;
|
||||||
|
case 'application/xmlExcel.Sheet': // Excel 2003
|
||||||
|
$format = '/'.preg_quote('<Data ss:Type="String">','/').'..('.implode('|',$names).')..'.preg_quote('</Data>','/').'/';
|
||||||
|
$replacement = '<Data ss:Type="DateTime">\$\$$1\$\$</Data>';
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
|
||||||
|
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.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process special flags, such as IF or NELF
|
* Process special flags, such as IF or NELF
|
||||||
*
|
*
|
||||||
|
@ -39,6 +39,14 @@ class infolog_merge extends bo_merge
|
|||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->bo = new infolog_bo();
|
$this->bo = new infolog_bo();
|
||||||
|
|
||||||
|
$this->date_fields += array(
|
||||||
|
'info_startdate',
|
||||||
|
'info_enddate',
|
||||||
|
'info_datecompleted',
|
||||||
|
'info_datemodified',
|
||||||
|
'info_created',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user