mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-26 01:43:47 +01:00
InfoLog/CalDAV: store unsupported iCal properties like custom fields incl. history logging, thought they are not displayed unless you explicitly add a custom field from them (prefixed with one #)
This commit is contained in:
parent
f293f8edb8
commit
fb16ff842d
@ -355,7 +355,7 @@ abstract class bo_tracking
|
|||||||
}
|
}
|
||||||
foreach($changed_fields as $name)
|
foreach($changed_fields as $name)
|
||||||
{
|
{
|
||||||
$status = $this->field2history[$name];
|
$status = isset($this->field2history[$name]) ? $this->field2history[$name] : $name;
|
||||||
//error_log(__METHOD__.__LINE__." Name $name,".' Status:'.array2string($status));
|
//error_log(__METHOD__.__LINE__." Name $name,".' Status:'.array2string($status));
|
||||||
if (is_array($status)) // 1:N relation --> remove common rows
|
if (is_array($status)) // 1:N relation --> remove common rows
|
||||||
{
|
{
|
||||||
@ -423,6 +423,13 @@ abstract class bo_tracking
|
|||||||
//echo "<p>$name: ".array2string($data[$name]).' != '.array2string($old[$name])."</p>\n";
|
//echo "<p>$name: ".array2string($data[$name]).' != '.array2string($old[$name])."</p>\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
foreach($data as $name => $value)
|
||||||
|
{
|
||||||
|
if ($name[0] == '#' && $name[1] == '#' && $value !== $old[$name])
|
||||||
|
{
|
||||||
|
$changed_fields[] = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
//error_log(__METHOD__."() changed_fields=".array2string($changed_fields));
|
//error_log(__METHOD__."() changed_fields=".array2string($changed_fields));
|
||||||
return $changed_fields;
|
return $changed_fields;
|
||||||
}
|
}
|
||||||
|
@ -46,30 +46,24 @@ class historylog_widget
|
|||||||
// 'historylog-helper' => '',
|
// 'historylog-helper' => '',
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
* pre-processing of the history logging extension
|
|
||||||
*
|
|
||||||
* @param string $name form-name of the control
|
|
||||||
* @param mixed &$value value / existing content, can be modified
|
|
||||||
* @param array &$cell array with the widget, can be modified for ui-independent widgets
|
|
||||||
* @param array &$readonlys names of widgets as key, to be made readonly
|
|
||||||
* @param mixed &$extension_data data the extension can store persisten between pre- and post-process
|
|
||||||
* @param etemplate $tmpl reference to the template we belong too
|
|
||||||
* @return boolean true if extra label is allowed, false otherwise
|
|
||||||
*/
|
|
||||||
function pre_process($name,&$value,&$cell,&$readonlys,&$extension_data,etemplate $tmpl)
|
|
||||||
{
|
|
||||||
static $status_widgets;
|
static $status_widgets;
|
||||||
|
|
||||||
if ($cell['type'] == 'historylog-helper')
|
/**
|
||||||
|
* pre-processing of the historylog-helper
|
||||||
|
*
|
||||||
|
* @param mixed &$value value / existing content, can be modified
|
||||||
|
* @param array &$cell array with the widget, can be modified for ui-independent widgets
|
||||||
|
* @return boolean true if extra label is allowed, false otherwise
|
||||||
|
*/
|
||||||
|
private function pre_process_helper(&$value, &$cell)
|
||||||
{
|
{
|
||||||
if (empty($value) && (string)$value !== '0')
|
if (empty($value) && (string)$value !== '0')
|
||||||
{
|
{
|
||||||
$cell = etemplate::empty_cell();
|
$cell = etemplate::empty_cell();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//echo $value.'/'.$cell['size']; _debug_array($status_widgets);
|
//echo $value.'/'.$cell['size']; _debug_array(self::$status_widgets);
|
||||||
$type = isset($status_widgets[$cell['size']]) ? $status_widgets[$cell['size']] : 'label';
|
$type = isset(self::$status_widgets[$cell['size']]) ? self::$status_widgets[$cell['size']] : 'label';
|
||||||
$options = '';
|
$options = '';
|
||||||
if (!is_array($type) && strpos($type,':') !== false)
|
if (!is_array($type) && strpos($type,':') !== false)
|
||||||
{
|
{
|
||||||
@ -83,7 +77,17 @@ class historylog_widget
|
|||||||
$options = implode(',',array($rows,$type1,$type2,$type3,$type4,$type5,$type6));
|
$options = implode(',',array($rows,$type1,$type2,$type3,$type4,$type5,$type6));
|
||||||
}
|
}
|
||||||
$cell = etemplate::empty_cell($type,$cell['name'],array('readonly' => true,'size' => $options));
|
$cell = etemplate::empty_cell($type,$cell['name'],array('readonly' => true,'size' => $options));
|
||||||
if (is_array($type))
|
// display unsupported iCal properties, which have multiple values or attributes
|
||||||
|
if ($type === 'label' && $value[1] === ':' && ($v = unserialize($value)))
|
||||||
|
{
|
||||||
|
$values = $v['values'];
|
||||||
|
foreach((array)$v['params'] as $name => $val)
|
||||||
|
{
|
||||||
|
$values[] = $name.': '.$val;
|
||||||
|
}
|
||||||
|
$value = implode("\n", $values);
|
||||||
|
}
|
||||||
|
elseif (is_array($type))
|
||||||
{
|
{
|
||||||
list($t) = explode(':',$type[0]);
|
list($t) = explode(':',$type[0]);
|
||||||
if (isset($type[0]) && // numeric indexed array --> multiple values of 1:N releation
|
if (isset($type[0]) && // numeric indexed array --> multiple values of 1:N releation
|
||||||
@ -123,10 +127,30 @@ class historylog_widget
|
|||||||
$value = egw_time::server2user($value);
|
$value = egw_time::server2user($value);
|
||||||
}
|
}
|
||||||
if ($cell['type'] == 'label') $cell['no_lang'] = 'true';
|
if ($cell['type'] == 'label') $cell['no_lang'] = 'true';
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pre-processing of the history logging extension
|
||||||
|
*
|
||||||
|
* @param string $name form-name of the control
|
||||||
|
* @param mixed &$value value / existing content, can be modified
|
||||||
|
* @param array &$cell array with the widget, can be modified for ui-independent widgets
|
||||||
|
* @param array &$readonlys names of widgets as key, to be made readonly
|
||||||
|
* @param mixed &$extension_data data the extension can store persisten between pre- and post-process
|
||||||
|
* @param etemplate $tmpl reference to the template we belong too
|
||||||
|
* @return boolean true if extra label is allowed, false otherwise
|
||||||
|
*/
|
||||||
|
function pre_process($name,&$value,&$cell,&$readonlys,&$extension_data,etemplate $tmpl)
|
||||||
|
{
|
||||||
|
switch ($cell['type'])
|
||||||
|
{
|
||||||
|
case 'historylog-helper':
|
||||||
|
return $this->pre_process_helper($value, $cell);
|
||||||
|
}
|
||||||
$app = is_array($value) ? $value['app'] : $GLOBALS['egw_info']['flags']['currentapp'];
|
$app = is_array($value) ? $value['app'] : $GLOBALS['egw_info']['flags']['currentapp'];
|
||||||
$status_widgets = is_array($value) && isset($value['status-widgets']) ? $value['status-widgets'] : null;
|
self::$status_widgets = is_array($value) && isset($value['status-widgets']) ? $value['status-widgets'] : null;
|
||||||
|
|
||||||
$id = is_array($value) ? $value['id'] : $value;
|
$id = is_array($value) ? $value['id'] : $value;
|
||||||
$filter = is_array($value) ? $value['filter'] : array();
|
$filter = is_array($value) ? $value['filter'] : array();
|
||||||
@ -168,24 +192,34 @@ class historylog_widget
|
|||||||
{
|
{
|
||||||
$tmpl->sel_options[$status]['#'.$cf_name] = lang($cf_data['label']);
|
$tmpl->sel_options[$status]['#'.$cf_name] = lang($cf_data['label']);
|
||||||
}
|
}
|
||||||
if (isset($status_widgets['#'.$cf_name])) continue; // app set a status widget --> use that
|
if (isset(self::$status_widgets['#'.$cf_name])) continue; // app set a status widget --> use that
|
||||||
|
|
||||||
if(!is_array($cf_data['values']) || !$cf_data['values'])
|
if(!is_array($cf_data['values']) || !$cf_data['values'])
|
||||||
{
|
{
|
||||||
$status_widgets['#'.$cf_name] = $cf_data['type'] != 'text' ? $cf_data['type'] : 'label';
|
self::$status_widgets['#'.$cf_name] = $cf_data['type'] != 'text' ? $cf_data['type'] : 'label';
|
||||||
}
|
}
|
||||||
elseif($cf_data['values']['@'])
|
elseif($cf_data['values']['@'])
|
||||||
{
|
{
|
||||||
$status_widgets['#'.$cf_name] = customfields_widget::_get_options_from_file($cf_data['values']['@']);
|
self::$status_widgets['#'.$cf_name] = customfields_widget::_get_options_from_file($cf_data['values']['@']);
|
||||||
}
|
}
|
||||||
elseif(count($cf_data['values']))
|
elseif(count($cf_data['values']))
|
||||||
{
|
{
|
||||||
$status_widgets['#'.$cf_name] = $cf_data['values'];
|
self::$status_widgets['#'.$cf_name] = $cf_data['values'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($value) // autorepeated data-row only if there is data
|
if ($value) // autorepeated data-row only if there is data
|
||||||
{
|
{
|
||||||
|
// add "labels" for unsupported iCal properties, we just remove the '##' prefix
|
||||||
|
foreach($value as &$row)
|
||||||
|
{
|
||||||
|
if ($row['status'][0] == '#' && $row['status'][1] == '#' &&
|
||||||
|
isset($tmpl->sel_options[$status]) && !isset($tmpl->sel_options[$status][$row['status']]))
|
||||||
|
{
|
||||||
|
$tmpl->sel_options[$status][$row['status']] = substr($row['status'], 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$tpl->new_cell(2,'date-time','','${row}[user_ts]',array('readonly' => true));
|
$tpl->new_cell(2,'date-time','','${row}[user_ts]',array('readonly' => true));
|
||||||
$tpl->new_cell(2,'select-account','','${row}[owner]',array('readonly' => true));
|
$tpl->new_cell(2,'select-account','','${row}[owner]',array('readonly' => true));
|
||||||
|
|
||||||
@ -201,7 +235,7 @@ class historylog_widget
|
|||||||
}
|
}
|
||||||
// if $value[status-widgets] is set, use them together with the historylog-helper
|
// if $value[status-widgets] is set, use them together with the historylog-helper
|
||||||
// to display new_ & old_value in the specified widget, otherwise use a label
|
// to display new_ & old_value in the specified widget, otherwise use a label
|
||||||
if ($status_widgets)
|
if (self::$status_widgets)
|
||||||
{
|
{
|
||||||
$tpl->new_cell(2,'historylog-helper','','${row}[new_value]',array('size' => '$row_cont[status]','no_lang' => true,'readonly' => true));
|
$tpl->new_cell(2,'historylog-helper','','${row}[new_value]',array('size' => '$row_cont[status]','no_lang' => true,'readonly' => true));
|
||||||
$tpl->new_cell(2,'historylog-helper','','${row}[old_value]',array('size' => '$row_cont[status]','no_lang' => true,'readonly' => true));
|
$tpl->new_cell(2,'historylog-helper','','${row}[old_value]',array('size' => '$row_cont[status]','no_lang' => true,'readonly' => true));
|
||||||
|
@ -694,10 +694,12 @@ class infolog_bo
|
|||||||
* @param boolean $user2server=true conversion between user- and server-time necessary
|
* @param boolean $user2server=true conversion between user- and server-time necessary
|
||||||
* @param boolean $skip_notification=false true = do NOT send notification, false (default) = send notifications
|
* @param boolean $skip_notification=false true = do NOT send notification, false (default) = send notifications
|
||||||
* @param boolean $throw_exception=false Throw an exception (if required fields are not set)
|
* @param boolean $throw_exception=false Throw an exception (if required fields are not set)
|
||||||
|
* @param string $purge_cfs=null null=dont, 'ical'=only iCal X-properties (cfs name starting with "#"), 'all'=all cfs
|
||||||
*
|
*
|
||||||
* @return int/boolean info_id on a successfull write or false
|
* @return int|boolean info_id on a successfull write or false
|
||||||
*/
|
*/
|
||||||
function write(&$values_in, $check_defaults=true, $touch_modified=true, $user2server=true, $skip_notification=false, $throw_exception=false)
|
function write(&$values_in, $check_defaults=true, $touch_modified=true, $user2server=true,
|
||||||
|
$skip_notification=false, $throw_exception=false, $purge_cfs=null)
|
||||||
{
|
{
|
||||||
$values = $values_in;
|
$values = $values_in;
|
||||||
//echo "boinfolog::write()values="; _debug_array($values);
|
//echo "boinfolog::write()values="; _debug_array($values);
|
||||||
@ -902,7 +904,7 @@ class infolog_bo
|
|||||||
//_debug_array($values);
|
//_debug_array($values);
|
||||||
// error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n".array2string($values)."\n",3,'/tmp/infolog');
|
// error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n".array2string($values)."\n",3,'/tmp/infolog');
|
||||||
|
|
||||||
if (($info_id = $this->so->write($to_write,$check_modified)))
|
if (($info_id = $this->so->write($to_write, $check_modified, $purge_cfs)))
|
||||||
{
|
{
|
||||||
if (!isset($values['info_type']) || $status_only || empty($values['caldav_url']))
|
if (!isset($values['info_type']) || $status_only || empty($values['caldav_url']))
|
||||||
{
|
{
|
||||||
|
@ -126,7 +126,7 @@ class infolog_groupdav extends groupdav_handler
|
|||||||
'filter' => $task_filter,
|
'filter' => $task_filter,
|
||||||
'info_type' => explode(',', $infolog_types),
|
'info_type' => explode(',', $infolog_types),
|
||||||
);
|
);
|
||||||
error_log(__METHOD__."('$path', $user) returning ".array2string($ret));
|
//error_log(__METHOD__."('$path', $user) returning ".array2string($ret));
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,6 +327,24 @@ class infolog_ical extends infolog_bo
|
|||||||
}
|
}
|
||||||
$vevent->setAttribute('PRIORITY', $priority);
|
$vevent->setAttribute('PRIORITY', $priority);
|
||||||
|
|
||||||
|
// for CalDAV add all X-Properties previously parsed
|
||||||
|
if ($this->productManufacturer == 'groupdav')
|
||||||
|
{
|
||||||
|
foreach($taskData as $name => $value)
|
||||||
|
{
|
||||||
|
if (substr($name, 0, 2) == '##')
|
||||||
|
{
|
||||||
|
if ($value[1] == ':' && ($attr = unserialize($value)) !== false)
|
||||||
|
{
|
||||||
|
$vevent->setAttribute(substr($name, 2), $attr['value'], $attr['params'], true, $attr['values']);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$vevent->setAttribute(substr($name, 2), $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
$vcal->addComponent($vevent);
|
$vcal->addComponent($vevent);
|
||||||
|
|
||||||
$retval = $vcal->exportvCalendar();
|
$retval = $vcal->exportvCalendar();
|
||||||
@ -461,7 +479,7 @@ class infolog_ical extends infolog_bo
|
|||||||
{
|
{
|
||||||
$taskData['caldav_name'] = $caldav_name;
|
$taskData['caldav_name'] = $caldav_name;
|
||||||
}
|
}
|
||||||
return $this->write($taskData, true, true, false);
|
return $this->write($taskData, true, true, false, false, false, 'ical');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -612,6 +630,7 @@ class infolog_ical extends infolog_bo
|
|||||||
$taskData['info_startdate'] = $component->getAttribute('DTSTART');
|
$taskData['info_startdate'] = $component->getAttribute('DTSTART');
|
||||||
}
|
}
|
||||||
$attribute['value'] += $taskData['info_startdate'];
|
$attribute['value'] += $taskData['info_startdate'];
|
||||||
|
$taskData['##DURATION'] = $attribute['value'];
|
||||||
// fall throught
|
// fall throught
|
||||||
case 'DUE':
|
case 'DUE':
|
||||||
// even as EGroupware only displays the date, we can still store the full value
|
// even as EGroupware only displays the date, we can still store the full value
|
||||||
@ -647,6 +666,8 @@ class infolog_ical extends infolog_bo
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'X-INFOLOG-STATUS':
|
||||||
|
break;
|
||||||
case 'STATUS':
|
case 'STATUS':
|
||||||
// check if we (still) have X-INFOLOG-STATUS set AND it would give an unchanged status (no change by the user)
|
// check if we (still) have X-INFOLOG-STATUS set AND it would give an unchanged status (no change by the user)
|
||||||
$taskData['info_status'] = $this->vtodo2status($attribute['value'],
|
$taskData['info_status'] = $this->vtodo2status($attribute['value'],
|
||||||
@ -679,6 +700,28 @@ class infolog_ical extends infolog_bo
|
|||||||
case 'PERCENT-COMPLETE':
|
case 'PERCENT-COMPLETE':
|
||||||
$taskData['info_percent'] = (int) $attribute['value'];
|
$taskData['info_percent'] = (int) $attribute['value'];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// ignore all PROPS, we dont want to store like X-properties or unsupported props
|
||||||
|
case 'DTSTAMP':
|
||||||
|
case 'SEQUENCE':
|
||||||
|
case 'CREATED':
|
||||||
|
case 'LAST-MODIFIED':
|
||||||
|
//case 'ATTENDEE': // todo: add real support for it
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // X- attribute or other by EGroupware unsupported property
|
||||||
|
error_log(__METHOD__."() $attribute[name] = ".array2string($attribute));
|
||||||
|
// for attributes with multiple values in multiple lines, merge the values
|
||||||
|
if (isset($taskData['##'.$attribute['name']]))
|
||||||
|
{
|
||||||
|
error_log(__METHOD__."() taskData['##$attribute[name]'] = ".array2string($taskData['##'.$attribute['name']]));
|
||||||
|
$attribute['values'] = array_merge(
|
||||||
|
is_array($taskData['##'.$attribute['name']]) ? $taskData['##'.$attribute['name']]['values'] : (array)$taskData['##'.$attribute['name']],
|
||||||
|
$attribute['values']);
|
||||||
|
}
|
||||||
|
$taskData['##'.$attribute['name']] = $attribute['params'] || count($attribute['values']) > 1 ?
|
||||||
|
serialize($attribute) : $attribute['value'];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -529,9 +529,10 @@ class infolog_so
|
|||||||
*
|
*
|
||||||
* @param array $values with the data of the log-entry
|
* @param array $values with the data of the log-entry
|
||||||
* @param int $check_modified=0 old modification date to check before update (include in WHERE)
|
* @param int $check_modified=0 old modification date to check before update (include in WHERE)
|
||||||
|
* @param string $purge_cfs=null null=dont, 'ical'=only iCal X-properties (cfs name starting with "#"), 'all'=all cfs
|
||||||
* @return int|boolean info_id, false on error or 0 if the entry has been updated in the meantime
|
* @return int|boolean info_id, false on error or 0 if the entry has been updated in the meantime
|
||||||
*/
|
*/
|
||||||
function write($values,$check_modified=0) // did _not_ ensure ACL
|
function write($values, $check_modified=0, $purge_cfs=null) // did _not_ ensure ACL
|
||||||
{
|
{
|
||||||
if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length']))
|
if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length']))
|
||||||
{
|
{
|
||||||
@ -604,6 +605,12 @@ class infolog_so
|
|||||||
//echo "<p>soinfolog.write values= "; _debug_array($values);
|
//echo "<p>soinfolog.write values= "; _debug_array($values);
|
||||||
|
|
||||||
// write customfields now
|
// write customfields now
|
||||||
|
if ($purge_cfs)
|
||||||
|
{
|
||||||
|
$where = array('info_id' => $info_id);
|
||||||
|
if ($purge_cfs == 'ical') $where[] = "info_extra_name LIKE '#%'";
|
||||||
|
$this->db->delete($this->extra_table,$where,__LINE__,__FILE__);
|
||||||
|
}
|
||||||
$to_delete = array();
|
$to_delete = array();
|
||||||
foreach($values as $key => $val)
|
foreach($values as $key => $val)
|
||||||
{
|
{
|
||||||
@ -627,7 +634,7 @@ class infolog_so
|
|||||||
$to_delete[] = substr($key,1);
|
$to_delete[] = substr($key,1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($to_delete)
|
if ($to_delete && !$purge_cfs)
|
||||||
{
|
{
|
||||||
$this->db->delete($this->extra_table,array(
|
$this->db->delete($this->extra_table,array(
|
||||||
'info_id' => $info_id,
|
'info_id' => $info_id,
|
||||||
|
Loading…
Reference in New Issue
Block a user