forked from extern/egroupware
- merged SyncML-1.2 branch with trunk:
svn merge ^/trunk/infolog@27329 ^/branches/SyncML-1.2/infolog . - completly reverted changes in inc/class.boinfolog.inc.php, as they are not related to SyncML at all: svn revert inc/class.boinfolog.inc.php
This commit is contained in:
parent
d333605510
commit
036b2cd14e
@ -4,6 +4,7 @@
|
|||||||
*
|
*
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
|
* @author Joerg Lehrke <jlehrke@noc.de>
|
||||||
* @package infolog
|
* @package infolog
|
||||||
* @copyright (c) 2003-8 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @copyright (c) 2003-8 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
@ -513,7 +514,6 @@ class infolog_bo
|
|||||||
$GLOBALS['egw']->contenthistory->updateTimeStamp('infolog_'.$info['info_type'], $info_id, 'delete', time());
|
$GLOBALS['egw']->contenthistory->updateTimeStamp('infolog_'.$info['info_type'], $info_id, 'delete', time());
|
||||||
|
|
||||||
// send email notifications and do the history logging
|
// send email notifications and do the history logging
|
||||||
require_once(EGW_INCLUDE_ROOT.'/infolog/inc/class.infolog_tracking.inc.php');
|
|
||||||
if (!is_object($this->tracking))
|
if (!is_object($this->tracking))
|
||||||
{
|
{
|
||||||
$this->tracking = new infolog_tracking($this);
|
$this->tracking = new infolog_tracking($this);
|
||||||
@ -578,7 +578,7 @@ class infolog_bo
|
|||||||
if ($set_completed)
|
if ($set_completed)
|
||||||
{
|
{
|
||||||
$values['info_datecompleted'] = $this->user_time_now;
|
$values['info_datecompleted'] = $this->user_time_now;
|
||||||
$values['info_percent'] = '100%';
|
$values['info_percent'] = 100;
|
||||||
$forcestatus = true;
|
$forcestatus = true;
|
||||||
$status = 'done';
|
$status = 'done';
|
||||||
if (isset($values['info_type']) && !in_array($values['info_status'],array('done','billed','cancelled'))) {
|
if (isset($values['info_type']) && !in_array($values['info_status'],array('done','billed','cancelled'))) {
|
||||||
@ -608,7 +608,7 @@ class infolog_bo
|
|||||||
}
|
}
|
||||||
if (in_array($values['info_status'],array('done','billed')))
|
if (in_array($values['info_status'],array('done','billed')))
|
||||||
{
|
{
|
||||||
$values['info_percent'] = '100';
|
$values['info_percent'] = 100;
|
||||||
}
|
}
|
||||||
if ((int)$values['info_percent'] == 100 && !in_array($values['info_status'],array('done','billed','cancelled')))
|
if ((int)$values['info_percent'] == 100 && !in_array($values['info_status'],array('done','billed','cancelled')))
|
||||||
{
|
{
|
||||||
@ -659,7 +659,7 @@ class infolog_bo
|
|||||||
// Should only an entry be updated which includes the original modification date?
|
// Should only an entry be updated which includes the original modification date?
|
||||||
// Used in the web-GUI to check against a modification by an other user while editing the entry.
|
// Used in the web-GUI to check against a modification by an other user while editing the entry.
|
||||||
// It's now disabled for xmlrpc, as otherwise the xmlrpc code need to be changed!
|
// It's now disabled for xmlrpc, as otherwise the xmlrpc code need to be changed!
|
||||||
$xmprpc = is_object($GLOBALS['server']) && $GLOBALS['server']->last_method;
|
$xmlrpc = is_object($GLOBALS['server']) && $GLOBALS['server']->last_method;
|
||||||
$check_modified = $values['info_datemodified'] && !$xmlrpc ? $values['info_datemodified']-$this->tz_offset_s : false;
|
$check_modified = $values['info_datemodified'] && !$xmlrpc ? $values['info_datemodified']-$this->tz_offset_s : false;
|
||||||
$values['info_datemodified'] = $this->user_time_now;
|
$values['info_datemodified'] = $this->user_time_now;
|
||||||
}
|
}
|
||||||
@ -1080,7 +1080,7 @@ class infolog_bo
|
|||||||
$cat_id = $this->categories->name2id($cat_name, 'X-');
|
$cat_id = $this->categories->name2id($cat_name, 'X-');
|
||||||
if (!$cat_id)
|
if (!$cat_id)
|
||||||
{
|
{
|
||||||
$cat_id = $this->categories->add(array('name' => $cat_name,'descr' => $cat_name));
|
$cat_id = $this->categories->add(array('name' => $cat_name, 'descr' => $cat_name, 'access' => 'private'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cat_id)
|
if ($cat_id)
|
||||||
@ -1172,32 +1172,32 @@ class infolog_bo
|
|||||||
// check if we already send a notification for that infolog entry, eg. starting and due on same day
|
// check if we already send a notification for that infolog entry, eg. starting and due on same day
|
||||||
if (in_array($info['info_id'],$notified_info_ids)) continue;
|
if (in_array($info['info_id'],$notified_info_ids)) continue;
|
||||||
|
|
||||||
if (is_null($tracking) || $tracking->user != $user)
|
if (is_null($this->tracking) || $this->tracking->user != $user)
|
||||||
{
|
{
|
||||||
require_once(EGW_INCLUDE_ROOT.'/infolog/inc/class.infolog_tracking.inc.php');
|
require_once(EGW_INCLUDE_ROOT.'/infolog/inc/class.infolog_tracking.inc.php');
|
||||||
$tracking = new infolog_tracking($this);
|
$this->tracking = new infolog_tracking($this);
|
||||||
}
|
}
|
||||||
switch($pref)
|
switch($pref)
|
||||||
{
|
{
|
||||||
case 'notify_due_responsible':
|
case 'notify_due_responsible':
|
||||||
$info['message'] = lang('%1 you are responsible for is due at %2',$this->enums['type'][$info['info_type']],
|
$info['message'] = lang('%1 you are responsible for is due at %2',$this->enums['type'][$info['info_type']],
|
||||||
$tracking->datetime($info['info_enddate']-$this->tz_offset_s,false));
|
$this->tracking->datetime($info['info_enddate']-$this->tz_offset_s,false));
|
||||||
break;
|
break;
|
||||||
case 'notify_due_delegated':
|
case 'notify_due_delegated':
|
||||||
$info['message'] = lang('%1 you delegated is due at %2',$this->enums['type'][$info['info_type']],
|
$info['message'] = lang('%1 you delegated is due at %2',$this->enums['type'][$info['info_type']],
|
||||||
$tracking->datetime($info['info_enddate']-$this->tz_offset_s,false));
|
$this->tracking->datetime($info['info_enddate']-$this->tz_offset_s,false));
|
||||||
break;
|
break;
|
||||||
case 'notify_start_responsible':
|
case 'notify_start_responsible':
|
||||||
$info['message'] = lang('%1 you are responsible for is starting at %2',$this->enums['type'][$info['info_type']],
|
$info['message'] = lang('%1 you are responsible for is starting at %2',$this->enums['type'][$info['info_type']],
|
||||||
$tracking->datetime($info['info_startdate']-$this->tz_offset_s,null));
|
$this->tracking->datetime($info['info_startdate']-$this->tz_offset_s,null));
|
||||||
break;
|
break;
|
||||||
case 'notify_start_delegated':
|
case 'notify_start_delegated':
|
||||||
$info['message'] = lang('%1 you delegated is starting at %2',$this->enums['type'][$info['info_type']],
|
$info['message'] = lang('%1 you delegated is starting at %2',$this->enums['type'][$info['info_type']],
|
||||||
$tracking->datetime($info['info_startdate']-$this->tz_offset_s,null));
|
$this->tracking->datetime($info['info_startdate']-$this->tz_offset_s,null));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
error_log("notifiying $user($email) about $info[info_subject]: $info[message]");
|
error_log("notifiying $user($email) about $info[info_subject]: $info[message]");
|
||||||
$tracking->send_notification($info,null,$email,$user,$pref);
|
$this->tracking->send_notification($info,null,$email,$user,$pref);
|
||||||
|
|
||||||
$notified_info_ids[] = $info['info_id'];
|
$notified_info_ids[] = $info['info_id'];
|
||||||
}
|
}
|
||||||
@ -1221,6 +1221,8 @@ class infolog_bo
|
|||||||
'template' => 'CANCELLED',
|
'template' => 'CANCELLED',
|
||||||
'nonactive' => 'CANCELLED',
|
'nonactive' => 'CANCELLED',
|
||||||
'archive' => 'CANCELLED',
|
'archive' => 'CANCELLED',
|
||||||
|
'deferred' => 'NEEDS-ACTION',
|
||||||
|
'waiting' => 'IN-PROCESS',
|
||||||
);
|
);
|
||||||
|
|
||||||
/** conversion of vtodo status to infolog status
|
/** conversion of vtodo status to infolog status
|
||||||
@ -1229,7 +1231,9 @@ class infolog_bo
|
|||||||
*/
|
*/
|
||||||
var $_vtodo2status = array(
|
var $_vtodo2status = array(
|
||||||
'NEEDS-ACTION' => 'not-started',
|
'NEEDS-ACTION' => 'not-started',
|
||||||
|
'NEEDS ACTION' => 'not-started',
|
||||||
'IN-PROCESS' => 'ongoing',
|
'IN-PROCESS' => 'ongoing',
|
||||||
|
'IN PROCESS' => 'ongoing',
|
||||||
'COMPLETED' => 'done',
|
'COMPLETED' => 'done',
|
||||||
'CANCELLED' => 'cancelled',
|
'CANCELLED' => 'cancelled',
|
||||||
);
|
);
|
||||||
@ -1285,4 +1289,128 @@ class infolog_bo
|
|||||||
}
|
}
|
||||||
return 'ongoing';
|
return 'ongoing';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Parent ID of an InfoLog entry
|
||||||
|
*
|
||||||
|
* @param string $_guid
|
||||||
|
* @return string parentID
|
||||||
|
*/
|
||||||
|
function getParentID($_guid)
|
||||||
|
{
|
||||||
|
#Horde::logMessage("getParentID($_guid)", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
|
$parentID = False;
|
||||||
|
$myfilter = array('col_filter' => array('info_uid'=>$_guid)) ;
|
||||||
|
if ($_guid && ($found=$this->search($myfilter)) && ($uidmatch = array_shift($found))) {
|
||||||
|
$parentID = $uidmatch['info_id'];
|
||||||
|
};
|
||||||
|
return $parentID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to find a matching db entry
|
||||||
|
*
|
||||||
|
* @param array $egwData the vTODO data we try to find
|
||||||
|
* @param boolean $relax=false if asked to relax, we only match against some key fields
|
||||||
|
* @return the infolog_id of the matching entry or false (if none matches)
|
||||||
|
*/
|
||||||
|
function findVTODO($egwData, $relax=false)
|
||||||
|
{
|
||||||
|
$myfilter = array('col_filter' => array('info_uid'=>$egwData['info_uid'])) ;
|
||||||
|
if ($egwData['info_uid']
|
||||||
|
&& ($found = $this->search($myfilter))
|
||||||
|
&& ($uidmatch = array_shift($found)))
|
||||||
|
{
|
||||||
|
return $uidmatch['info_id'];
|
||||||
|
};
|
||||||
|
unset($egwData['info_uid']);
|
||||||
|
|
||||||
|
$filter = array();
|
||||||
|
|
||||||
|
$description = '';
|
||||||
|
if (!empty($egwData['info_des'])) {
|
||||||
|
$description = trim(preg_replace("/\r?\n?\\[[A-Z_]+:.*\\]/i", '', $egwData['info_des']));
|
||||||
|
unset($egwData['info_des']);
|
||||||
|
// Avoid quotation problems
|
||||||
|
$description = preg_replace("/[^\x20-\x7F].*/", '', $description);
|
||||||
|
if (strlen($description)) {
|
||||||
|
$filter['search'] = $description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($egwData['info_id']
|
||||||
|
&& ($found = $this->read($egwData['info_id'])))
|
||||||
|
{
|
||||||
|
// We only do a simple consistency check
|
||||||
|
if ($found['info_subject'] == $egwData['info_subject']
|
||||||
|
&& strpos($found['info_des'], $description) === 0)
|
||||||
|
{
|
||||||
|
return $found['info_id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($egwData['info_id']);
|
||||||
|
|
||||||
|
// priority does not need to match
|
||||||
|
unset($egwData['info_priority']);
|
||||||
|
|
||||||
|
$filter['col_filter'] = $egwData;
|
||||||
|
|
||||||
|
if($foundItems = $this->search($filter)) {
|
||||||
|
if(count($foundItems) > 0) {
|
||||||
|
$itemIDs = array_keys($foundItems);
|
||||||
|
return $itemIDs[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$filter = array();
|
||||||
|
|
||||||
|
if (!$relax && strlen($description)) {
|
||||||
|
$filter['search'] = $description;
|
||||||
|
}
|
||||||
|
|
||||||
|
$filter['col_filter'] = $egwData;
|
||||||
|
|
||||||
|
// search for date only match
|
||||||
|
unset($filter['col_filter']['info_startdate']);
|
||||||
|
unset($filter['col_filter']['info_datecompleted']);
|
||||||
|
|
||||||
|
// try tasks without category
|
||||||
|
unset($filter['col_filter']['info_cat']);
|
||||||
|
|
||||||
|
#Horde::logMessage("findVTODO Filter\n"
|
||||||
|
# . print_r($filter, true),
|
||||||
|
# __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
foreach ($this->search($filter) as $itemID => $taskData) {
|
||||||
|
# Horde::logMessage("findVTODO Trying\n"
|
||||||
|
# . print_r($taskData, true),
|
||||||
|
# __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
if (isset($egwData['info_cat'])
|
||||||
|
&& isset($taskData['info_cat']) && $taskData['info_cat']
|
||||||
|
&& $egwData['info_cat'] != $taskData['info_cat']) continue;
|
||||||
|
if (isset($egwData['info_startdate'])
|
||||||
|
&& isset($taskData['info_startdate']) && $taskData['info_startdate']) {
|
||||||
|
$parts = @getdate($taskData['info_startdate']);
|
||||||
|
$startdate = @mktime(0, 0, 0, $parts['mon'], $parts['mday'], $parts['year']);
|
||||||
|
if ($egwData['info_startdate'] != $startdate) continue;
|
||||||
|
}
|
||||||
|
// some clients don't support DTSTART
|
||||||
|
if (isset($egwData['info_startdate'])
|
||||||
|
&& (!isset($taskData['info_startdate']) || !$taskData['info_startdate'])
|
||||||
|
&& !$relax) continue;
|
||||||
|
if (isset($egwData['info_datecompleted'])
|
||||||
|
&& isset($taskData['info_datecompleted']) && $taskData['info_datecompleted']) {
|
||||||
|
$parts = @getdate($taskData['info_datecompleted']);
|
||||||
|
$enddate = @mktime(0, 0, 0, $parts['mon'], $parts['mday'], $parts['year']);
|
||||||
|
if ($egwData['info_datecompleted'] != $enddate) continue;
|
||||||
|
}
|
||||||
|
if ((isset($egwData['info_datecompleted'])
|
||||||
|
&& (!isset($taskData['info_datecompleted']) || !$taskData['info_datecompleted'])) ||
|
||||||
|
(!isset($egwData['info_datecompleted'])
|
||||||
|
&& isset($taskData['info_datecompleted']) && $taskData['info_datecompleted'])
|
||||||
|
&& !$relax) continue;
|
||||||
|
return($itemID);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,6 +331,7 @@ class infolog_hooks
|
|||||||
private static function all_cats()
|
private static function all_cats()
|
||||||
{
|
{
|
||||||
$categories = new categories('','infolog');
|
$categories = new categories('','infolog');
|
||||||
|
$accountId = $GLOBALS['egw_info']['user']['account_id'];
|
||||||
|
|
||||||
foreach((array)$categories->return_sorted_array(0,False,'','','',true) as $cat)
|
foreach((array)$categories->return_sorted_array(0,False,'','','',true) as $cat)
|
||||||
{
|
{
|
||||||
@ -340,6 +341,14 @@ class infolog_hooks
|
|||||||
{
|
{
|
||||||
$s .= ' ♦';
|
$s .= ' ♦';
|
||||||
}
|
}
|
||||||
|
elseif ($cat['owner'] != $accountId)
|
||||||
|
{
|
||||||
|
$s .= '<' . $GLOBALS['egw']->accounts->id2name($cat['owner'], 'account_fullname') . '>';
|
||||||
|
}
|
||||||
|
elseif ($cat['access'] == 'private')
|
||||||
|
{
|
||||||
|
$s .= ' ♥';
|
||||||
|
}
|
||||||
$sel_options[$cat['id']] = $s; // 0.9.14 only
|
$sel_options[$cat['id']] = $s; // 0.9.14 only
|
||||||
}
|
}
|
||||||
return $sel_options;
|
return $sel_options;
|
||||||
|
@ -4,15 +4,14 @@
|
|||||||
*
|
*
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Lars Kneschke <lkneschke@egroupware.org>
|
* @author Lars Kneschke <lkneschke@egroupware.org>
|
||||||
|
* @author Joerg Lehrke <jlehrke@noc.de>
|
||||||
* @package infolog
|
* @package infolog
|
||||||
* @subpackage syncml
|
* @subpackage syncml
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once EGW_API_INC.'/horde/Horde/iCalendar.php';
|
require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php';
|
||||||
require_once EGW_API_INC.'/horde/Horde/iCalendar/vnote.php';
|
|
||||||
require_once EGW_API_INC.'/horde/Horde/iCalendar/vtodo.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* InfoLog: Create and parse iCal's
|
* InfoLog: Create and parse iCal's
|
||||||
@ -20,17 +19,24 @@ require_once EGW_API_INC.'/horde/Horde/iCalendar/vtodo.php';
|
|||||||
*/
|
*/
|
||||||
class infolog_ical extends infolog_bo
|
class infolog_ical extends infolog_bo
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var array conversion of the priority egw => ical
|
||||||
|
*/
|
||||||
var $egw_priority2vcal_priority = array(
|
var $egw_priority2vcal_priority = array(
|
||||||
0 => 3,
|
0 => 9, // low
|
||||||
1 => 2,
|
1 => 5, // normal
|
||||||
2 => 1,
|
2 => 3, // high
|
||||||
3 => 1,
|
3 => 1, // urgent
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array conversion of the priority ical => egw
|
||||||
|
*/
|
||||||
var $vcal_priority2egw_priority = array(
|
var $vcal_priority2egw_priority = array(
|
||||||
1 => 2,
|
9 => 0, 8 => 0, 7 => 0, // low
|
||||||
2 => 1,
|
6 => 1, 5 => 1, 4 => 1, 0 => 1, // normal
|
||||||
3 => 0,
|
3 => 2, 2 => 2, // high
|
||||||
|
1 => 3, // urgent
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,6 +47,32 @@ class infolog_ical extends infolog_bo
|
|||||||
var $productManufacturer = 'file';
|
var $productManufacturer = 'file';
|
||||||
var $productName = '';
|
var $productName = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shall we use the UID extensions of the description field?
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
var $uidExtension = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client CTCap Properties
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $clientProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param array $_clientProperties client properties
|
||||||
|
*/
|
||||||
|
function __construct(&$_clientProperties = array())
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->clientProperties = $_clientProperties;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exports one InfoLog tast to an iCalendar VTODO
|
* Exports one InfoLog tast to an iCalendar VTODO
|
||||||
*
|
*
|
||||||
@ -53,9 +85,36 @@ class infolog_ical extends infolog_bo
|
|||||||
{
|
{
|
||||||
$taskData = $this->read($_taskID);
|
$taskData = $this->read($_taskID);
|
||||||
|
|
||||||
$taskData = $GLOBALS['egw']->translation->convert($taskData, $GLOBALS['egw']->translation->charset(), 'UTF-8');
|
if ($taskData['info_id_parent'])
|
||||||
|
{
|
||||||
|
$parent = $this->read($taskData['info_id_parent']);
|
||||||
|
$taskData['info_id_parent'] = $parent['info_uid'];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$taskData['info_id_parent'] = '';
|
||||||
|
}
|
||||||
|
|
||||||
$taskGUID = $GLOBALS['egw']->common->generate_uid('infolog_task',$_taskID);
|
if ($this->uidExtension)
|
||||||
|
{
|
||||||
|
if (!preg_match('/\[UID:.+\]/m', $taskData['info_des']))
|
||||||
|
{
|
||||||
|
$taskData['info_des'] .= "\n[UID:" . $taskData['info_uid'] . "]";
|
||||||
|
if ($taskData['info_id_parent'] != '')
|
||||||
|
{
|
||||||
|
$taskData['info_des'] .= "\n[PARENT_UID:" . $taskData['info_id_parent'] . "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($taskData['info_cat']))
|
||||||
|
{
|
||||||
|
$cats = $this->get_categories(array($taskData['info_cat']));
|
||||||
|
$taskData['info_cat'] = $cats[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$taskData = $GLOBALS['egw']->translation->convert($taskData,
|
||||||
|
$GLOBALS['egw']->translation->charset(), 'UTF-8');
|
||||||
|
|
||||||
$vcal = new Horde_iCalendar;
|
$vcal = new Horde_iCalendar;
|
||||||
$vcal->setAttribute('VERSION',$_version);
|
$vcal->setAttribute('VERSION',$_version);
|
||||||
@ -63,35 +122,91 @@ class infolog_ical extends infolog_bo
|
|||||||
|
|
||||||
$vevent = Horde_iCalendar::newComponent('VTODO',$vcal);
|
$vevent = Horde_iCalendar::newComponent('VTODO',$vcal);
|
||||||
|
|
||||||
|
if (!isset($this->clientProperties['SUMMARY']['Size']))
|
||||||
|
{
|
||||||
|
// make SUMMARY a required field
|
||||||
|
$this->clientProperties['SUMMARY']['Size'] = 0xFFFF;
|
||||||
|
$this->clientProperties['SUMMARY']['NoTruncate'] = false;
|
||||||
|
}
|
||||||
// set fields that may contain non-ascii chars and encode them if necessary
|
// set fields that may contain non-ascii chars and encode them if necessary
|
||||||
foreach (array(
|
foreach (array(
|
||||||
'SUMMARY' => $taskData['info_subject'],
|
'SUMMARY' => $taskData['info_subject'],
|
||||||
'DESCRIPTION' => $taskData['info_des'],
|
'DESCRIPTION' => $taskData['info_des'],
|
||||||
'LOCATION' => $taskData['info_location'],
|
'LOCATION' => $taskData['info_location'],
|
||||||
|
'RELATED-TO' => $taskData['info_id_parent'],
|
||||||
|
'UID' => $taskData['info_uid'],
|
||||||
|
'CATEGORIES' => $taskData['info_cat'],
|
||||||
) as $field => $value)
|
) as $field => $value)
|
||||||
{
|
{
|
||||||
$vevent->setAttribute($field,$value);
|
if (isset($this->clientProperties[$field]['Size']))
|
||||||
$options = array();
|
|
||||||
if($this->productManufacturer != 'GroupDAV' && preg_match('/([\000-\012\015\016\020-\037\075])/',$value))
|
|
||||||
{
|
{
|
||||||
$options['ENCODING'] = 'QUOTED-PRINTABLE';
|
$size = $this->clientProperties[$field]['Size'];
|
||||||
|
$noTruncate = $this->clientProperties[$field]['NoTruncate'];
|
||||||
|
#Horde::logMessage("VTODO $field Size: $size, NoTruncate: " .
|
||||||
|
# ($noTruncate ? 'TRUE' : 'FALSE'), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
}
|
}
|
||||||
if($this->productManufacturer != 'GroupDAV' && preg_match('/([\177-\377])/',$value))
|
else
|
||||||
|
{
|
||||||
|
$size = -1;
|
||||||
|
$noTruncate = false;
|
||||||
|
}
|
||||||
|
$cursize = strlen($value);
|
||||||
|
if (($size > 0) && $cursize > $size)
|
||||||
|
{
|
||||||
|
if ($noTruncate)
|
||||||
|
{
|
||||||
|
Horde::logMessage("VTODO $field omitted due to maximum size $size",
|
||||||
|
__FILE__, __LINE__, PEAR_LOG_WARNING);
|
||||||
|
continue; // skip field
|
||||||
|
}
|
||||||
|
// truncate the value to size
|
||||||
|
$value = substr($value, 0, $size -1);
|
||||||
|
#Horde::logMessage("VTODO $field truncated to maximum size $size",
|
||||||
|
# __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($value) && ($size < 0 || $noTruncate)) continue;
|
||||||
|
|
||||||
|
if ($field == 'RELATED-TO')
|
||||||
|
{
|
||||||
|
$options = array('RELTYPE' => 'PARENT');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$options = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if(preg_match('/([\000-\012\015\016\020-\037\075])/', $value)) {
|
||||||
|
$options['ENCODING'] = 'QUOTED-PRINTABLE';
|
||||||
|
}*/
|
||||||
|
if ($this->productManufacturer != 'groupdav'
|
||||||
|
&& preg_match('/([\177-\377])/',$value))
|
||||||
{
|
{
|
||||||
$options['CHARSET'] = 'UTF-8';
|
$options['CHARSET'] = 'UTF-8';
|
||||||
}
|
}
|
||||||
if ($options) $vevent->setParameter($field, $options);
|
$vevent->setAttribute($field, $value, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($taskData['info_startdate'])
|
if ($taskData['info_startdate'])
|
||||||
|
{
|
||||||
$vevent->setAttribute('DTSTART',$taskData['info_startdate']);
|
$vevent->setAttribute('DTSTART',$taskData['info_startdate']);
|
||||||
|
}
|
||||||
|
|
||||||
if ($taskData['info_enddate'])
|
if ($taskData['info_enddate'])
|
||||||
$vevent->setAttribute('DUE',$taskData['info_enddate']);
|
{
|
||||||
|
$parts = @getdate($taskData['info_enddate']);
|
||||||
|
$value = @mktime(12, 0, 0, $parts['mon'], $parts['mday'], $parts['year']);
|
||||||
|
$vevent->setAttribute('DUE', $value);
|
||||||
|
}
|
||||||
|
|
||||||
if ($taskData['info_datecompleted'])
|
if ($taskData['info_datecompleted'])
|
||||||
|
{
|
||||||
$vevent->setAttribute('COMPLETED',$taskData['info_datecompleted']);
|
$vevent->setAttribute('COMPLETED',$taskData['info_datecompleted']);
|
||||||
|
}
|
||||||
|
|
||||||
$vevent->setAttribute('DTSTAMP',time());
|
$vevent->setAttribute('DTSTAMP',time());
|
||||||
$vevent->setAttribute('CREATED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_task',$_taskID,'add'));
|
$vevent->setAttribute('CREATED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_task',$_taskID,'add'));
|
||||||
$vevent->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_task',$_taskID,'modify'));
|
$vevent->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_task',$_taskID,'modify'));
|
||||||
$vevent->setAttribute('UID',$taskData['info_uid']);
|
|
||||||
$vevent->setAttribute('CLASS',$taskData['info_access'] == 'public' ? 'PUBLIC' : 'PRIVATE');
|
$vevent->setAttribute('CLASS',$taskData['info_access'] == 'public' ? 'PUBLIC' : 'PRIVATE');
|
||||||
$vevent->setAttribute('STATUS',$this->status2vtodo($taskData['info_status']));
|
$vevent->setAttribute('STATUS',$this->status2vtodo($taskData['info_status']));
|
||||||
// we try to preserv the original infolog status as X-INFOLOG-STATUS, so we can restore it, if the user does not modify STATUS
|
// we try to preserv the original infolog status as X-INFOLOG-STATUS, so we can restore it, if the user does not modify STATUS
|
||||||
@ -99,16 +214,12 @@ class infolog_ical extends infolog_bo
|
|||||||
$vevent->setAttribute('PERCENT-COMPLETE',$taskData['info_percent']);
|
$vevent->setAttribute('PERCENT-COMPLETE',$taskData['info_percent']);
|
||||||
$vevent->setAttribute('PRIORITY',$this->egw_priority2vcal_priority[$taskData['info_priority']]);
|
$vevent->setAttribute('PRIORITY',$this->egw_priority2vcal_priority[$taskData['info_priority']]);
|
||||||
|
|
||||||
if (!empty($taskData['info_cat']))
|
|
||||||
{
|
|
||||||
$cats = $this->get_categories(array($taskData['info_cat']));
|
|
||||||
$vevent->setAttribute('CATEGORIES', $cats[0]);
|
|
||||||
}
|
|
||||||
//error_log("\n\nexportvcal\n". print_r($vcal,true));
|
|
||||||
//error_log("\n\nexportvcal\n". print_r($vevent,true));
|
|
||||||
$vcal->addComponent($vevent);
|
$vcal->addComponent($vevent);
|
||||||
error_log("\n\nexportvcal from infolog\n");
|
|
||||||
return $vcal->exportvCalendar();
|
$retval = $vcal->exportvCalendar();
|
||||||
|
Horde::logMessage("exportVTODO:\n" . print_r($retval, true), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
return $retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,104 +227,143 @@ class infolog_ical extends infolog_bo
|
|||||||
*
|
*
|
||||||
* @param string $_vcalData
|
* @param string $_vcalData
|
||||||
* @param int $_taskID=-1 info_id, default -1 = new entry
|
* @param int $_taskID=-1 info_id, default -1 = new entry
|
||||||
|
* @param boolean $merge=false merge data with existing entry
|
||||||
* @return int|boolean integer info_id or false on error
|
* @return int|boolean integer info_id or false on error
|
||||||
*/
|
*/
|
||||||
function importVTODO(&$_vcalData, $_taskID=-1)
|
function importVTODO(&$_vcalData, $_taskID=-1, $merge=false)
|
||||||
{
|
{
|
||||||
if(!$taskData = $this->vtodotoegw($_vcalData,$_taskID))
|
if (!$taskData = $this->vtodotoegw($_vcalData,$_taskID)) return false;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// we suppose that a not set status in a vtodo means that the task did not started yet
|
// we suppose that a not set status in a vtodo means that the task did not started yet
|
||||||
if (empty($taskData['info_status']))
|
if (empty($taskData['info_status']))
|
||||||
{
|
{
|
||||||
$taskData['info_status'] = 'not-started';
|
$taskData['info_status'] = 'not-started';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (empty($taskData['info_datecompleted']))
|
||||||
|
{
|
||||||
|
$taskData['info_datecompleted'] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->write($taskData);
|
return $this->write($taskData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function searchVTODO($_vcalData, $contentID=null)
|
/**
|
||||||
{
|
* Search a matching infolog entry for the VTODO data
|
||||||
if(!$egwData = $this->vtodotoegw($_vcalData)) {
|
*
|
||||||
return false;
|
* @param string $_vcalData VTODO
|
||||||
}
|
* @param int $contentID=null infolog_id (or null, if unkown)
|
||||||
|
* @param boolean $relax=false if true, a weaker match algorithm is used
|
||||||
|
* @return infolog_id of a matching entry or false, if nothing was found
|
||||||
|
*/
|
||||||
|
function searchVTODO($_vcalData, $contentID=null, $relax=false) {
|
||||||
|
$result = false;
|
||||||
|
|
||||||
$myfilter = array('col_filter' => array('info_uid'=>$egwData['info_uid'])) ;
|
if (($egwData = $this->vtodotoegw($_vcalData)))
|
||||||
if ($egwData['info_uid'] && ($found=parent::search($myfilter)) && ($uidmatch = array_shift($found)))
|
{
|
||||||
|
if ($contentID)
|
||||||
{
|
{
|
||||||
return $uidmatch['info_id'];
|
|
||||||
};
|
|
||||||
unset($egwData['info_uid']);
|
|
||||||
|
|
||||||
if ($contentID) {
|
|
||||||
$egwData['info_id'] = $contentID;
|
$egwData['info_id'] = $contentID;
|
||||||
}
|
}
|
||||||
|
$result = $this->findVTODO($egwData, $relax);
|
||||||
#unset($egwData['info_priority']);
|
|
||||||
|
|
||||||
$filter = array('col_filter' => $egwData);
|
|
||||||
if($foundItems = $this->search($filter)) {
|
|
||||||
if(count($foundItems) > 0) {
|
|
||||||
$itemIDs = array_keys($foundItems);
|
|
||||||
return $itemIDs[0];
|
|
||||||
}
|
}
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
/**
|
||||||
}
|
* Convert VTODO into a eGW infolog entry
|
||||||
|
*
|
||||||
|
* @param string $_vcalData VTODO data
|
||||||
|
* @param int $_taskID=-1 infolog_id of the entry
|
||||||
|
* @return array infolog entry or false on error
|
||||||
|
*/
|
||||||
function vtodotoegw($_vcalData, $_taskID=-1)
|
function vtodotoegw($_vcalData, $_taskID=-1)
|
||||||
{
|
{
|
||||||
$vcal = new Horde_iCalendar;
|
$vcal = new Horde_iCalendar;
|
||||||
if(!$vcal->parsevCalendar($_vcalData))
|
if (!($vcal->parsevCalendar($_vcalData))) return false;
|
||||||
|
|
||||||
|
if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length']))
|
||||||
{
|
{
|
||||||
return FALSE;
|
$minimum_uid_length = $GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$minimum_uid_length = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
$components = $vcal->getComponents();
|
$components = $vcal->getComponents();
|
||||||
|
|
||||||
if(count($components) > 0)
|
foreach ($components as $component)
|
||||||
{
|
{
|
||||||
$component = $components[0];
|
|
||||||
if (is_a($component, 'Horde_iCalendar_vtodo'))
|
if (is_a($component, 'Horde_iCalendar_vtodo'))
|
||||||
{
|
{
|
||||||
$taskData = array();
|
$taskData = array();
|
||||||
|
$taskData['info_type'] = 'task';
|
||||||
|
|
||||||
if ($_taskID > 0)
|
if ($_taskID > 0)
|
||||||
{
|
{
|
||||||
$taskData['info_id'] = $_taskID;
|
$taskData['info_id'] = $_taskID;
|
||||||
}
|
}
|
||||||
foreach ($component->_attributes as $attributes)
|
foreach ($component->_attributes as $attributes)
|
||||||
{
|
{
|
||||||
|
//$attributes['value'] = trim($attributes['value']);
|
||||||
|
if (empty($attributes['value'])) continue;
|
||||||
switch ($attributes['name'])
|
switch ($attributes['name'])
|
||||||
{
|
{
|
||||||
case 'CLASS':
|
case 'CLASS':
|
||||||
$taskData['info_access'] = strtolower($attributes['value']);
|
$taskData['info_access'] = strtolower($attributes['value']);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'DESCRIPTION':
|
case 'DESCRIPTION':
|
||||||
$taskData['info_des'] = $attributes['value'];
|
$value = $attributes['value'];
|
||||||
|
if (preg_match('/\s*\[UID:(.+)?\]/Usm', $value, $matches))
|
||||||
|
{
|
||||||
|
if (!isset($taskData['info_uid'])
|
||||||
|
&& strlen($matches[1]) >= $minimum_uid_length)
|
||||||
|
{
|
||||||
|
$taskData['info_uid'] = $matches[1];
|
||||||
|
}
|
||||||
|
//$value = str_replace($matches[0], '', $value);
|
||||||
|
}
|
||||||
|
if (preg_match('/\s*\[PARENT_UID:(.+)?\]/Usm', $value, $matches))
|
||||||
|
{
|
||||||
|
if (!isset($taskData['info_id_parent'])
|
||||||
|
&& strlen($matches[1]) >= $minimum_uid_length)
|
||||||
|
{
|
||||||
|
$taskData['info_id_parent'] = $this->getParentID($matches[1]);
|
||||||
|
}
|
||||||
|
//$value = str_replace($matches[0], '', $value);
|
||||||
|
}
|
||||||
|
$taskData['info_des'] = $value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'LOCATION':
|
case 'LOCATION':
|
||||||
$taskData['info_location'] = $attributes['value'];
|
$taskData['info_location'] = $attributes['value'];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'DUE':
|
case 'DUE':
|
||||||
$taskData['info_enddate'] = $attributes['value'];
|
// eGroupWare uses date only
|
||||||
|
$parts = @getdate($attributes['value']);
|
||||||
|
$value = @mktime(0, 0, 0, $parts['mon'], $parts['mday'], $parts['year']);
|
||||||
|
$taskData['info_enddate'] = $value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'COMPLETED':
|
case 'COMPLETED':
|
||||||
$taskData['info_datecompleted'] = $attributes['value'];
|
$taskData['info_datecompleted'] = $attributes['value'];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'DTSTART':
|
case 'DTSTART':
|
||||||
$taskData['info_startdate'] = $attributes['value'];
|
$taskData['info_startdate'] = $attributes['value'];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'PRIORITY':
|
case 'PRIORITY':
|
||||||
if (1 <= $attributes['value'] && $attributes['value'] <= 3)
|
if (1 <= $attributes['value'] && $attributes['value'] <= 3) {
|
||||||
{
|
|
||||||
$taskData['info_priority'] = $this->vcal_priority2egw_priority[$attributes['value']];
|
$taskData['info_priority'] = $this->vcal_priority2egw_priority[$attributes['value']];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$taskData['info_priority'] = 1; // default = normal
|
$taskData['info_priority'] = 1; // default = normal
|
||||||
}
|
}
|
||||||
break;
|
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)
|
||||||
foreach($component->_attributes as $attr)
|
foreach($component->_attributes as $attr)
|
||||||
@ -223,28 +373,26 @@ class infolog_ical extends infolog_bo
|
|||||||
$taskData['info_status'] = $this->vtodo2status($attributes['value'],
|
$taskData['info_status'] = $this->vtodo2status($attributes['value'],
|
||||||
$attr['name'] == 'X-INFOLOG-STATUS' ? $attr['value'] : null);
|
$attr['name'] == 'X-INFOLOG-STATUS' ? $attr['value'] : null);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'SUMMARY':
|
case 'SUMMARY':
|
||||||
$taskData['info_subject'] = $attributes['value'];
|
$taskData['info_subject'] = $attributes['value'];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'RELATED-TO':
|
||||||
|
$taskData['info_id_parent'] = $this->getParentID($attributes['value']);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'CATEGORIES':
|
case 'CATEGORIES':
|
||||||
$cats = $this->find_or_add_categories(explode(',', $attributes['value']));
|
$cats = $this->find_or_add_categories(explode(',', $attributes['value']));
|
||||||
$taskData['info_cat'] = $cats[0];
|
$taskData['info_cat'] = $cats[0];
|
||||||
break;
|
break;
|
||||||
case 'UID':
|
|
||||||
$taskData['info_uid'] = $attributes['value'];
|
|
||||||
if ($_taskID <= 0 && !empty($attributes['value']) && ($uid_task = $this->read($attributes['value'])))
|
|
||||||
{
|
|
||||||
$taskData['info_id'] = $uid_task['id'];
|
|
||||||
unset($uid_task);
|
|
||||||
}
|
|
||||||
// not use weak uids that might come from syncml clients
|
|
||||||
if (isset($event['uid']) && (strlen($event['uid']) < 20 || is_numeric($event['uid'])))
|
|
||||||
{
|
|
||||||
unset ($event['uid']);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
case 'UID':
|
||||||
|
if (strlen($attributes['value']) >= $minimum_uid_length) {
|
||||||
|
$taskData['info_uid'] = $attributes['value'];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'PERCENT-COMPLETE':
|
case 'PERCENT-COMPLETE':
|
||||||
$taskData['info_percent'] = (int) $attributes['value'];
|
$taskData['info_percent'] = (int) $attributes['value'];
|
||||||
break;
|
break;
|
||||||
@ -254,16 +402,26 @@ class infolog_ical extends infolog_bo
|
|||||||
# do NOT convert here
|
# do NOT convert here
|
||||||
#$taskData = $GLOBALS['egw']->translation->convert($taskData, 'UTF-8');
|
#$taskData = $GLOBALS['egw']->translation->convert($taskData, 'UTF-8');
|
||||||
|
|
||||||
|
Horde::logMessage("vtodotoegw:\n" . print_r($taskData, true), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
return $taskData;
|
return $taskData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export an infolog entry as VNOTE
|
||||||
|
*
|
||||||
|
* @param int $_noteID the infolog_id of the entry
|
||||||
|
* @param string $_type content type (e.g. text/plain)
|
||||||
|
* @return string VNOTE representation of the infolog entry
|
||||||
|
*/
|
||||||
function exportVNOTE($_noteID, $_type)
|
function exportVNOTE($_noteID, $_type)
|
||||||
{
|
{
|
||||||
$note = $this->read($_noteID);
|
$note = $this->read($_noteID);
|
||||||
$note = $GLOBALS['egw']->translation->convert($note, $GLOBALS['egw']->translation->charset(), 'UTF-8');
|
$note = $GLOBALS['egw']->translation->convert($note,
|
||||||
|
$GLOBALS['egw']->translation->charset(), 'UTF-8');
|
||||||
|
|
||||||
switch ($_type)
|
switch ($_type)
|
||||||
{
|
{
|
||||||
@ -273,66 +431,101 @@ class infolog_ical extends infolog_bo
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'text/x-vnote':
|
case 'text/x-vnote':
|
||||||
$noteGUID = $GLOBALS['egw']->common->generate_uid('infolog_note',$_noteID);
|
|
||||||
$vnote = new Horde_iCalendar_vnote();
|
$vnote = new Horde_iCalendar_vnote();
|
||||||
|
$options = array('CHARSET' => 'UTF-8');
|
||||||
$vNote->setAttribute('VERSION', '1.1');
|
$vNote->setAttribute('VERSION', '1.1');
|
||||||
$vnote->setAttribute('SUMMARY',$note['info_subject']);
|
foreach (array( 'SUMMARY' => $note['info_subject'],
|
||||||
$vnote->setAttribute('BODY',$note['info_des']);
|
'BODY' => $note['info_des'],
|
||||||
|
) as $field => $value)
|
||||||
|
{
|
||||||
|
$vnote->setAttribute($field, $value);
|
||||||
|
if ($this->productManufacturer != 'groupdav'
|
||||||
|
&& preg_match('/([\177-\377])/', $value))
|
||||||
|
{
|
||||||
|
$vevent->setParameter($field, $options);
|
||||||
|
}
|
||||||
|
}
|
||||||
if ($note['info_startdate'])
|
if ($note['info_startdate'])
|
||||||
|
{
|
||||||
$vnote->setAttribute('DCREATED',$note['info_startdate']);
|
$vnote->setAttribute('DCREATED',$note['info_startdate']);
|
||||||
|
}
|
||||||
$vnote->setAttribute('DCREATED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'add'));
|
$vnote->setAttribute('DCREATED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'add'));
|
||||||
$vnote->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'modify'));
|
$vnote->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'modify'));
|
||||||
|
|
||||||
if (!empty($note['info_cat']))
|
if (!empty($note['info_cat']))
|
||||||
{
|
{
|
||||||
$cats = $this->get_categories(array($note['info_cat']));
|
$cats = $this->get_categories(array($note['info_cat']));
|
||||||
$vnote->setAttribute('CATEGORIES', $cats[0]);
|
$value = $cats[0];
|
||||||
|
$vnote->setAttribute('CATEGORIES', $value);
|
||||||
|
if ($this->productManufacturer != 'groupdav'
|
||||||
|
&& preg_match('/([\177-\377])/', $value))
|
||||||
|
{
|
||||||
|
$vevent->setParameter('CATEGORIES', $options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#$vnote->setAttribute('UID',$noteGUID);
|
|
||||||
#$vnote->setAttribute('CLASS',$taskData['info_access'] == 'public' ? 'PUBLIC' : 'PRIVATE');
|
#$vnote->setAttribute('CLASS',$taskData['info_access'] == 'public' ? 'PUBLIC' : 'PRIVATE');
|
||||||
|
|
||||||
#$options = array('CHARSET' => 'UTF-8','ENCODING' => 'QUOTED-PRINTABLE');
|
|
||||||
#$vnote->setParameter('SUMMARY', $options);
|
|
||||||
#$vnote->setParameter('DESCRIPTION', $options);
|
|
||||||
|
|
||||||
return $vnote->exportvCalendar();
|
return $vnote->exportvCalendar();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function importVNOTE(&$_vcalData, $_type, $_noteID = -1)
|
/**
|
||||||
|
* Import a VNOTE component of an iCal
|
||||||
|
*
|
||||||
|
* @param string $_vcalData
|
||||||
|
* @param string $_type content type (eg.g text/plain)
|
||||||
|
* @param int $_taskID=-1 info_id, default -1 = new entry
|
||||||
|
* @param boolean $merge=false merge data with existing entry
|
||||||
|
* @return int|boolean integer info_id or false on error
|
||||||
|
*/
|
||||||
|
function importVNOTE(&$_vcalData, $_type, $_noteID = -1, $merge=false)
|
||||||
{
|
{
|
||||||
if(!$note = $this->vnotetoegw($_vcalData, $_type))
|
if (!($note = $this->vnotetoegw($_vcalData, $_type))) return false;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if($_noteID > 0)
|
if($_noteID > 0) $note['info_id'] = $_noteID;
|
||||||
{
|
|
||||||
$note['info_id'] = $_noteID;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(empty($note['info_status'])) {
|
if (empty($note['info_status'])) $note['info_status'] = 'done';
|
||||||
$note['info_status'] = 'done';
|
|
||||||
}
|
|
||||||
|
|
||||||
#_debug_array($taskData);exit;
|
#_debug_array($taskData);exit;
|
||||||
return $this->write($note);
|
return $this->write($note);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search a matching infolog entry for the VNOTE data
|
||||||
|
*
|
||||||
|
* @param string $_vcalData VNOTE
|
||||||
|
* @param int $contentID=null infolog_id (or null, if unkown)
|
||||||
|
* @return infolog_id of a matching entry or false, if nothing was found
|
||||||
|
*/
|
||||||
function searchVNOTE($_vcalData, $_type, $contentID=null)
|
function searchVNOTE($_vcalData, $_type, $contentID=null)
|
||||||
{
|
{
|
||||||
if(!$note = $this->vnotetoegw($_vcalData,$_type)) {
|
if (!($note = $this->vnotetoegw($_vcalData,$_type))) return false;
|
||||||
return false;
|
|
||||||
|
if ($contentID) $note['info_id'] = $contentID;
|
||||||
|
|
||||||
|
unset($note['info_startdate']);
|
||||||
|
|
||||||
|
$filter = array();
|
||||||
|
|
||||||
|
if (!empty($note['info_des']))
|
||||||
|
{
|
||||||
|
$description = trim(preg_replace("/\r?\n?\\[[A-Z_]+:.*\\]/i", '', $note['info_des']));
|
||||||
|
unset($note['info_des']);
|
||||||
|
if (strlen($description))
|
||||||
|
{
|
||||||
|
$filter['search'] = $description;
|
||||||
}
|
}
|
||||||
if ($contentID) {
|
|
||||||
$note['info_id'] = $contentID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$filter = array('col_filter' => $note);
|
$filter['col_filter'] = $note;
|
||||||
if($foundItems = $this->search($filter)) {
|
|
||||||
if(count($foundItems) > 0) {
|
if (($foundItems = $this->search($filter)))
|
||||||
|
{
|
||||||
|
if (count($foundItems) > 0)
|
||||||
|
{
|
||||||
$itemIDs = array_keys($foundItems);
|
$itemIDs = array_keys($foundItems);
|
||||||
return $itemIDs[0];
|
return $itemIDs[0];
|
||||||
}
|
}
|
||||||
@ -341,6 +534,13 @@ class infolog_ical extends infolog_bo
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert VTODO into a eGW infolog entry
|
||||||
|
*
|
||||||
|
* @param string $_data VNOTE data
|
||||||
|
* @param string $_type content type (eg.g text/plain)
|
||||||
|
* @return array infolog entry or false on error
|
||||||
|
*/
|
||||||
function vnotetoegw($_data, $_type)
|
function vnotetoegw($_data, $_type)
|
||||||
{
|
{
|
||||||
switch ($_type)
|
switch ($_type)
|
||||||
@ -360,7 +560,7 @@ class infolog_ical extends infolog_bo
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// should better be imported as subject, but causes duplicates
|
// should better be imported as subject, but causes duplicates
|
||||||
// TODO: should be qexamined
|
// TODO: should be examined
|
||||||
$note['info_des'] = $txt;
|
$note['info_des'] = $txt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,14 +569,11 @@ class infolog_ical extends infolog_bo
|
|||||||
|
|
||||||
case 'text/x-vnote':
|
case 'text/x-vnote':
|
||||||
$vnote = new Horde_iCalendar;
|
$vnote = new Horde_iCalendar;
|
||||||
if (!$vcal->parsevCalendar($_data))
|
if (!$vcal->parsevCalendar($_data)) return false;
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
$components = $vnote->getComponent();
|
$components = $vnote->getComponent();
|
||||||
if(count($components) > 0)
|
foreach ($components as $component)
|
||||||
{
|
{
|
||||||
$component = $components[0];
|
|
||||||
if (is_a($component, 'Horde_iCalendar_vnote'))
|
if (is_a($component, 'Horde_iCalendar_vnote'))
|
||||||
{
|
{
|
||||||
$note = array();
|
$note = array();
|
||||||
@ -389,14 +586,14 @@ class infolog_ical extends infolog_bo
|
|||||||
case 'BODY':
|
case 'BODY':
|
||||||
$note['info_des'] = $attribute['value'];
|
$note['info_des'] = $attribute['value'];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'SUMMARY':
|
case 'SUMMARY':
|
||||||
$note['info_subject'] = $attribute['value'];
|
$note['info_subject'] = $attribute['value'];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'CATEGORIES':
|
case 'CATEGORIES':
|
||||||
{
|
|
||||||
$cats = $this->find_or_add_categories(explode(',', $attribute['value']));
|
$cats = $this->find_or_add_categories(explode(',', $attribute['value']));
|
||||||
$note['info_cat'] = $cats[0];
|
$note['info_cat'] = $cats[0];
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,7 +601,7 @@ class infolog_ical extends infolog_bo
|
|||||||
return $note;
|
return $note;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -415,11 +612,41 @@ class infolog_ical extends infolog_bo
|
|||||||
* @param string $_productManufacturer
|
* @param string $_productManufacturer
|
||||||
* @param string $_productName
|
* @param string $_productName
|
||||||
*/
|
*/
|
||||||
function setSupportedFields($_productManufacturer='file', $_productName='')
|
function setSupportedFields($_productManufacturer='', $_productName='')
|
||||||
{
|
{
|
||||||
// save them vor later use
|
$state = &$_SESSION['SyncML.state'];
|
||||||
$this->productManufacturer = $_productManufacturer;
|
if (isset($state))
|
||||||
$this->productName = $_productName;
|
{
|
||||||
|
$deviceInfo = $state->getClientDeviceInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
// store product manufacturer and name, to be able to use it elsewhere
|
||||||
|
if ($_productManufacturer)
|
||||||
|
{
|
||||||
|
$this->productManufacturer = strtolower($_productManufacturer);
|
||||||
|
$this->productName = strtolower($_productName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($deviceInfo) && is_array($deviceInfo))
|
||||||
|
{
|
||||||
|
if (!isset($this->productManufacturer)
|
||||||
|
|| $this->productManufacturer == ''
|
||||||
|
|| $this->productManufacturer == 'file')
|
||||||
|
{
|
||||||
|
$this->productManufacturer = strtolower($deviceInfo['manufacturer']);
|
||||||
|
}
|
||||||
|
if (!isset($this->productName) || $this->productName == '')
|
||||||
|
{
|
||||||
|
$this->productName = strtolower($deviceInfo['model']);
|
||||||
|
}
|
||||||
|
if (isset($deviceInfo['uidExtension'])
|
||||||
|
&& $deviceInfo['uidExtension'])
|
||||||
|
{
|
||||||
|
$this->uidExtension = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Horde::logMessage('setSupportedFields(' . $this->productManufacturer . ', ' . $this->productName .')', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,13 +4,14 @@
|
|||||||
*
|
*
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Lars Kneschke <lkneschke@egroupware.org>
|
* @author Lars Kneschke <lkneschke@egroupware.org>
|
||||||
|
* @author Joerg Lehrke <jlehrke@noc.de>
|
||||||
* @package infolog
|
* @package infolog
|
||||||
* @subpackage syncml
|
* @subpackage syncml
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once EGW_API_INC.'/horde/Horde/iCalendar.php';
|
require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* InfoLog: Create and parse SIF
|
* InfoLog: Create and parse SIF
|
||||||
@ -43,7 +44,7 @@ class infolog_sif extends infolog_bo
|
|||||||
'Body' => 'info_des',
|
'Body' => 'info_des',
|
||||||
'Categories' => 'info_cat',
|
'Categories' => 'info_cat',
|
||||||
'Companies' => '',
|
'Companies' => '',
|
||||||
'Complete' => '',
|
'Complete' => 'complete',
|
||||||
'DateCompleted' => 'info_datecompleted',
|
'DateCompleted' => 'info_datecompleted',
|
||||||
'DueDate' => 'info_enddate',
|
'DueDate' => 'info_enddate',
|
||||||
'Importance' => 'info_priority',
|
'Importance' => 'info_priority',
|
||||||
@ -70,26 +71,56 @@ class infolog_sif extends infolog_bo
|
|||||||
'Occurrences' => '',
|
'Occurrences' => '',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// standard headers
|
||||||
|
const xml_decl = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||||
|
const SIF_decl = '<SIFVersion>1.1</SIFVersion>';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* name and version of the sync-client
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $productName = 'mozilla plugin';
|
||||||
|
var $productSoftwareVersion = '0.3';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shall we use the UID extensions of the description field?
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
var $uidExtension = false;
|
||||||
|
|
||||||
|
|
||||||
function startElement($_parser, $_tag, $_attributes) {
|
function startElement($_parser, $_tag, $_attributes)
|
||||||
|
{
|
||||||
|
// nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
function endElement($_parser, $_tag) {
|
function endElement($_parser, $_tag)
|
||||||
error_log("infolog: tag=$_tag data=".trim($this->sifData));
|
{
|
||||||
if(!empty($this->_currentSIFMapping[$_tag])) {
|
#error_log("infolog: tag=$_tag data=".trim($this->sifData));
|
||||||
|
if (!empty($this->_currentSIFMapping[$_tag]))
|
||||||
|
{
|
||||||
$this->_extractedSIFData[$this->_currentSIFMapping[$_tag]] = trim($this->sifData);
|
$this->_extractedSIFData[$this->_currentSIFMapping[$_tag]] = trim($this->sifData);
|
||||||
}
|
}
|
||||||
unset($this->sifData);
|
unset($this->sifData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function characterData($_parser, $_data) {
|
function characterData($_parser, $_data)
|
||||||
|
{
|
||||||
$this->sifData .= $_data;
|
$this->sifData .= $_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
function siftoegw($_sifData, $_sifType) {
|
/**
|
||||||
|
* Convert SIF data into a eGW infolog entry
|
||||||
|
*
|
||||||
|
* @param string $sifData the SIF data
|
||||||
|
* @param string $_sifType type (note/task)
|
||||||
|
* @return array infolog entry or false on error
|
||||||
|
*/
|
||||||
|
function siftoegw($sifData, $_sifType)
|
||||||
|
{
|
||||||
$sysCharSet = $GLOBALS['egw']->translation->charset();
|
$sysCharSet = $GLOBALS['egw']->translation->charset();
|
||||||
$sifData = base64_decode($_sifData);
|
|
||||||
|
|
||||||
#$tmpfname = tempnam('/tmp/sync/contents','sift_');
|
#$tmpfname = tempnam('/tmp/sync/contents','sift_');
|
||||||
|
|
||||||
@ -115,29 +146,44 @@ class infolog_sif extends infolog_bo
|
|||||||
xml_set_element_handler($this->xml_parser, "startElement", "endElement");
|
xml_set_element_handler($this->xml_parser, "startElement", "endElement");
|
||||||
xml_set_character_data_handler($this->xml_parser, "characterData");
|
xml_set_character_data_handler($this->xml_parser, "characterData");
|
||||||
$this->strXmlData = xml_parse($this->xml_parser, $sifData);
|
$this->strXmlData = xml_parse($this->xml_parser, $sifData);
|
||||||
if(!$this->strXmlData) {
|
|
||||||
|
if (!$this->strXmlData)
|
||||||
|
{
|
||||||
error_log(sprintf("XML error: %s at line %d",
|
error_log(sprintf("XML error: %s at line %d",
|
||||||
xml_error_string(xml_get_error_code($this->xml_parser)),
|
xml_error_string(xml_get_error_code($this->xml_parser)),
|
||||||
xml_get_current_line_number($this->xml_parser)));
|
xml_get_current_line_number($this->xml_parser)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!array($this->_extractedSIFData)) {
|
if (!array($this->_extractedSIFData)) return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch($_sifType) {
|
switch ($_sifType)
|
||||||
|
{
|
||||||
case 'task':
|
case 'task':
|
||||||
$taskData = array();
|
$taskData = array();
|
||||||
$vcal = new Horde_iCalendar;
|
$vcal = new Horde_iCalendar;
|
||||||
|
|
||||||
$taskData['info_type'] = 'task';
|
$taskData['info_type'] = 'task';
|
||||||
|
$taskData['info_status'] = 'not-started';
|
||||||
|
|
||||||
foreach($this->_extractedSIFData as $key => $value) {
|
if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length']))
|
||||||
|
{
|
||||||
|
$minimum_uid_length = $GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$minimum_uid_length = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->_extractedSIFData as $key => $value)
|
||||||
|
{
|
||||||
|
$value = preg_replace('/<\!\[CDATA\[(.+)\]\]>/Usim', '$1', $value);
|
||||||
$value = $GLOBALS['egw']->translation->convert($value, 'utf-8', $sysCharSet);
|
$value = $GLOBALS['egw']->translation->convert($value, 'utf-8', $sysCharSet);
|
||||||
error_log("infolog key=$key => value=$value");
|
#error_log("infolog key=$key => value=$value");
|
||||||
|
if (empty($value)) continue;
|
||||||
|
|
||||||
switch($key) {
|
switch($key)
|
||||||
|
{
|
||||||
case 'info_access':
|
case 'info_access':
|
||||||
$taskData[$key] = ((int)$value > 0) ? 'private' : 'public';
|
$taskData[$key] = ((int)$value > 0) ? 'private' : 'public';
|
||||||
break;
|
break;
|
||||||
@ -145,19 +191,18 @@ class infolog_sif extends infolog_bo
|
|||||||
case 'info_datecompleted':
|
case 'info_datecompleted':
|
||||||
case 'info_enddate':
|
case 'info_enddate':
|
||||||
case 'info_startdate':
|
case 'info_startdate':
|
||||||
if(!empty($value)) {
|
if (!empty($value))
|
||||||
|
{
|
||||||
$taskData[$key] = $vcal->_parseDateTime($value);
|
$taskData[$key] = $vcal->_parseDateTime($value);
|
||||||
// somehow the client always deliver a timestamp about 3538 seconds, when no startdate set.
|
// somehow the client always deliver a timestamp about 3538 seconds, when no startdate set.
|
||||||
if($taskData[$key] < 10000)
|
if ($taskData[$key] < 10000) unset($taskData[$key]);
|
||||||
$taskData[$key] = '';
|
|
||||||
} else {
|
|
||||||
$taskData[$key] = '';
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case 'info_cat':
|
case 'info_cat':
|
||||||
if (!empty($value)) {
|
if (!empty($value))
|
||||||
|
{
|
||||||
$categories = $this->find_or_add_categories(explode(';', $value));
|
$categories = $this->find_or_add_categories(explode(';', $value));
|
||||||
$taskData['info_cat'] = $categories[0];
|
$taskData['info_cat'] = $categories[0];
|
||||||
}
|
}
|
||||||
@ -168,8 +213,8 @@ class infolog_sif extends infolog_bo
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'info_status':
|
case 'info_status':
|
||||||
$taskData[$key] = ((int)$value == 2) ? 'done' : 'ongoing';
|
switch ($value)
|
||||||
switch($value) {
|
{
|
||||||
case '0':
|
case '0':
|
||||||
$taskData[$key] = 'not-started';
|
$taskData[$key] = 'not-started';
|
||||||
break;
|
break;
|
||||||
@ -178,9 +223,20 @@ class infolog_sif extends infolog_bo
|
|||||||
break;
|
break;
|
||||||
case '2':
|
case '2':
|
||||||
$taskData[$key] = 'done';
|
$taskData[$key] = 'done';
|
||||||
|
$taskData['info_percent'] = 100;
|
||||||
|
break;
|
||||||
|
case '3':
|
||||||
|
$taskData[$key] = 'waiting';
|
||||||
break;
|
break;
|
||||||
case '4':
|
case '4':
|
||||||
|
if ($this->productName == 'blackberry plug-in')
|
||||||
|
{
|
||||||
|
$taskData[$key] = 'deferred';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$taskData[$key] = 'cancelled';
|
$taskData[$key] = 'cancelled';
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$taskData[$key] = 'ongoing';
|
$taskData[$key] = 'ongoing';
|
||||||
@ -188,11 +244,35 @@ class infolog_sif extends infolog_bo
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'complete':
|
||||||
|
$taskData['info_status'] = 'done';
|
||||||
|
$taskData['info_percent'] = 100;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'info_des':
|
||||||
|
// extract our UID and PARENT_UID information
|
||||||
|
if (preg_match('/\s*\[UID:(.+)?\]/Usm', $value, $matches))
|
||||||
|
{
|
||||||
|
if (strlen($matches[1]) >= $minimum_uid_length)
|
||||||
|
{
|
||||||
|
$taskData['info_uid'] = $matches[1];
|
||||||
|
}
|
||||||
|
//$value = str_replace($matches[0], '', $value);
|
||||||
|
}
|
||||||
|
if (preg_match('/\s*\[PARENT_UID:(.+)?\]/Usm', $value, $matches))
|
||||||
|
{
|
||||||
|
if (strlen($matches[1]) >= $minimum_uid_length)
|
||||||
|
{
|
||||||
|
$taskData['info_id_parent'] = $this->getParentID($matches[1]);
|
||||||
|
}
|
||||||
|
//$value = str_replace($matches[0], '', $value);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$taskData[$key] = $value;
|
$taskData[$key] = $value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
error_log("infolog task key=$key => value=".$taskData[$key]);
|
#error_log("infolog task key=$key => value=" . $taskData[$key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $taskData;
|
return $taskData;
|
||||||
@ -205,26 +285,30 @@ class infolog_sif extends infolog_bo
|
|||||||
|
|
||||||
foreach ($this->_extractedSIFData as $key => $value)
|
foreach ($this->_extractedSIFData as $key => $value)
|
||||||
{
|
{
|
||||||
|
$value = preg_replace('/<\!\[CDATA\[(.+)\]\]>/Usim', '$1', $value);
|
||||||
$value = $GLOBALS['egw']->translation->convert($value, 'utf-8', $sysCharSet);
|
$value = $GLOBALS['egw']->translation->convert($value, 'utf-8', $sysCharSet);
|
||||||
|
|
||||||
error_log("infolog client key=$key => value=".$value);
|
#error_log("infolog client key=$key => value=" . $value);
|
||||||
switch ($key)
|
switch ($key)
|
||||||
{
|
{
|
||||||
case 'info_startdate':
|
case 'info_startdate':
|
||||||
if(!empty($value)) {
|
if (!empty($value))
|
||||||
|
{
|
||||||
$noteData[$key] = $vcal->_parseDateTime($value);
|
$noteData[$key] = $vcal->_parseDateTime($value);
|
||||||
// somehow the client always deliver a timestamp about 3538 seconds, when no startdate set.
|
// somehow the client always deliver a timestamp about 3538 seconds, when no startdate set.
|
||||||
if($noteData[$key] < 10000)
|
if ($noteData[$key] < 10000) $noteData[$key] = '';
|
||||||
$noteData[$key] = '';
|
}
|
||||||
} else {
|
else
|
||||||
|
{
|
||||||
$noteData[$key] = '';
|
$noteData[$key] = '';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'info_cat':
|
case 'info_cat':
|
||||||
if (!empty($value)) {
|
if (!empty($value))
|
||||||
|
{
|
||||||
$categories = $this->find_or_add_categories(explode(';', $value));
|
$categories = $this->find_or_add_categories(explode(';', $value));
|
||||||
$taskData['info_cat'] = $categories[0];
|
$noteData['info_cat'] = $categories[0];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -232,7 +316,7 @@ class infolog_sif extends infolog_bo
|
|||||||
$noteData[$key] = $value;
|
$noteData[$key] = $value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
error_log("infolog note key=$key => value=".$noteData[$key]);
|
#error_log("infolog note key=$key => value=".$noteData[$key]);
|
||||||
}
|
}
|
||||||
return $noteData;
|
return $noteData;
|
||||||
break;
|
break;
|
||||||
@ -243,17 +327,33 @@ class infolog_sif extends infolog_bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function searchSIF($_sifData, $_sifType, $contentID=null) {
|
/**
|
||||||
if(!$egwData = $this->siftoegw($_sifData, $_sifType)) {
|
* Search for SIF data a matching infolog entry
|
||||||
return false;
|
*
|
||||||
}
|
* @param string $sifData the SIF data
|
||||||
if ($contentID) {
|
* @param string $_sifType type (note/task)
|
||||||
$egwData['info_id'] = $contentID;
|
* @param int $contentID=null infolog_id (or null, if unkown)
|
||||||
}
|
* @param boolean $relax=false if true, a weaker match algorithm is used
|
||||||
|
* @return infolog_id of a matching entry or false, if nothing was found
|
||||||
|
*/
|
||||||
|
function searchSIF($_sifData, $_sifType, $contentID=null, $relax=false)
|
||||||
|
{
|
||||||
|
if (!($egwData = $this->siftoegw($_sifData, $_sifType))) return false;
|
||||||
|
|
||||||
$filter = array('col_filter' => $egwData);
|
if ($contentID) $egwData['info_id'] = $contentID;
|
||||||
if($foundItems = $this->search($filter)) {
|
|
||||||
if(count($foundItems) > 0) {
|
if ($_sifType == 'task') return $this->findVTODO($egwData, $relax);
|
||||||
|
|
||||||
|
if ($_sifType == 'note') unset($egwData['info_startdate']);
|
||||||
|
|
||||||
|
$filter = array();
|
||||||
|
|
||||||
|
$filter['col_filter'] = $egwData;
|
||||||
|
|
||||||
|
if ($foundItems = $this->search($filter))
|
||||||
|
{
|
||||||
|
if (count($foundItems) > 0)
|
||||||
|
{
|
||||||
$itemIDs = array_keys($foundItems);
|
$itemIDs = array_keys($foundItems);
|
||||||
return $itemIDs[0];
|
return $itemIDs[0];
|
||||||
}
|
}
|
||||||
@ -262,27 +362,69 @@ class infolog_sif extends infolog_bo
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSIF($_sifData, $_id, $_sifType) {
|
/**
|
||||||
if(!$egwData = $this->siftoegw($_sifData, $_sifType)) {
|
* Add SIF data entry
|
||||||
return false;
|
*
|
||||||
}
|
* @param string $sifData the SIF data
|
||||||
|
* @param string $_sifType type (note/task)
|
||||||
|
* @param boolean $merge=false reserved for future use
|
||||||
|
* @return infolog_id of the new entry or false, for errors
|
||||||
|
*/
|
||||||
|
function addSIF($_sifData, $_id, $_sifType, $merge=false)
|
||||||
|
{
|
||||||
|
if (!($egwData = $this->siftoegw($_sifData, $_sifType))) return false;
|
||||||
|
|
||||||
if($_id > 0)
|
if ($_id > 0) $egwData['info_id'] = $_id;
|
||||||
$egwData['info_id'] = $_id;
|
|
||||||
|
if (empty($taskData['info_datecompleted']))
|
||||||
|
{
|
||||||
|
$taskData['info_datecompleted'] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
$egwID = $this->write($egwData, false);
|
$egwID = $this->write($egwData, false);
|
||||||
|
|
||||||
return $egwID;
|
return $egwID;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSIF($_id, $_sifType) {
|
|
||||||
switch($_sifType) {
|
|
||||||
case 'task':
|
|
||||||
if($taskData = $this->read($_id)) {
|
|
||||||
$sysCharSet = $GLOBALS['egw']->translation->charset();
|
|
||||||
$vcal = new Horde_iCalendar;
|
|
||||||
|
|
||||||
$sifTask = '<task>';
|
/**
|
||||||
|
* Export an infolog entry as SIF data
|
||||||
|
*
|
||||||
|
* @param int $_id the infolog_id of the entry
|
||||||
|
* @param string $_sifType type (note/task)
|
||||||
|
* @return string SIF representation of the infolog entry
|
||||||
|
*/
|
||||||
|
function getSIF($_id, $_sifType)
|
||||||
|
{
|
||||||
|
$sysCharSet = $GLOBALS['egw']->translation->charset();
|
||||||
|
|
||||||
|
switch($_sifType)
|
||||||
|
{
|
||||||
|
case 'task':
|
||||||
|
if (($taskData = $this->read($_id)))
|
||||||
|
{
|
||||||
|
$vcal = new Horde_iCalendar('1.0');
|
||||||
|
|
||||||
|
if ($taskData['info_id_parent'])
|
||||||
|
{
|
||||||
|
$parent = $this->read($taskData['info_id_parent']);
|
||||||
|
$taskData['info_id_parent'] = $parent['info_uid'];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$taskData['info_id_parent'] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preg_match('/\[UID:.+\]/m', $taskData['info_des']))
|
||||||
|
{
|
||||||
|
$taskData['info_des'] .= "\r\n[UID:" . $taskData['info_uid'] . "]";
|
||||||
|
if ($taskData['info_id_parent'] != '')
|
||||||
|
{
|
||||||
|
$taskData['info_des'] .= "\r\n[PARENT_UID:" . $taskData['info_id_parent'] . "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$sifTask = self::xml_decl . "\n<task>" . self::SIF_decl;
|
||||||
|
|
||||||
foreach ($this->_sifTaskMapping as $sifField => $egwField)
|
foreach ($this->_sifTaskMapping as $sifField => $egwField)
|
||||||
{
|
{
|
||||||
@ -290,14 +432,45 @@ class infolog_sif extends infolog_bo
|
|||||||
|
|
||||||
$value = $GLOBALS['egw']->translation->convert($taskData[$egwField], $sysCharSet, 'utf-8');
|
$value = $GLOBALS['egw']->translation->convert($taskData[$egwField], $sysCharSet, 'utf-8');
|
||||||
|
|
||||||
switch($sifField) {
|
switch ($sifField)
|
||||||
|
{
|
||||||
|
|
||||||
|
case 'Complete':
|
||||||
|
// is handled with DateCompleted
|
||||||
|
break;
|
||||||
|
|
||||||
case 'DateCompleted':
|
case 'DateCompleted':
|
||||||
case 'DueDate':
|
if ($taskData[info_status] == 'done')
|
||||||
case 'StartDate':
|
{
|
||||||
if(!empty($value)) {
|
$sifTask .= "<Complete>1</Complete>";
|
||||||
$value = $vcal->_exportDateTime($value);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sifTask .= "<DateCompleted></DateCompleted><Complete>0</Complete>";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case 'DueDate':
|
||||||
|
if (!empty($value))
|
||||||
|
{
|
||||||
|
$hdate = new Horde_Date($value);
|
||||||
|
$value = $vcal->_exportDate($hdate, '000000Z');
|
||||||
$sifTask .= "<$sifField>$value</$sifField>";
|
$sifTask .= "<$sifField>$value</$sifField>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sifTask .= "<$sifField></$sifField>";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'StartDate':
|
||||||
|
if (!empty($value))
|
||||||
|
{
|
||||||
|
$value = $vcal->_exportDateTime($value);
|
||||||
|
$sifTask .= "<$sifField>$value</$sifField>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sifTask .= "<$sifField></$sifField>";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Importance':
|
case 'Importance':
|
||||||
@ -311,20 +484,26 @@ class infolog_sif extends infolog_bo
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Status':
|
case 'Status':
|
||||||
switch($value) {
|
switch ($value)
|
||||||
|
{
|
||||||
case 'cancelled':
|
case 'cancelled':
|
||||||
|
case 'deferred':
|
||||||
$value = '4';
|
$value = '4';
|
||||||
break;
|
break;
|
||||||
|
case 'waiting':
|
||||||
|
case 'nonactive':
|
||||||
|
$value = '3';
|
||||||
|
break;
|
||||||
case 'done':
|
case 'done':
|
||||||
|
case 'archive':
|
||||||
|
case 'billed':
|
||||||
$value = '2';
|
$value = '2';
|
||||||
break;
|
break;
|
||||||
case 'not-started':
|
case 'not-started':
|
||||||
|
case 'template':
|
||||||
$value = '0';
|
$value = '0';
|
||||||
break;
|
break;
|
||||||
case 'ongoing':
|
default: //ongoing
|
||||||
$value = '1';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$value = 1;
|
$value = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -332,65 +511,33 @@ class infolog_sif extends infolog_bo
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Categories':
|
case 'Categories':
|
||||||
if (!empty($value))
|
if (!empty($value) && $value)
|
||||||
{
|
{
|
||||||
$value = implode('; ', $this->get_categories(array($value)));
|
$value = implode('; ', $this->get_categories(array($value)));
|
||||||
$value = $GLOBALS['egw']->translation->convert($value, $sysCharSet, 'utf-8');
|
$value = $GLOBALS['egw']->translation->convert($value, $sysCharSet, 'utf-8');
|
||||||
}
|
}
|
||||||
$sifTask .= "<$sifField>$value</$sifField>";
|
else
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
$value = @htmlspecialchars($value, ENT_QUOTES, 'utf-8');
|
||||||
$sifTask .= "<$sifField>$value</$sifField>";
|
$sifTask .= "<$sifField>$value</$sifField>";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$sifTask .= '<ActualWork>0</ActualWork><IsRecurring>0</IsRecurring></task>';
|
||||||
$sifTask .= '<ActualWork>0</ActualWork><IsRecurring>0</IsRecurring>';
|
return $sifTask;
|
||||||
return base64_encode($sifTask);
|
|
||||||
|
|
||||||
/* return base64_encode("<task>
|
|
||||||
<ActualWork>0</ActualWork>
|
|
||||||
<BillingInformation></BillingInformation>
|
|
||||||
<Body></Body>
|
|
||||||
<Categories></Categories>
|
|
||||||
<Companies></Companies>
|
|
||||||
<Complete>0</Complete>
|
|
||||||
<DateCompleted></DateCompleted>
|
|
||||||
<DueDate></DueDate>
|
|
||||||
<Importance>1</Importance>
|
|
||||||
<IsRecurring>0</IsRecurring>
|
|
||||||
<Mileage></Mileage>
|
|
||||||
<PercentComplete>0</PercentComplete>
|
|
||||||
<ReminderSet>0</ReminderSet>
|
|
||||||
<ReminderTime></ReminderTime>
|
|
||||||
<Sensitivity>0</Sensitivity>
|
|
||||||
<StartDate>45001231T230000Z</StartDate>
|
|
||||||
<Status>3</Status>
|
|
||||||
<Subject>TARAAA3</Subject>
|
|
||||||
<TeamTask>0</TeamTask>
|
|
||||||
<TotalWork>0</TotalWork>
|
|
||||||
<RecurrenceType>1</RecurrenceType>
|
|
||||||
<Interval>1</Interval>
|
|
||||||
<MonthOfYear>0</MonthOfYear>
|
|
||||||
<DayOfMonth>0</DayOfMonth>
|
|
||||||
<DayOfWeekMask>4</DayOfWeekMask>
|
|
||||||
<Instance>0</Instance>
|
|
||||||
<PatternStartDate>20060320T230000Z</PatternStartDate>
|
|
||||||
<NoEndDate>1</NoEndDate>
|
|
||||||
<PatternEndDate></PatternEndDate>
|
|
||||||
<Occurrences>10</Occurrences>
|
|
||||||
</task>
|
|
||||||
"); */
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'note':
|
case 'note':
|
||||||
if($taskData = $this->read($_id)) {
|
if (($taskData = $this->read($_id)))
|
||||||
$sysCharSet = $GLOBALS['egw']->translation->charset();
|
{
|
||||||
$vcal = new Horde_iCalendar;
|
$vcal = new Horde_iCalendar('1.0');
|
||||||
|
|
||||||
$sifNote = '<note>';
|
$sifNote = self::xml_decl . "\n<note>" . self::SIF_decl;
|
||||||
|
|
||||||
foreach ($this->_sifNoteMapping as $sifField => $egwField)
|
foreach ($this->_sifNoteMapping as $sifField => $egwField)
|
||||||
{
|
{
|
||||||
@ -398,36 +545,35 @@ class infolog_sif extends infolog_bo
|
|||||||
|
|
||||||
$value = $GLOBALS['egw']->translation->convert($taskData[$egwField], $sysCharSet, 'utf-8');
|
$value = $GLOBALS['egw']->translation->convert($taskData[$egwField], $sysCharSet, 'utf-8');
|
||||||
|
|
||||||
switch($sifField) {
|
switch ($sifField)
|
||||||
|
{
|
||||||
case 'Date':
|
case 'Date':
|
||||||
if(!empty($value)) {
|
if (!empty($value))
|
||||||
|
{
|
||||||
$value = $vcal->_exportDateTime($value);
|
$value = $vcal->_exportDateTime($value);
|
||||||
}
|
}
|
||||||
$sifNote .= "<$sifField>$value</$sifField>";
|
$sifNote .= "<$sifField>$value</$sifField>";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Body':
|
|
||||||
$value = $GLOBALS['egw']->translation->convert($taskData['info_subject'], $sysCharSet, 'utf-8') . "\n" . $value;
|
|
||||||
$sifNote .= "<$sifField>$value</$sifField>";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'Categories':
|
case 'Categories':
|
||||||
if (!empty($value))
|
if (!empty($value))
|
||||||
{
|
{
|
||||||
$value = implode('; ', $this->get_categories(array($value)));
|
$value = implode('; ', $this->get_categories(array($value)));
|
||||||
$value = $GLOBALS['egw']->translation->convert($value, $sysCharSet, 'utf-8');
|
$value = $GLOBALS['egw']->translation->convert($value, $sysCharSet, 'utf-8');
|
||||||
}
|
}
|
||||||
$sifNote .= "<$sifField>$value</$sifField>";
|
else
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
$value = @htmlspecialchars($value, ENT_QUOTES, 'utf-8');
|
||||||
$sifNote .= "<$sifField>$value</$sifField>";
|
$sifNote .= "<$sifField>$value</$sifField>";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$sifNote .= '</note>';
|
||||||
return base64_encode($sifNote);
|
return $sifNote;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -437,117 +583,35 @@ class infolog_sif extends infolog_bo
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function exportVTODO($_taskID, $_version)
|
/**
|
||||||
|
* Set the supported fields
|
||||||
|
*
|
||||||
|
* Currently we only store name and version, manucfacturer is always Funambol
|
||||||
|
*
|
||||||
|
* @param string $_productName
|
||||||
|
* @param string $_productSoftwareVersion
|
||||||
|
*/
|
||||||
|
function setSupportedFields($_productName='', $_productSoftwareVersion='')
|
||||||
{
|
{
|
||||||
error_log(__METHOD__."called : $_version ,$_taskID");
|
$state = &$_SESSION['SyncML.state'];
|
||||||
$taskData = $this->read($_taskID);
|
$deviceInfo = $state->getClientDeviceInfo();
|
||||||
|
|
||||||
$taskData = $GLOBALS['egw']->translation->convert($taskData,$GLOBALS['egw']->translation->charset(),'UTF-8');
|
if (isset($deviceInfo) && is_array($deviceInfo))
|
||||||
|
|
||||||
//_debug_array($taskData);
|
|
||||||
|
|
||||||
$taskGUID = $GLOBALS['phpgw']->common->generate_uid('infolog_task',$_taskID);
|
|
||||||
|
|
||||||
$vcal = new Horde_iCalendar;
|
|
||||||
$vcal->setAttribute('VERSION',$_version);
|
|
||||||
$vcal->setAttribute('METHOD','PUBLISH');
|
|
||||||
|
|
||||||
$vevent = Horde_iCalendar::newComponent('VTODO',$vcal);
|
|
||||||
|
|
||||||
$options = array();
|
|
||||||
|
|
||||||
$vevent->setAttribute('SUMMARY',$taskData['info_subject']);
|
|
||||||
$vevent->setAttribute('DESCRIPTION',$taskData['info_des']);
|
|
||||||
if($taskData['info_startdate'])
|
|
||||||
$vevent->setAttribute('DTSTART',$taskData['info_startdate']);
|
|
||||||
if($taskData['info_enddate'])
|
|
||||||
$vevent->setAttribute('DUE',$taskData['info_enddate']);
|
|
||||||
$vevent->setAttribute('DTSTAMP',time());
|
|
||||||
$vevent->setAttribute('CREATED',$GLOBALS['phpgw']->contenthistory->getTSforAction('infolog_task',$_taskID,'add'));
|
|
||||||
$vevent->setAttribute('LAST-MODIFIED',$GLOBALS['phpgw']->contenthistory->getTSforAction('infolog_task',$_taskID,'modify'));
|
|
||||||
$vevent->setAttribute('UID',$taskGUID);
|
|
||||||
$vevent->setAttribute('CLASS',(($taskData['info_access'] == 'public')?'PUBLIC':'PRIVATE'));
|
|
||||||
$vevent->setAttribute('STATUS',(($taskData['info_status'] == 'completed')?'COMPLETED':'NEEDS-ACTION'));
|
|
||||||
// 3=urgent => 1, 2=high => 2, 1=normal => 3, 0=low => 4
|
|
||||||
$vevent->setAttribute('PRIORITY',4-$taskData['info_priority']);
|
|
||||||
|
|
||||||
#$vevent->setAttribute('TRANSP','OPAQUE');
|
|
||||||
# status
|
|
||||||
# ATTENDEE
|
|
||||||
|
|
||||||
$options = array('CHARSET' => 'UTF-8','ENCODING' => 'QUOTED-PRINTABLE');
|
|
||||||
$vevent->setParameter('SUMMARY', $options);
|
|
||||||
$vevent->setParameter('DESCRIPTION', $options);
|
|
||||||
|
|
||||||
$vcal->addComponent($vevent);
|
|
||||||
|
|
||||||
#print "<pre>";
|
|
||||||
#print $vcal->exportvCalendar();
|
|
||||||
#print "</pre>";
|
|
||||||
|
|
||||||
return $vcal->exportvCalendar();
|
|
||||||
}
|
|
||||||
|
|
||||||
function importVTODO(&$_vcalData, $_taskID=-1)
|
|
||||||
{
|
{
|
||||||
$botranslation = CreateObject('phpgwapi.translation');
|
if (isset($deviceInfo['uidExtension']) &&
|
||||||
|
$deviceInfo['uidExtension'])
|
||||||
$vcal = new Horde_iCalendar;
|
|
||||||
if(!$vcal->parsevCalendar($_vcalData))
|
|
||||||
{
|
{
|
||||||
return FALSE;
|
$this->uidExtension = true;
|
||||||
}
|
}
|
||||||
$components = $vcal->getComponents();
|
}
|
||||||
if(count($components) > 0)
|
// store product name and version, to be able to use it elsewhere
|
||||||
|
if ($_productName)
|
||||||
{
|
{
|
||||||
$component = $components[0];
|
$this->productName = strtolower($_productName);
|
||||||
if(is_a($component, 'Horde_iCalendar_vtodo'))
|
if (preg_match('/^[^\d]*(\d+\.?\d*)[\.|\d]*$/', $_productSoftwareVersion, $matches))
|
||||||
{
|
{
|
||||||
if($_taskID>0)
|
$this->productSoftwareVersion = $matches[1];
|
||||||
$taskData['info_id'] = $_taskID;
|
|
||||||
|
|
||||||
foreach($component->_attributes as $attributes)
|
|
||||||
{
|
|
||||||
#print $attributes['name'].' - '.$attributes['value'].'<br>';
|
|
||||||
#$attributes['value'] = $GLOBALS['egw']->translation->convert($attributes['value'],'UTF-8');
|
|
||||||
switch($attributes['name'])
|
|
||||||
{
|
|
||||||
case 'CLASS':
|
|
||||||
$taskData['info_access'] = strtolower($attributes['value']);
|
|
||||||
break;
|
|
||||||
case 'DESCRIPTION':
|
|
||||||
$taskData['info_des'] = $attributes['value'];
|
|
||||||
break;
|
|
||||||
case 'DUE':
|
|
||||||
$taskData['info_enddate'] = $attributes['value'];
|
|
||||||
break;
|
|
||||||
case 'DTSTART':
|
|
||||||
$taskData['info_startdate'] = $attributes['value'];
|
|
||||||
break;
|
|
||||||
case 'PRIORITY':
|
|
||||||
// 1 => 3=urgent, 2 => 2=high, 3 => 1=normal, 4 => 0=low
|
|
||||||
if (1 <= $attributes['value'] && $attributes['value'] <= 4)
|
|
||||||
{
|
|
||||||
$taskData['info_priority'] = 4 - $attributes['value'];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$taskData['info_priority'] = 1; // default = normal
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'STATUS':
|
|
||||||
$taskData['info_status'] = (strtolower($attributes['value']) == 'completed') ? 'done' : 'ongoing';
|
|
||||||
break;
|
|
||||||
case 'SUMMARY':
|
|
||||||
$taskData['info_subject'] = $attributes['value'];
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#_debug_array($eventData);exit;
|
|
||||||
return $this->write($taskData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,6 +344,12 @@ class infolog_so
|
|||||||
*/
|
*/
|
||||||
function read($info_id) // did _not_ ensure ACL
|
function read($info_id) // did _not_ ensure ACL
|
||||||
{
|
{
|
||||||
|
if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'])) {
|
||||||
|
$minimum_uid_length = $GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'];
|
||||||
|
} else {
|
||||||
|
$minimum_uid_length = 8;
|
||||||
|
}
|
||||||
|
|
||||||
//echo "<p>read($info_id) ".function_backtrace()."</p>\n";
|
//echo "<p>read($info_id) ".function_backtrace()."</p>\n";
|
||||||
if ($info_id && ((int)$info_id == $this->data['info_id'] || $info_id == $this->data['info_uid']))
|
if ($info_id && ((int)$info_id == $this->data['info_id'] || $info_id == $this->data['info_uid']))
|
||||||
{
|
{
|
||||||
@ -356,6 +362,14 @@ class infolog_so
|
|||||||
$this->init( );
|
$this->init( );
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
if (!$this->data['info_uid'] || strlen($this->data['info_uid']) < $minimum_uid_length) {
|
||||||
|
// entry without uid --> create one based on our info_id and save it
|
||||||
|
|
||||||
|
$this->data['info_uid'] = $GLOBALS['egw']->common->generate_uid('infolog', $info_id);
|
||||||
|
$this->db->update($this->info_table,
|
||||||
|
array('info_uid' => $this->data['info_uid']),
|
||||||
|
array('info_id' => $this->data['info_id']), __LINE__,__FILE__);
|
||||||
|
}
|
||||||
if (!is_array($this->data['info_responsible']))
|
if (!is_array($this->data['info_responsible']))
|
||||||
{
|
{
|
||||||
$this->data['info_responsible'] = $this->data['info_responsible'] ? explode(',',$this->data['info_responsible']) : array();
|
$this->data['info_responsible'] = $this->data['info_responsible'] ? explode(',',$this->data['info_responsible']) : array();
|
||||||
@ -499,6 +513,12 @@ class infolog_so
|
|||||||
*/
|
*/
|
||||||
function write($values,$check_modified=0) // did _not_ ensure ACL
|
function write($values,$check_modified=0) // did _not_ ensure ACL
|
||||||
{
|
{
|
||||||
|
if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'])) {
|
||||||
|
$minimum_uid_length = $GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'];
|
||||||
|
} else {
|
||||||
|
$minimum_uid_length = 8;
|
||||||
|
}
|
||||||
|
|
||||||
//echo "soinfolog::write(,$check_modified) values="; _debug_array($values);
|
//echo "soinfolog::write(,$check_modified) values="; _debug_array($values);
|
||||||
$info_id = (int) $values['info_id'];
|
$info_id = (int) $values['info_id'];
|
||||||
|
|
||||||
@ -540,12 +560,17 @@ class infolog_so
|
|||||||
$this->db->insert($this->info_table,$to_write,false,__LINE__,__FILE__);
|
$this->db->insert($this->info_table,$to_write,false,__LINE__,__FILE__);
|
||||||
$info_id = $this->data['info_id'] = $this->db->get_last_insert_id($this->info_table,'info_id');
|
$info_id = $this->data['info_id'] = $this->db->get_last_insert_id($this->info_table,'info_id');
|
||||||
|
|
||||||
if (!$this->data['info_uid']) // new entry without uid --> create one based on our info_id and save it
|
}
|
||||||
{
|
|
||||||
|
if (!$this->data['info_uid'] || strlen($this->data['info_uid']) < $minimum_uid_length) {
|
||||||
|
// entry without uid --> create one based on our info_id and save it
|
||||||
|
|
||||||
$this->data['info_uid'] = $GLOBALS['egw']->common->generate_uid('infolog', $info_id);
|
$this->data['info_uid'] = $GLOBALS['egw']->common->generate_uid('infolog', $info_id);
|
||||||
$this->db->update($this->info_table,array('info_uid'=>$this->data['info_uid']),array('info_id'=>$info_id),__LINE__,__FILE__);
|
$this->db->update($this->info_table,
|
||||||
}
|
array('info_uid' => $this->data['info_uid']),
|
||||||
|
array('info_id' => $info_id), __LINE__,__FILE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
//echo "<p>soinfolog.write values= "; _debug_array($values);
|
//echo "<p>soinfolog.write values= "; _debug_array($values);
|
||||||
|
|
||||||
// write customfields now
|
// write customfields now
|
||||||
@ -775,6 +800,7 @@ class infolog_so
|
|||||||
if ($action == '' || $action == 'sp' || count($links))
|
if ($action == '' || $action == 'sp' || count($links))
|
||||||
{
|
{
|
||||||
$sql_query = "FROM $this->info_table main $join WHERE ($filtermethod $pid $sql_query) $link_extra";
|
$sql_query = "FROM $this->info_table main $join WHERE ($filtermethod $pid $sql_query) $link_extra";
|
||||||
|
#error_log("infolog.so.search:\n" . print_r($sql_query, true));
|
||||||
|
|
||||||
if ($this->db->Type == 'mysql' && $this->db->ServerInfo['version'] >= 4.0)
|
if ($this->db->Type == 'mysql' && $this->db->ServerInfo['version'] >= 4.0)
|
||||||
{
|
{
|
||||||
|
@ -186,6 +186,7 @@ class infolog_tracking extends bo_tracking
|
|||||||
*/
|
*/
|
||||||
function get_details($data)
|
function get_details($data)
|
||||||
{
|
{
|
||||||
|
$header_done = false;
|
||||||
$responsible = array();
|
$responsible = array();
|
||||||
if ($data['info_responsible'])
|
if ($data['info_responsible'])
|
||||||
{
|
{
|
||||||
|
@ -654,6 +654,7 @@ class infolog_ui
|
|||||||
*
|
*
|
||||||
* @param int|array $values=0 info_id (default _GET[info_id])
|
* @param int|array $values=0 info_id (default _GET[info_id])
|
||||||
* @param string $referer=''
|
* @param string $referer=''
|
||||||
|
* @param boolean $closesingle=false
|
||||||
*/
|
*/
|
||||||
function close($values=0,$referer='',$closesingle=false)
|
function close($values=0,$referer='',$closesingle=false)
|
||||||
{
|
{
|
||||||
@ -973,6 +974,7 @@ class infolog_ui
|
|||||||
}
|
}
|
||||||
$parent = $this->bo->so->data;
|
$parent = $this->bo->so->data;
|
||||||
$content['info_id'] = $info_id = 0;
|
$content['info_id'] = $info_id = 0;
|
||||||
|
$content['info_uid'] = ''; // ensure that we have our own UID
|
||||||
$content['info_owner'] = $this->user;
|
$content['info_owner'] = $this->user;
|
||||||
$content['info_id_parent'] = $parent['info_id'];
|
$content['info_id_parent'] = $parent['info_id'];
|
||||||
/*
|
/*
|
||||||
@ -1432,7 +1434,6 @@ class infolog_ui
|
|||||||
#continue;
|
#continue;
|
||||||
}
|
}
|
||||||
$message .= $bofelamimail->wordwrap($value,75,"\n");
|
$message .= $bofelamimail->wordwrap($value,75,"\n");
|
||||||
#$message .= $bodyAppend;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user