forked from extern/egroupware
Big patch from Philip Herbert (Knauber) modifying the SyncML code to no
longer use GUIDs containing eGW's install_id, as the information is irrellevant for SyncML and cause doublications of entries if the install_id changes. I plan to have a new rc4 Wednesday or Thursday containing these changes.
This commit is contained in:
parent
7c3ab3ab8c
commit
71edd1c938
@ -243,7 +243,8 @@ switch($_POST['action'])
|
||||
'trans' => $_POST['trans']
|
||||
));
|
||||
@set_time_limit(0);
|
||||
$fp=fopen($csvfile,'rb');
|
||||
ini_set('auto_detect_line_endings',true); // to allow to import files created eg. on a mac
|
||||
$fp=fopen($csvfile,'r');
|
||||
$csv_fields = fgetcsv($fp,8000,$_POST['fieldsep']);
|
||||
$csv_fields = $GLOBALS['egw']->translation->convert($csv_fields,$_POST['charset']);
|
||||
$csv_fields[] = 'no CSV 1'; // eg. for static assignments
|
||||
|
@ -421,9 +421,9 @@ class addressbook_vcal extends addressbook_bo
|
||||
));
|
||||
|
||||
$defaultFields[9] = array( // nokia e90
|
||||
'ADR;WORK' => array('','','adr_one_street','adr_one_locality','adr_one_region',
|
||||
'ADR;WORK' => array('','adr_one_street2','adr_one_street','adr_one_locality','adr_one_region',
|
||||
'adr_one_postalcode','adr_one_countryname'),
|
||||
'ADR;HOME' => array('','','adr_two_street','adr_two_locality','adr_two_region',
|
||||
'ADR;HOME' => array('','adr_two_street2','adr_two_street','adr_two_locality','adr_two_region',
|
||||
'adr_two_postalcode','adr_two_countryname'),
|
||||
'BDAY' => array('bday'),
|
||||
'X-CLASS' => array('private'),
|
||||
@ -441,7 +441,7 @@ class addressbook_vcal extends addressbook_bo
|
||||
'TEL;PAGER;WORK' => array('tel_pager'),
|
||||
'TEL;VOICE;WORK' => array('tel_work'),
|
||||
'TEL;VOICE;HOME' => array('tel_home'),
|
||||
'TITLE' => array('contact_role'),
|
||||
'TITLE' => array('title'),
|
||||
'URL;WORK' => array('url'),
|
||||
'URL;HOME' => array('url_home'),
|
||||
'X-ASSISTANT' => array('assistent'),
|
||||
@ -539,6 +539,7 @@ class addressbook_vcal extends addressbook_bo
|
||||
break;
|
||||
case 'e51':
|
||||
case 'e90':
|
||||
case 'e71':
|
||||
$this->supportedFields = $defaultFields[9];
|
||||
break;
|
||||
case '9300':
|
||||
|
@ -391,8 +391,8 @@ class calendar_ical extends calendar_boupdate
|
||||
}
|
||||
}
|
||||
|
||||
$modified = $GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'modify');
|
||||
$created = $GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'add');
|
||||
$modified = $GLOBALS['egw']->contenthistory->getTSforAction('calendar',$event['id'],'modify');
|
||||
$created = $GLOBALS['egw']->contenthistory->getTSforAction('calendar',$event['id'],'add');
|
||||
if (!$created && !$modified) $created = $event['modified'];
|
||||
if ($created) $attributes['CREATED'] = $created;
|
||||
if (!$modified) $modified = $event['modified'];
|
||||
@ -443,7 +443,8 @@ class calendar_ical extends calendar_boupdate
|
||||
}
|
||||
}
|
||||
|
||||
$attributes['UID'] = $force_own_uid ? $eventGUID : $event['uid'];
|
||||
//$attributes['UID'] = $force_own_uid ? $eventGUID : $event['uid'];
|
||||
$attributes['UID'] = $event['uid'];
|
||||
foreach($attributes as $key => $value)
|
||||
{
|
||||
foreach(is_array($value)&&$parameters[$key]['VALUE']!='DATE' ? $value : array($value) as $valueID => $valueData)
|
||||
@ -1166,6 +1167,11 @@ class calendar_ical extends calendar_boupdate
|
||||
case 'e61':
|
||||
$this->supportedFields = $defaultFields['minimal'];
|
||||
break;
|
||||
case 'e51':
|
||||
case 'e90':
|
||||
case 'e71':
|
||||
$this->supportedFields = $defaultFields['basic'];
|
||||
break;
|
||||
default:
|
||||
error_log("Unknown Nokia phone '$_productName', assuming E61");
|
||||
$this->supportedFields = $defaultFields['minimal'];
|
||||
|
@ -81,9 +81,10 @@ class infolog_ical extends infolog_bo
|
||||
if($taskData['info_datecompleted'])
|
||||
$vevent->setAttribute('COMPLETED',$taskData['info_datecompleted']);
|
||||
$vevent->setAttribute('DTSTAMP',time());
|
||||
$vevent->setAttribute('CREATED',$GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'add'));
|
||||
$vevent->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'modify'));
|
||||
$vevent->setAttribute('UID',$force_own_uid ? $taskGUID : $taskData['info_uid']);
|
||||
$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('UID',$force_own_uid ? $taskGUID : $taskData['info_uid']);
|
||||
$vevent->setAttribute('UID',$taskData['info_uid']);
|
||||
$vevent->setAttribute('CLASS',$taskData['info_access'] == 'public' ? 'PUBLIC' : 'PRIVATE');
|
||||
$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
|
||||
@ -253,8 +254,8 @@ class infolog_ical extends infolog_bo
|
||||
$vnote->setAttribute('BODY',$note['info_des']);
|
||||
if($note['info_startdate'])
|
||||
$vnote->setAttribute('DCREATED',$note['info_startdate']);
|
||||
$vnote->setAttribute('DCREATED',$GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'add'));
|
||||
$vnote->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'modify'));
|
||||
$vnote->setAttribute('DCREATED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'add'));
|
||||
$vnote->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'modify'));
|
||||
if (!empty($note['info_cat']))
|
||||
{
|
||||
$cats = $this->get_categories(array($note['info_cat']));
|
||||
|
@ -459,8 +459,8 @@ class infolog_sif extends infolog_bo
|
||||
if($taskData['info_enddate'])
|
||||
$vevent->setAttribute('DUE',$taskData['info_enddate']);
|
||||
$vevent->setAttribute('DTSTAMP',time());
|
||||
$vevent->setAttribute('CREATED',$GLOBALS['phpgw']->contenthistory->getTSforAction($eventGUID,'add'));
|
||||
$vevent->setAttribute('LAST-MODIFIED',$GLOBALS['phpgw']->contenthistory->getTSforAction($eventGUID,'modify'));
|
||||
$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'));
|
||||
|
@ -58,7 +58,7 @@ class contenthistory
|
||||
* @param string$_appName the appname example: infolog_notes
|
||||
* @param string $_action can be modify, add or delete
|
||||
* @param string $_ts timestamp where to start searching from
|
||||
* @return array containing the global UID's
|
||||
* @return array containing contentIds with changes
|
||||
*/
|
||||
function getHistory($_appName, $_action, $_ts)
|
||||
{
|
||||
@ -79,13 +79,13 @@ class contenthistory
|
||||
// no valid $_action set
|
||||
return array();
|
||||
}
|
||||
$guidList = array();
|
||||
foreach($this->db->select(self::TABLE,'sync_guid',$where,__LINE__,__FILE__) as $row)
|
||||
$idList = array();
|
||||
foreach($this->db->select(self::TABLE,'sync_contentid',$where,__LINE__,__FILE__) as $row)
|
||||
{
|
||||
$guidList[] = $row['sync_guid'];
|
||||
$idList[] = $row['sync_contentid'];
|
||||
}
|
||||
|
||||
return $guidList;
|
||||
return $idList;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,7 +95,7 @@ class contenthistory
|
||||
* @param $_action string can be add, delete or modify
|
||||
* @return string the last timestamp
|
||||
*/
|
||||
function getTSforAction($_guid, $_action)
|
||||
function getTSforAction($_appName, $_id, $_action)
|
||||
{
|
||||
switch($_action)
|
||||
{
|
||||
@ -112,7 +112,8 @@ class contenthistory
|
||||
return false;
|
||||
}
|
||||
$where = array (
|
||||
'sync_guid' => $_guid,
|
||||
'sync_appname' => $_appName,
|
||||
'sync_contentid' => $_id,
|
||||
);
|
||||
|
||||
if (($ts = $this->db->select(self::TABLE,$col,$where,__LINE__,__FILE__)->fetchSingle()))
|
||||
@ -137,7 +138,6 @@ class contenthistory
|
||||
'sync_appname' => $_appName,
|
||||
'sync_contentid' => $_id,
|
||||
'sync_added' => $this->db->to_timestamp($_ts),
|
||||
'sync_guid' => $GLOBALS['egw']->common->generate_uid($_appName, $_id),
|
||||
'sync_changedby' => $GLOBALS['egw_info']['user']['account_id'],
|
||||
);
|
||||
|
||||
|
@ -779,10 +779,13 @@ class Horde_SyncML_State {
|
||||
break;
|
||||
|
||||
case 'calendar':
|
||||
case 'caltasks':
|
||||
return 'calendar';
|
||||
break;
|
||||
|
||||
case 'caltasks':
|
||||
return 'caltasks';
|
||||
break;
|
||||
|
||||
# funambol related types
|
||||
|
||||
case 'sifcalendar':
|
||||
|
@ -17,12 +17,67 @@ include_once dirname(__FILE__).'/State.php';
|
||||
class EGW_SyncML_State extends Horde_SyncML_State
|
||||
{
|
||||
var $table_devinfo = 'egw_syncmldevinfo';
|
||||
|
||||
|
||||
/*
|
||||
* store the mappings of egw uids to client uids
|
||||
*/
|
||||
var $uidMappings = array();
|
||||
|
||||
|
||||
/**
|
||||
* get the local content id from a syncid
|
||||
*
|
||||
* @param sting $_syncid id used in syncml
|
||||
* @return int local egw content id
|
||||
*/
|
||||
function get_egwID($_syncid)
|
||||
{
|
||||
$syncIDParts = explode('-',$_syncid);
|
||||
array_shift($syncIDParts);
|
||||
$_id = implode ('', $syncIDParts);
|
||||
return $_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* when got a entry last added/modified/deleted
|
||||
*
|
||||
* @param $_syncid containing appName-contentid
|
||||
* @param $_action string can be add, delete or modify
|
||||
* @return string the last timestamp
|
||||
*/
|
||||
function getSyncTSforAction($_syncid, $_action)
|
||||
{
|
||||
$syncIDParts = explode('-',$_syncid);
|
||||
$_appName = array_shift($syncIDParts);
|
||||
$_id = implode ('', $syncIDParts);
|
||||
|
||||
$ts = $GLOBALS['egw']->contenthistory->getTSforAction($_appName, $_id, $_action);
|
||||
|
||||
return $ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the timestamp for action
|
||||
*
|
||||
* find which content changed since $_ts for application $_appName
|
||||
*
|
||||
* @param string$_appName the appname example: infolog_notes
|
||||
* @param string $_action can be modify, add or delete
|
||||
* @param string $_ts timestamp where to start searching from
|
||||
* @return array containing syncIDs with changes
|
||||
*/
|
||||
function getHistory($_appName, $_action, $_ts)
|
||||
{
|
||||
$guidList = array ();
|
||||
$syncIdList = array ();
|
||||
$idList = $GLOBALS['egw']->contenthistory->getHistory($_appName, $_action, $_ts);
|
||||
foreach ($idList as $idItem)
|
||||
{
|
||||
$syncIdList[] = $_appName . '-' . $idItem;
|
||||
}
|
||||
return $syncIdList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the timestamp (if set) of the last change to the
|
||||
* obj:guid, that was caused by the client. This is stored to
|
||||
@ -257,7 +312,7 @@ class EGW_SyncML_State extends Horde_SyncML_State
|
||||
function removeUID($type, $locid)
|
||||
{
|
||||
$mapID = $this->_locName . $this->_sourceURI . $type;
|
||||
|
||||
|
||||
$where = array (
|
||||
'map_id' => $mapID,
|
||||
'map_locuid' => $locid
|
||||
@ -301,6 +356,9 @@ class EGW_SyncML_State extends Horde_SyncML_State
|
||||
$guid = $this->getUIDMapping($_guid);
|
||||
if($guid === false)
|
||||
{
|
||||
// this message is not really usefull here because setUIDMapping is only called when adding content to the client,
|
||||
// however setUID is called also when adding content from the client. So in all other conditions this
|
||||
// message will be logged.
|
||||
Horde::logMessage("SyncML: setUID $type, $locid, $guid something went wrong!!! Mapping not found.", __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||
$guid = $_guid;
|
||||
//return false;
|
||||
|
@ -163,7 +163,7 @@ class Horde_SyncML_Sync {
|
||||
array($state->convertClient2Server($syncItem->getContent(), $contentType), $contentType));
|
||||
|
||||
if (!is_a($guid, 'PEAR_Error')) {
|
||||
$ts = $history->getTSforAction($guid, 'add');
|
||||
$ts = $state->getSyncTSforAction($guid, 'add');
|
||||
$state->setUID($type, $syncItem->getLocURI(), $guid, $ts);
|
||||
$state->log("Client-Add");
|
||||
Horde::logMessage('SyncML: added client entry as ' . $guid, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
@ -180,7 +180,7 @@ class Horde_SyncML_Sync {
|
||||
|
||||
if (!is_a($guid, 'PEAR_Error') && $guid != false) {
|
||||
$registry->call($hordeType . '/delete', array($guid));
|
||||
#$ts = $history->getTSforAction($guid, 'delete');
|
||||
#$ts = $state->getSyncTSforAction($guid, 'delete');
|
||||
#$state->setUID($type, $syncItem->getLocURI(), $guid, $ts);
|
||||
$state->log("Client-Delete");
|
||||
Horde::logMessage('SyncML: deleted entry ' . $guid . ' due to client request', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
@ -194,13 +194,14 @@ class Horde_SyncML_Sync {
|
||||
if ($guid) {
|
||||
Horde::logMessage('SyncML: locuri'. $syncItem->getLocURI() . ' guid ' . $guid , __FILE__, __LINE__, PEAR_LOG_ERR);
|
||||
// Entry exists: replace current one.
|
||||
$ok = $registry->call($hordeType . '/replace',
|
||||
array($guid, $state->convertClient2Server($syncItem->getContent(), $contentType), $contentType));
|
||||
$ok = $registry->call($hordeType . '/replace',
|
||||
array($guid, $state->convertClient2Server($syncItem->getContent(), $contentType), $contentType));
|
||||
if (!is_a($ok, 'PEAR_Error')) {
|
||||
$ts = $history->getTSforAction($guid, 'modify');
|
||||
$ts = $state->getSyncTSforAction($guid, 'modify');
|
||||
$state->setUID($type, $syncItem->getLocURI(), $guid, $ts);
|
||||
Horde::logMessage('SyncML: replaced entry due to client request guid: ' .$guid. ' ts: ' .$ts, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
$state->log("Client-Replace");
|
||||
error_log("done_replace");
|
||||
$ok = true;
|
||||
} else {
|
||||
// Entry may have been deleted; try adding it.
|
||||
@ -214,7 +215,7 @@ class Horde_SyncML_Sync {
|
||||
$guid = $registry->call($hordeType . '/import',
|
||||
array($state->convertClient2Server($syncItem->getContent(), $contentType), $contentType));
|
||||
if (!is_a($guid, 'PEAR_Error')) {
|
||||
$ts = $history->getTSforAction($guid, 'add');
|
||||
$ts = $state->getSyncTSforAction($guid, 'add');
|
||||
$state->setUID($type, $syncItem->getLocURI(), $guid, $ts);
|
||||
$state->log("Client-AddReplace");
|
||||
Horde::logMessage('SyncML: r/ added client entry as ' . $guid, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
|
@ -19,7 +19,6 @@ class Horde_SyncML_Sync_RefreshFromServerSync extends Horde_SyncML_Sync_TwoWaySy
|
||||
function handleSync($currentCmdID, $hordeType, $syncType, &$output, $refts) {
|
||||
global $registry;
|
||||
|
||||
$history = $GLOBALS['egw']->contenthistory;
|
||||
$state = &$_SESSION['SyncML.state'];
|
||||
|
||||
$adds = &$state->getAddedItems($hordeType);
|
||||
|
@ -160,7 +160,7 @@ class Horde_SyncML_Sync_SlowSync extends Horde_SyncML_Sync_TwoWaySync {
|
||||
$guid = $registry->call($hordeType . '/import',
|
||||
array($state->convertClient2Server($syncItem->getContent(), $contentType), $contentType));
|
||||
if (!is_a($guid, 'PEAR_Error')) {
|
||||
$ts = $history->getTSforAction($guid, 'add');
|
||||
$ts = $state->getSyncTSforAction($guid, 'add');
|
||||
$state->setUID($type, $syncItem->getLocURI(), $guid, $ts);
|
||||
$state->log("Client-AddReplace");
|
||||
Horde::logMessage('SyncML: r/ added client entry as ' . $guid, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
|
@ -60,7 +60,7 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync {
|
||||
// handle changes
|
||||
if(is_array($changes)) {
|
||||
while($guid = array_shift($changes)) {
|
||||
$guid_ts = $history->getTSforAction($guid, 'modify');
|
||||
$guid_ts = $state->getSyncTSforAction($guid, 'modify');
|
||||
$sync_ts = $state->getChangeTS($syncType, $guid);
|
||||
Horde::logMessage("SyncML: timestamp modify guid_ts: $guid_ts sync_ts: $sync_ts", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
if ($sync_ts && $sync_ts == $guid_ts) {
|
||||
@ -115,7 +115,7 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync {
|
||||
// handle deletes
|
||||
if(is_array($deletes)) {
|
||||
while($guid = array_shift($deletes)) {
|
||||
$guid_ts = $history->getTSforAction($guid, 'delete');
|
||||
$guid_ts = $state->getSyncTSforAction($guid, 'delete');
|
||||
$sync_ts = $state->getChangeTS($syncType, $guid);
|
||||
Horde::logMessage("SyncML: timestamp delete guid_ts: $guid_ts sync_ts: $sync_ts", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
if ($sync_ts && $sync_ts == $guid_ts) {
|
||||
@ -163,7 +163,7 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync {
|
||||
|
||||
if(is_array($adds)) {
|
||||
while($guid = array_shift($adds)) {
|
||||
$guid_ts = $history->getTSforAction($guid, 'add');
|
||||
$guid_ts = $state->getSyncTSforAction($guid, 'add');
|
||||
$sync_ts = $state->getChangeTS($syncType, $guid);
|
||||
Horde::logMessage("SyncML: timestamp add $guid guid_ts: $guid_ts sync_ts: $sync_ts", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
if ($sync_ts && $sync_ts == $guid_ts) {
|
||||
|
@ -12,7 +12,7 @@
|
||||
/* Basic information about this app */
|
||||
$setup_info['phpgwapi']['name'] = 'phpgwapi';
|
||||
$setup_info['phpgwapi']['title'] = 'eGroupWare API';
|
||||
$setup_info['phpgwapi']['version'] = '1.5.016';
|
||||
$setup_info['phpgwapi']['version'] = '1.5.017';
|
||||
$setup_info['phpgwapi']['versions']['current_header'] = '1.29';
|
||||
$setup_info['phpgwapi']['enable'] = 3;
|
||||
$setup_info['phpgwapi']['app_order'] = 1;
|
||||
|
@ -302,7 +302,6 @@ $phpgw_baseline = array(
|
||||
'sync_modified' => array('type' => 'timestamp'),
|
||||
'sync_deleted' => array('type' => 'timestamp'),
|
||||
'sync_id' => array('type' => 'auto','nullable' => False),
|
||||
'sync_guid' => array('type' => 'varchar','precision' => '120','nullable' => False),
|
||||
'sync_changedby' => array('type' => 'int','precision' => '4','nullable' => False)
|
||||
),
|
||||
'pk' => array('sync_id'),
|
||||
|
@ -578,3 +578,27 @@ function phpgwapi_upgrade1_5_015()
|
||||
|
||||
return $GLOBALS['setup_info']['phpgwapi']['currentver'] = '1.5.016';
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop no longer needed egw_api_content_history.sync_guid column
|
||||
*/
|
||||
function phpgwapi_upgrade1_5_016()
|
||||
{
|
||||
$GLOBALS['egw_setup']->oProc->DropColumn('egw_api_content_history',array(
|
||||
'fd' => array(
|
||||
'sync_appname' => array('type' => 'varchar','precision' => '60','nullable' => False),
|
||||
'sync_contentid' => array('type' => 'varchar','precision' => '60','nullable' => False),
|
||||
'sync_added' => array('type' => 'timestamp'),
|
||||
'sync_modified' => array('type' => 'timestamp'),
|
||||
'sync_deleted' => array('type' => 'timestamp'),
|
||||
'sync_id' => array('type' => 'auto','nullable' => False),
|
||||
'sync_changedby' => array('type' => 'int','precision' => '4','nullable' => False)
|
||||
),
|
||||
'pk' => array('sync_id'),
|
||||
'fk' => array(),
|
||||
'ix' => array('sync_added','sync_modified','sync_deleted','sync_guid','sync_changedby',array('sync_appname','sync_contentid')),
|
||||
'uc' => array()
|
||||
),'sync_guid');
|
||||
|
||||
return $GLOBALS['setup_info']['phpgwapi']['currentver'] = '1.5.017';
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user