From 45200da6846bf2c68fe882158bdad43dc029c2fa Mon Sep 17 00:00:00 2001 From: Lars Kneschke Date: Tue, 15 Aug 2006 14:42:13 +0000 Subject: [PATCH] various syncml fixes - when doing slowsync we don't update the entries anymore. we just add the needed mapping to the database. - improved handing of deviceinfo --- phpgwapi/inc/horde/Horde/SyncML.php | 6 - .../inc/horde/Horde/SyncML/Command/Alert.php | 201 ++++----- .../inc/horde/Horde/SyncML/Command/Get.php | 1 + .../inc/horde/Horde/SyncML/Command/Put.php | 238 +++++----- .../horde/Horde/SyncML/Command/Results.php | 423 +++++++++--------- phpgwapi/inc/horde/Horde/SyncML/State.php | 135 +++--- phpgwapi/inc/horde/Horde/SyncML/State_egw.php | 306 ++++++++----- .../inc/horde/Horde/SyncML/Sync/SlowSync.php | 94 ++-- .../horde/Horde/SyncML/Sync/TwoWaySync.php | 165 ++++--- 9 files changed, 802 insertions(+), 767 deletions(-) diff --git a/phpgwapi/inc/horde/Horde/SyncML.php b/phpgwapi/inc/horde/Horde/SyncML.php index db5c75dad0..055192a718 100644 --- a/phpgwapi/inc/horde/Horde/SyncML.php +++ b/phpgwapi/inc/horde/Horde/SyncML.php @@ -493,12 +493,6 @@ class Horde_SyncML_SyncMLBody extends Horde_SyncML_ContentHandler { switch($element) { -# case 'Final': -# if($state->getClientSyncStatus() == 1) -# { -# $state->setClientSyncStatus(2); -# } -# break; case 'Sync': $state->setSyncStatus(CLIENT_SYNC_STARTED); Horde::logMessage('SyncML['. session_id() .']: syncStatus(client sync started) ' . $state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_DEBUG); diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Alert.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Alert.php index 14563615a2..4d16a08017 100644 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Alert.php +++ b/phpgwapi/inc/horde/Horde/SyncML/Command/Alert.php @@ -78,8 +78,7 @@ class Horde_SyncML_Command_Alert extends Horde_SyncML_Command { - if($this->_alert < ALERT_RESULT_ALERT) - { + if($this->_alert < ALERT_RESULT_ALERT) { $type = $this->_targetLocURI; @@ -121,6 +120,7 @@ class Horde_SyncML_Command_Alert extends Horde_SyncML_Command { if(isset($this->_targetLocURIParameters)) $sync->_targetLocURIParameters = $this->_targetLocURIParameters; $state->setSync($this->_targetLocURI, $sync); + $state->removeAllUID($this->_targetLocURI); } $status = &new Horde_SyncML_Command_Status($code, 'Alert'); @@ -196,10 +196,46 @@ class Horde_SyncML_Command_Alert extends Horde_SyncML_Command { $output->endElement($state->getURI(), 'Item'); $output->endElement($state->getURI(), 'Alert'); + // still needed? lars $state->_sendFinal = true; - + $currentCmdID++; + + if($state->_devinfoRequested == false && + $this->_sourceLocURI != null && + is_a($state->getPreferedContentTypeClient($this->_sourceLocURI), 'PEAR_Error')) { + + $output->startElement($state->getURI(), 'Get', $attrs); + + $output->startElement($state->getURI(), 'CmdID', $attrs); + $output->characters($currentCmdID); + $currentCmdID++; + $output->endElement($state->getURI(), 'CmdID'); + + $output->startElement($state->getURI(), 'Meta', $attrs); + $output->startElement($state->getURIMeta(), 'Type', $attrs); + if(is_a($output, 'XML_WBXML_Encoder')) { + $output->characters('application/vnd.syncml-devinf+wbxml'); + } else { + $output->characters('application/vnd.syncml-devinf+xml'); + } + $output->endElement($state->getURIMeta(), 'Type'); + $output->endElement($state->getURI(), 'Meta'); + + $output->startElement($state->getURI(), 'Item', $attrs); + $output->startElement($state->getURI(), 'Target', $attrs); + $output->startElement($state->getURI(), 'LocURI', $attrs); + $output->characters(($state->getVersion() == 0) ? './devinf10' : './devinf11'); + $output->endElement($state->getURI(), 'LocURI'); + $output->endElement($state->getURI(), 'Target'); + $output->endElement($state->getURI(), 'Item'); + + $output->endElement($state->getURI(), 'Get'); + + $state->_devinfoRequested = true; + } } + } elseif ($this->_alert == ALERT_NEXT_MESSAGE) { $status = &new Horde_SyncML_Command_Status(RESPONSE_OK, 'Alert'); $status->setCmdRef($this->_cmdID); @@ -214,10 +250,7 @@ class Horde_SyncML_Command_Alert extends Horde_SyncML_Command { $currentCmdID = $status->output($currentCmdID, $output); $state->setAlert222Received(true); - - #if($state->getSyncStatus() > CLIENT_SYNC_STARTED && $state->getSyncStatus() < CLIENT_SYNC_ACKNOWLEDGED) { - # $state->setSyncStatus(CLIENT_SYNC_ACKNOWLEDGED); - #} + } else { $status = &new Horde_SyncML_Command_Status(RESPONSE_OK, 'Alert'); $status->setCmdRef($this->_cmdID); @@ -230,46 +263,6 @@ class Horde_SyncML_Command_Alert extends Horde_SyncML_Command { $currentCmdID = $status->output($currentCmdID, $output); } -/* else - { - if ($state->isAuthorized()) { - $output->startElement($state->getURI(), 'Alert', $attrs); - - $output->startElement($state->getURI(), 'CmdID', $attrs); - $chars = $currentCmdID; - $output->characters($chars); - $output->endElement($state->getURI(), 'CmdID'); - - $output->startElement($state->getURI(), 'Data', $attrs); - $chars = $this->_alert; - $output->characters($chars); - $output->endElement($state->getURI(), 'Data'); - - $output->startElement($state->getURI(), 'Item', $attrs); - - if ($this->_sourceLocURI != null) { - $output->startElement($state->getURI(), 'Target', $attrs); - $output->startElement($state->getURI(), 'LocURI', $attrs); - $chars = $this->_sourceLocURI; - $output->characters($chars); - $output->endElement($state->getURI(), 'LocURI'); - $output->endElement($state->getURI(), 'Target'); - } - - if ($this->_targetLocURI != null) { - $output->startElement($state->getURI(), 'Source', $attrs); - $output->startElement($state->getURI(), 'LocURI', $attrs); - $chars = (isset($this->_targetLocURIParameters) ? $this->_targetLocURI.'?/'.$this->_targetLocURIParameters : $this->_targetLocURI); - $output->characters($chars); - $output->endElement($state->getURI(), 'LocURI'); - $output->endElement($state->getURI(), 'Source'); - } - $output->endElement($state->getURI(), 'Item'); - $output->endElement($state->getURI(), 'Alert'); - - $currentCmdID++; - } - }*/ return $currentCmdID; } @@ -325,60 +318,68 @@ class Horde_SyncML_Command_Alert extends Horde_SyncML_Command { } } - function endElement($uri, $element) - { - switch ($this->_xmlStack) { - case 1: - $state = & $_SESSION['SyncML.state']; - $sync = $state->getSync($this->_targetLocURI); + function endElement($uri, $element) + { + switch ($this->_xmlStack) { + case 1: + $state = & $_SESSION['SyncML.state']; + $sync = $state->getSync($this->_targetLocURI); + + if (!$sync && $this->_alert < ALERT_RESULT_ALERT) { + Horde::logMessage('SyncML: create new sync for ' . $this->_targetLocURI . ' ' . $this->_alert, __FILE__, __LINE__, PEAR_LOG_DEBUG); + $sync = &Horde_SyncML_Sync::factory($this->_alert); + + $sync->_targetLocURI = $this->_targetLocURI; + $sync->_sourceLocURI = $this->_sourceLocURI; + if(isset($this->_targetLocURIParameters)) { + $sync->_targetLocURIParameters = $this->_targetLocURIParameters; + } + + $state->setSync($this->_targetLocURI, $sync); - if (!$sync && $this->_alert < ALERT_RESULT_ALERT) { - Horde::logMessage('SyncML: create new sync for ' . $this->_targetLocURI . ' ' . $this->_alert, __FILE__, __LINE__, PEAR_LOG_DEBUG); - $sync = &Horde_SyncML_Sync::factory($this->_alert); - - $sync->_targetLocURI = $this->_targetLocURI; - $sync->_sourceLocURI = $this->_sourceLocURI; - if(isset($this->_targetLocURIParameters)) - $sync->_targetLocURIParameters = $this->_targetLocURIParameters; - - $state->setSync($this->_targetLocURI, $sync); - } - break; - - case 2: - if ($element == 'Data') { - $this->_alert = intval(trim($this->_chars)); - } - break; - - case 4: - if ($element == 'LocURI') { - if ($this->_isInSource) { - $this->_sourceLocURI = trim($this->_chars); - } else { - $targetLocURIData = explode('?/',trim($this->_chars)); - - $this->_targetLocURI = $targetLocURIData[0]; - - if(isset($targetLocURIData[1])) - { - $this->_targetLocURIParameters = $targetLocURIData[1]; - } - } - } - break; - - case 5: - if ($element == 'Next') { - $this->_metaAnchorNext = trim($this->_chars); - } else if ($element == 'Last') { - $this->_metaAnchorLast = trim($this->_chars); - } - break; - } - - parent::endElement($uri, $element); - } + if($this->_alert == ALERT_SLOW_SYNC) { + $state->removeAllUID($this->_targetLocURI); + } + } + + break; + + case 2: + if ($element == 'Data') { + $this->_alert = intval(trim($this->_chars)); + } + + break; + + case 4: + if ($element == 'LocURI') { + if ($this->_isInSource) { + $this->_sourceLocURI = trim($this->_chars); + } else { + $targetLocURIData = explode('?/',trim($this->_chars)); + + $this->_targetLocURI = $targetLocURIData[0]; + + if(isset($targetLocURIData[1])) { + $this->_targetLocURIParameters = $targetLocURIData[1]; + } + } + } + + break; + + case 5: + if ($element == 'Next') { + $this->_metaAnchorNext = trim($this->_chars); + } else if ($element == 'Last') { + $this->_metaAnchorLast = trim($this->_chars); + } + + break; + } + + parent::endElement($uri, $element); + } function getAlert() { diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Get.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Get.php index f2b344a9c8..ddcc6122ae 100644 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Get.php +++ b/phpgwapi/inc/horde/Horde/SyncML/Command/Get.php @@ -90,6 +90,7 @@ class Horde_SyncML_Command_Get extends Horde_SyncML_Command { $this->_writeDataStore('./contacts', 'text/x-vcard', '2.1', $output); $this->_writeDataStore('./tasks', 'text/x-vcalendar', '1.0', $output); $this->_writeDataStore('./calendar', 'text/x-vcalendar', '1.0', $output); + $this->_writeDataStore('./caltasks', 'text/x-vcalendar', '1.0', $output); $output->endElement($state->getURIDevInf() , 'DevInf', $attrs); $output->endElement($state->getURI(), 'Data'); diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Put.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Put.php index 7e03b36687..5d0c5d48ba 100644 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Put.php +++ b/phpgwapi/inc/horde/Horde/SyncML/Command/Put.php @@ -42,116 +42,136 @@ class Horde_SyncML_Command_Put extends Horde_SyncML_Command { var $_softwareVersion; - function endElement($uri, $element) - { - #Horde::logMessage('SyncML: put endelement ' . $element . ' stack ' . $this->_xmlStack, __FILE__, __LINE__, PEAR_LOG_DEBUG); - switch ($this->_xmlStack) { - case 5: - switch($element) { - case 'DataStore': - $this->_deviceInfo['dataStore'][$this->_sourceReference] = array( - 'maxGUIDSize' => $this->_maxGUIDSize, - 'rxPreference' => $this->_rxPreference, - 'txPreference' => $this->_txPreference, - 'syncCapabilities' => $this->_syncCapabilities, - ); - break; - case 'DevID': - $this->_deviceInfo['deviceID'] = trim($this->_chars); - break; - case 'DevTyp': - $this->_deviceInfo['deviceType'] = trim($this->_chars); - break; - case 'Man': - $this->_deviceInfo['manufacturer'] = trim($this->_chars); - break; - case 'Mod': - $this->_deviceInfo['model'] = trim($this->_chars); - break; - case 'OEM': - $this->_deviceInfo['oem'] = trim($this->_chars); - break; - case 'SwV': - $this->_deviceInfo['softwareVersion'] = trim($this->_chars); - break; - case 'SupportLargeObjs': - $this->_deviceInfo['supportLargeObjs'] = true; - break; - case 'SupportNumberOfChanges': - $this->_deviceInfo['supportNumberOfChanges'] = true; - break; - case 'VerDTD': - $this->_deviceInfo['DTDVersion'] = trim($this->_chars); - break; - } - break; - case 6: - switch($element) { - case 'MaxGUIDSize': - $this->_maxGUIDSize = trim($this->_chars); - break; - case 'Rx-Pref': - $this->_rxPreference = array( - 'contentType' => $this->_contentType, - 'contentVersion' => $this->_contentVersion, - ); - break; - case 'SourceRef': - $this->_sourceReference = trim($this->_chars); - break; - case 'Tx-Pref': - $this->_txPreference = array( - 'contentType' => $this->_contentType, - 'contentVersion' => $this->_contentVersion, - ); - break; - } - break; - case 7: - switch($element) { - case 'CTType': - $this->_contentType = trim($this->_chars); - break; - case 'SyncType': - $this->_syncCapabilities[] = trim($this->_chars); - break; - case 'VerCT': - $this->_contentVersion = trim($this->_chars); - break; - } - break; - } - - parent::endElement($uri, $element); - } + function endElement($uri, $element) { + switch ($this->_xmlStack) { + case 5: + switch($element) { + case 'DataStore': + $this->_deviceInfo['dataStore'][$this->_sourceReference] = array( + 'maxGUIDSize' => $this->_maxGUIDSize, + 'rxPreference' => $this->_rxPreference, + 'txPreference' => $this->_txPreference, + 'syncCapabilities' => $this->_syncCapabilities, + ); + break; + + case 'DevID': + $this->_deviceInfo['deviceID'] = trim($this->_chars); + break; + + case 'DevTyp': + $this->_deviceInfo['deviceType'] = trim($this->_chars); + break; + + case 'FwV': + $this->_deviceInfo['firmwareVersion'] = trim($this->_chars); + break; + + case 'HwV': + $this->_deviceInfo['hardwareVersion'] = trim($this->_chars); + break; + + case 'Man': + $this->_deviceInfo['manufacturer'] = trim($this->_chars); + break; + + case 'Mod': + $this->_deviceInfo['model'] = trim($this->_chars); + break; + + case 'OEM': + $this->_deviceInfo['oem'] = trim($this->_chars); + break; + + case 'SwV': + $this->_deviceInfo['softwareVersion'] = trim($this->_chars); + break; + + case 'SupportLargeObjs': + $this->_deviceInfo['supportLargeObjs'] = true; + break; + + case 'SupportNumberOfChanges': + $this->_deviceInfo['supportNumberOfChanges'] = true; + break; + + case 'UTC': + $this->_deviceInfo['UTC'] = true; + break; + + case 'VerDTD': + $this->_deviceInfo['DTDVersion'] = trim($this->_chars); + break; + } + break; + case 6: + switch($element) { + case 'MaxGUIDSize': + $this->_maxGUIDSize = trim($this->_chars); + break; + + case 'Rx-Pref': + $this->_rxPreference = array( + 'contentType' => $this->_contentType, + 'contentVersion' => $this->_contentVersion, + ); + break; + + case 'SourceRef': + $this->_sourceReference = trim($this->_chars); + break; + + case 'Tx-Pref': + $this->_txPreference = array( + 'contentType' => $this->_contentType, + 'contentVersion' => $this->_contentVersion, + ); + break; + } + break; + + case 7: + switch($element) { + case 'CTType': + $this->_contentType = trim($this->_chars); + break; + + case 'SyncType': + $this->_syncCapabilities[] = trim($this->_chars); + break; + + case 'VerCT': + $this->_contentVersion = trim($this->_chars); + break; + } + break; + } + + parent::endElement($uri, $element); + } - function output($currentCmdID, &$output ) - { - $state = &$_SESSION['SyncML.state']; + function output($currentCmdID, &$output ) { + $state = &$_SESSION['SyncML.state']; + + $status = &new Horde_SyncML_Command_Status((($state->isAuthorized()) ? RESPONSE_OK : RESPONSE_INVALID_CREDENTIALS), 'Put'); + $status->setCmdRef($this->_cmdID); + + $ref = ($state->getVersion() == 0) ? './devinf10' : './devinf11'; + + $status->setSourceRef($ref); + + if($state->isAuthorized()) { + if(count((array)$this->_deviceInfo) > 0) { + $state->setClientDeviceInfo($this->_deviceInfo); + $state->writeClientDeviceInfo(); + } + } + + return $status->output($currentCmdID, $output); + } - $status = &new Horde_SyncML_Command_Status((($state->isAuthorized()) ? RESPONSE_OK : RESPONSE_INVALID_CREDENTIALS), 'Put'); - $status->setCmdRef($this->_cmdID); - - $ref = ($state->getVersion() == 0) ? './devinf10' : './devinf11'; - - $status->setSourceRef($ref); - - if($state->isAuthorized()) - { - if(count((array)$this->_deviceInfo) > 0) - { - $state->setClientDeviceInfo($this->_deviceInfo); - $state->writeClientDeviceInfo(); - } - } - - return $status->output($currentCmdID, $output); - } - - function startElement($uri, $element, $attrs) - { - #Horde::logMessage('SyncML: put startelement ' . $element, __FILE__, __LINE__, PEAR_LOG_DEBUG); - parent::startElement($uri, $element, $attrs); - } + function startElement($uri, $element, $attrs) { + parent::startElement($uri, $element, $attrs); + } } diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Results.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Results.php index 4ad52c8eb2..6759896d50 100644 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Results.php +++ b/phpgwapi/inc/horde/Horde/SyncML/Command/Results.php @@ -18,212 +18,229 @@ include_once 'Horde/SyncML/Command.php'; */ class Horde_SyncML_Command_Results extends Horde_SyncML_Command { - var $_cmdRef; - var $_type; - var $_data; - var $_locSourceURI; - var $_deviceInfo; + var $_cmdRef; + var $_type; + var $_data; + var $_locSourceURI; + var $_deviceInfo; + + function endElement($uri, $element) { + #Horde::logMessage('SyncML: put endelement ' . $element . ' stack ' . $this->_xmlStack, __FILE__, __LINE__, PEAR_LOG_DEBUG); + + switch ($this->_xmlStack) { + case 5: + switch($element) { + case 'DataStore': + $this->_deviceInfo['dataStore'][$this->_sourceReference] = array ( + 'maxGUIDSize' => $this->_maxGUIDSize, + 'rxPreference' => $this->_rxPreference, + 'txPreference' => $this->_txPreference, + 'syncCapabilities' => $this->_syncCapabilities, + ); + break; + + case 'DevID': + $this->_deviceInfo['deviceID'] = trim($this->_chars); + break; + + case 'DevTyp': + $this->_deviceInfo['deviceType'] = trim($this->_chars); + break; + + case 'FwV': + $this->_deviceInfo['firmwareVersion'] = trim($this->_chars); + break; + + case 'HwV': + $this->_deviceInfo['hardwareVersion'] = trim($this->_chars); + break; + + case 'Man': + $this->_deviceInfo['manufacturer'] = trim($this->_chars); + break; + + case 'Mod': + $this->_deviceInfo['model'] = trim($this->_chars); + break; + + case 'OEM': + $this->_deviceInfo['oem'] = trim($this->_chars); + break; + + case 'SwV': + $this->_deviceInfo['softwareVersion'] = trim($this->_chars); + break; + + case 'SupportLargeObjs': + $this->_deviceInfo['supportLargeObjs'] = true; + break; + + case 'SupportNumberOfChanges': + $this->_deviceInfo['supportNumberOfChanges'] = true; + break; + + case 'UTC': + $this->_deviceInfo['UTC'] = true; + break; + + case 'VerDTD': + $this->_deviceInfo['DTDVersion'] = trim($this->_chars); + break; + } + break; - function endElement($uri, $element) - { - #Horde::logMessage('SyncML: put endelement ' . $element . ' stack ' . $this->_xmlStack, __FILE__, __LINE__, PEAR_LOG_DEBUG); - switch ($this->_xmlStack) { - case 5: - switch($element) { - case 'DataStore': - $this->_deviceInfo['dataStore'][$this->_sourceReference] = array( - 'maxGUIDSize' => $this->_maxGUIDSize, - 'rxPreference' => $this->_rxPreference, - 'txPreference' => $this->_txPreference, - 'syncCapabilities' => $this->_syncCapabilities, - ); - break; - case 'DevID': - $this->_deviceInfo['deviceID'] = trim($this->_chars); - break; - case 'DevTyp': - $this->_deviceInfo['deviceType'] = trim($this->_chars); - break; - case 'Man': - $this->_deviceInfo['manufacturer'] = trim($this->_chars); - break; - case 'Mod': - $this->_deviceInfo['model'] = trim($this->_chars); - break; - case 'OEM': - $this->_deviceInfo['oem'] = trim($this->_chars); - break; - case 'SwV': - $this->_deviceInfo['softwareVersion'] = trim($this->_chars); - break; - case 'SupportLargeObjs': - $this->_deviceInfo['supportLargeObjs'] = true; - break; - case 'SupportNumberOfChanges': - $this->_deviceInfo['supportNumberOfChanges'] = true; - break; - case 'VerDTD': - $this->_deviceInfo['DTDVersion'] = trim($this->_chars); - break; - } - break; - case 6: - switch($element) { - case 'MaxGUIDSize': - $this->_maxGUIDSize = trim($this->_chars); - break; - case 'Rx-Pref': - $this->_rxPreference = array( - 'contentType' => $this->_contentType, - 'contentVersion' => $this->_contentVersion, - ); - break; - case 'SourceRef': - $this->_sourceReference = trim($this->_chars); - break; - case 'Tx-Pref': - $this->_txPreference = array( - 'contentType' => $this->_contentType, - 'contentVersion' => $this->_contentVersion, - ); - break; - } - break; - case 7: - switch($element) { - case 'CTType': - $this->_contentType = trim($this->_chars); - break; - case 'SyncType': - $this->_syncCapabilities[] = trim($this->_chars); - break; - case 'VerCT': - $this->_contentVersion = trim($this->_chars); - break; - } - break; - } - - parent::endElement($uri, $element); - } - - function output($currentCmdID, &$output) - { - if(!isset($this->_locSourceURI)) - { - Horde::logMessage('SyncML: BIG TODO!!!!!!!!!!!!!!!!!! parse reply', __FILE__, __LINE__, PEAR_LOG_DEBUG); - $state = &$_SESSION['SyncML.state']; - - $status = &new Horde_SyncML_Command_Status((($state->isAuthorized()) ? RESPONSE_OK : RESPONSE_INVALID_CREDENTIALS), 'Results'); - $status->setCmdRef($this->_cmdID); - - $ref = ($state->getVersion() == 0) ? './devinf10' : './devinf11'; - - $status->setSourceRef($ref); - - if($state->isAuthorized()) - { - if(count((array)$this->_deviceInfo) > 0) - { - $state->setClientDeviceInfo($this->_deviceInfo); - $state->writeClientDeviceInfo(); - } + case 6: + switch($element) { + case 'MaxGUIDSize': + $this->_maxGUIDSize = trim($this->_chars); + break; + + case 'Rx-Pref': + $this->_rxPreference = array ( + 'contentType' => $this->_contentType, + 'contentVersion' => $this->_contentVersion, + ); + break; + + case 'SourceRef': + $this->_sourceReference = trim($this->_chars); + break; + + case 'Tx-Pref': + $this->_txPreference = array( + 'contentType' => $this->_contentType, + 'contentVersion' => $this->_contentVersion, + ); + break; + } + break; + + case 7: + switch($element) { + case 'CTType': + $this->_contentType = trim($this->_chars); + break; + + case 'SyncType': + $this->_syncCapabilities[] = trim($this->_chars); + break; + + case 'VerCT': + $this->_contentVersion = trim($this->_chars); + break; + } + break; } - return $status->output($currentCmdID, $output); + parent::endElement($uri, $element); } - else - { - Horde::logMessage('SyncML: BIG TODO!!!!!!!!!!!!!!!!!! generate reponse', __FILE__, __LINE__, PEAR_LOG_DEBUG); - $state = $_SESSION['SyncML.state']; - - $attrs = array(); - $output->startElement($state->getURI(), 'Results', $attrs); - - $output->startElement($state->getURI(), 'CmdID', $attrs); - $chars = $currentCmdID; - $output->characters($chars); - $output->endElement($state->getURI(), 'CmdID'); - - $output->startElement($state->getURI(), 'MsgRef', $attrs); - $chars = $state->getMsgID(); - $output->characters($chars); - $output->endElement($state->getURI(), 'MsgRef'); - - $output->startElement($state->getURI(), 'CmdRef', $attrs); - $chars = $this->_cmdRef; - $output->characters($chars); - $output->endElement($state->getURI(), 'CmdRef'); - - $output->startElement($state->getURI(), 'Meta', $attrs); - $output->startElement($state->getURIMeta(), 'Type', $attrs); - $output->characters($this->_type); - $output->endElement($state->getURIMeta(), 'Type'); - $output->endElement($state->getURI(), 'Meta'); - - $output->startElement($state->getURI(), 'Item', $attrs); - $output->startElement($state->getURI(), 'Source', $attrs); - $output->startElement($state->getURI(), 'LocURI', $attrs); - $chars = $this->_locSourceURI; - $output->characters($chars); - $output->endElement($state->getURI(), 'LocURI'); - $output->endElement($state->getURI(), 'Source'); - - $output->startElement($state->getURI(), 'Data', $attrs); - - // Need to send this information as opaque data so the WBXML - // will understand it. - $output->opaque($this->_data); - - $output->endElement($state->getURI(), 'Data'); - $output->endElement($state->getURI(), 'Item'); - - $output->endElement($state->getURI(), 'Results'); - - $currentCmdID++; - - return $currentCmdID; + + function output($currentCmdID, &$output) { + if(!isset($this->_locSourceURI)) { + #Horde::logMessage('SyncML: BIG TODO!!!!!!!!!!!!!!!!!! parse reply', __FILE__, __LINE__, PEAR_LOG_DEBUG); + $state = &$_SESSION['SyncML.state']; + + $status = &new Horde_SyncML_Command_Status((($state->isAuthorized()) ? RESPONSE_OK : RESPONSE_INVALID_CREDENTIALS), 'Results'); + $status->setCmdRef($this->_cmdID); + + $ref = ($state->getVersion() == 0) ? './devinf10' : './devinf11'; + + $status->setSourceRef($ref); + + if($state->isAuthorized()) { + if(count((array)$this->_deviceInfo) > 0) { + $state->setClientDeviceInfo($this->_deviceInfo); + $state->writeClientDeviceInfo(); + } + } + + return $status->output($currentCmdID, $output); + } else { + #Horde::logMessage('SyncML: BIG TODO!!!!!!!!!!!!!!!!!! generate reponse', __FILE__, __LINE__, PEAR_LOG_DEBUG); + $state = $_SESSION['SyncML.state']; + + $attrs = array(); + $output->startElement($state->getURI(), 'Results', $attrs); + + $output->startElement($state->getURI(), 'CmdID', $attrs); + $chars = $currentCmdID; + $output->characters($chars); + $output->endElement($state->getURI(), 'CmdID'); + + $output->startElement($state->getURI(), 'MsgRef', $attrs); + $chars = $state->getMsgID(); + $output->characters($chars); + $output->endElement($state->getURI(), 'MsgRef'); + + $output->startElement($state->getURI(), 'CmdRef', $attrs); + $chars = $this->_cmdRef; + $output->characters($chars); + $output->endElement($state->getURI(), 'CmdRef'); + + $output->startElement($state->getURI(), 'Meta', $attrs); + $output->startElement($state->getURIMeta(), 'Type', $attrs); + $output->characters($this->_type); + $output->endElement($state->getURIMeta(), 'Type'); + $output->endElement($state->getURI(), 'Meta'); + + $output->startElement($state->getURI(), 'Item', $attrs); + $output->startElement($state->getURI(), 'Source', $attrs); + $output->startElement($state->getURI(), 'LocURI', $attrs); + $chars = $this->_locSourceURI; + $output->characters($chars); + $output->endElement($state->getURI(), 'LocURI'); + $output->endElement($state->getURI(), 'Source'); + + $output->startElement($state->getURI(), 'Data', $attrs); + + // Need to send this information as opaque data so the WBXML + // will understand it. + $output->opaque($this->_data); + + $output->endElement($state->getURI(), 'Data'); + $output->endElement($state->getURI(), 'Item'); + + $output->endElement($state->getURI(), 'Results'); + + $currentCmdID++; + + return $currentCmdID; + } + } + + /** + * Setter for property cmdRef. + * + * @param string $cmdRef New value of property cmdRef. + */ + function setCmdRef($cmdRef) { + $this->_cmdRef = $cmdRef; + } + + /** + * Setter for property Type. + * + * @param string $type New value of property type. + */ + function setType($type) { + $this->_type = $type; + } + + /** + * Setter for property data. + * + * @param string $data New value of property data. + */ + function setData($data) { + $this->_data = $data; + } + + /** + * Setter for property locSourceURI. + * + * @param string $locSourceURI New value of property locSourceURI. + */ + function setlocSourceURI($locSourceURI) { + $this->_locSourceURI = $locSourceURI; } - } - - /** - * Setter for property cmdRef. - * - * @param string $cmdRef New value of property cmdRef. - */ - function setCmdRef($cmdRef) - { - $this->_cmdRef = $cmdRef; - } - - /** - * Setter for property Type. - * - * @param string $type New value of property type. - */ - function setType($type) - { - $this->_type = $type; - } - - /** - * Setter for property data. - * - * @param string $data New value of property data. - */ - function setData($data) - { - $this->_data = $data; - } - - /** - * Setter for property locSourceURI. - * - * @param string $locSourceURI New value of property locSourceURI. - */ - function setlocSourceURI($locSourceURI) - { - $this->_locSourceURI = $locSourceURI; - } - } diff --git a/phpgwapi/inc/horde/Horde/SyncML/State.php b/phpgwapi/inc/horde/Horde/SyncML/State.php index 98d23646d0..77009fd454 100644 --- a/phpgwapi/inc/horde/Horde/SyncML/State.php +++ b/phpgwapi/inc/horde/Horde/SyncML/State.php @@ -199,6 +199,9 @@ class Horde_SyncML_State { // stores if we received Alert 222 already var $_receivedAlert222 = false; + + // stores if we already requested the deviceinfo + var $_devinfoRequested = false; /** * Creates a new instance of Horde_SyncML_State. @@ -625,87 +628,65 @@ class Horde_SyncML_State { return $guid; } - /** - * This function should use DevINF information. - */ - function getPreferedContentType($type) - { -# if ($type == 'contacts') { -# return 'text/x-vcard'; -# } elseif ($type == 'notes') { -# return 'text/x-vnote'; -# } elseif ($type == 'tasks') { -# return 'text/x-vcalendar'; -# } elseif ($type == 'calendar') { -# return 'text/x-vcalendar'; -# } - switch($type) { - case 'contacts': - case './contacts': - return 'text/x-vcard'; - break; - - case 'sifcalendar': - case './sifcalendar': - return 'text/x-s4j-sife'; - break; - - case 'sifcontacts': - case './sifcontacts': - return 'text/x-s4j-sifc'; - break; - - case 'siftasks': - case './siftasks': - return 'text/x-s4j-sift'; - break; - - case 'notes': - return 'text/x-vnote'; - break; + + /** + * This function should use DevINF information. + */ + function getPreferedContentType($type) { + switch($type) { + case 'contacts': + case './contacts': + return 'text/x-vcard'; + break; + + case 'sifcalendar': + case './sifcalendar': + return 'text/x-s4j-sife'; + break; + + case 'sifcontacts': + case './sifcontacts': + return 'text/x-s4j-sifc'; + break; + + case 'siftasks': + case './siftasks': + return 'text/x-s4j-sift'; + break; - case 'tasks': - return 'text/x-vcalendar'; - break; + case 'notes': + return 'text/x-vnote'; + break; + + case 'tasks': + return 'text/x-vcalendar'; + break; - case 'calendar': - case './calendar': - return 'text/x-vcalendar'; - break; + case 'calendar': + case './calendar': + return 'text/x-vcalendar'; + break; + } } - } - /** - * Returns the preferred contenttype of the client for the given - * sync data type (database). - * - * This is passed as an option to the Horde API export functions. - */ - function getPreferedContentTypeClient($_sourceLocURI) - { - $deviceInfo = $this->getClientDeviceInfo(); - - if(isset($deviceInfo['dataStore'][$_sourceLocURI]['rxPreference']['contentType'])) - { - return array('ContentType' => $deviceInfo['dataStore'][$_sourceLocURI]['rxPreference']['contentType']); - } - - Horde::logMessage('SyncML: sourceLocURI ' . $_sourceLocURI .' not found', __FILE__, __LINE__, PEAR_LOG_DEBUG); - return PEAR::raiseError(_('sourceLocURI not found')); -# elseif ($type == 'contacts') { -# return 'text/x-vcard'; -# } elseif ($type == 'notes') { -# return array('ContentType' => 'text/x-vnote', -# 'ENCODING' => 'QUOTED-PRINTABLE', -# 'CHARSET' => 'UTF-8'); -# } elseif ($type == 'tasks') { -# return 'text/x-vcalendar'; -# } elseif ($type == 'calendar') { -# return array('ContentType' => 'text/x-vcalendar', -# 'ENCODING' => 'QUOTED-PRINTABLE', -# 'CHARSET' => 'UTF-8'); -# } - } + /** + * Returns the preferred contenttype of the client for the given + * sync data type (database). + * + * This is passed as an option to the Horde API export functions. + */ + + function getPreferedContentTypeClient($_sourceLocURI) { + $deviceInfo = $this->getClientDeviceInfo(); + + if(isset($deviceInfo['dataStore'][$_sourceLocURI]['rxPreference']['contentType'])) { + return array('ContentType' => $deviceInfo['dataStore'][$_sourceLocURI]['rxPreference']['contentType']); + } + + Horde::logMessage('SyncML: sourceLocURI ' . $_sourceLocURI .' not found', __FILE__, __LINE__, PEAR_LOG_DEBUG); + + return PEAR::raiseError(_('sourceLocURI not found')); + } function setClientAnchorNext($type, $a) { diff --git a/phpgwapi/inc/horde/Horde/SyncML/State_egw.php b/phpgwapi/inc/horde/Horde/SyncML/State_egw.php index 3bfc501d68..2528369f4e 100644 --- a/phpgwapi/inc/horde/Horde/SyncML/State_egw.php +++ b/phpgwapi/inc/horde/Horde/SyncML/State_egw.php @@ -36,61 +36,73 @@ class EGW_SyncML_State extends Horde_SyncML_State return false; } - /** - * Retrieves information about the clients device info if any. Returns - * false if no info found or a DateTreeObject with at least the - * following attributes: - * - * a array containing all available infos about the device - */ - function getClientDeviceInfo() - { - $deviceID = $this->_locName . $this->_sourceURI; - - $db = clone($GLOBALS['egw']->db); - - $cols = array - ( - 'dev_dtdversion', - 'dev_numberofchanges', - 'dev_largeobjs', - 'dev_swversion', - 'dev_oem', - 'dev_model', - 'dev_manufacturer', - 'dev_devicetype', - 'dev_deviceid', - 'dev_datastore', - ); - - $where = array - ( - 'dev_id' => $deviceID, - ); - - $db->select('egw_syncmldevinfo', $cols, $where, __LINE__, __FILE__); - - if($db->next_record()) - { - $devInfo = array - ( - 'DTDVersion' => $db->f('dev_dtdversion'), - 'supportNumberOfChanges' => $db->f('dev_numberofchanges'), - 'supportLargeObjs' => $db->f('dev_largeobjs'), - 'softwareVersion' => $db->f('dev_swversion'), - 'oem' => $db->f('dev_oem'), - 'model' => $db->f('dev_model'), - 'manufacturer' => $db->f('dev_manufacturer'), - 'deviceType' => $db->f('dev_devicetype'), - 'deviceID' => $db->f('dev_deviceid'), - 'dataStore' => unserialize($db->f('dev_datastore')), - ); - - return $devInfo; - } - - return false; - } + /** + * Retrieves information about the clients device info if any. Returns + * false if no info found or a DateTreeObject with at least the + * following attributes: + * + * a array containing all available infos about the device + */ + function getClientDeviceInfo() { + $db = clone($GLOBALS['egw']->db); + + $cols = array( + 'owner_devid', + ); + + $where = array ( + 'owner_locname' => $this->_locName, + 'owner_deviceid' => $this->_sourceURI, + ); + + $db->select('egw_syncmldeviceowner', $cols, $where, __LINE__, __FILE__); + + if($db->next_record()) { + $deviceID = $db->f('owner_devid'); + + $cols = array( + 'dev_dtdversion', + 'dev_numberofchanges', + 'dev_largeobjs', + 'dev_swversion', + 'dev_fwversion', + 'dev_hwversion', + 'dev_oem', + 'dev_model', + 'dev_manufacturer', + 'dev_devicetype', + 'dev_datastore', + 'dev_utc', + ); + + $where = array( + 'dev_id' => $deviceID, + ); + + $db->select('egw_syncmldevinfo', $cols, $where, __LINE__, __FILE__); + + if($db->next_record()) { + $devInfo = array ( + 'DTDVersion' => $db->f('dev_dtdversion'), + 'supportNumberOfChanges' => $db->f('dev_numberofchanges'), + 'supportLargeObjs' => $db->f('dev_largeobjs'), + 'UTC' => $db->f('dev_utc'), + 'softwareVersion' => $db->f('dev_swversion'), + 'hardwareVersion' => $db->f('dev_hwversion'), + 'firmwareVersion' => $db->f('dev_fwversion'), + 'oem' => $db->f('dev_oem'), + 'model' => $db->f('dev_model'), + 'manufacturer' => $db->f('dev_manufacturer'), + 'deviceType' => $db->f('dev_devicetype'), + 'dataStore' => unserialize($db->f('dev_datastore')), + ); + + return $devInfo; + } + } + + return false; + } /** * Retrieves the Horde server guid (like @@ -243,41 +255,62 @@ class EGW_SyncML_State extends Horde_SyncML_State return $this->_isAuthorized; } - /** - * Removes the locid<->guid mapping for the given locid. Returns - * the guid that was removed or false if no mapping entry was - * found. - */ - function removeUID($type, $locid) - { - $mapID = $this->_locName . $this->_sourceURI . $type; - - $db = clone($GLOBALS['egw']->db); - - $cols = array('map_guid'); - - $where = array - ( - 'map_id' => $mapID, - 'map_locuid' => $locid - ); - - $db->select('egw_contentmap', $cols, $where, __LINE__, __FILE__); - - if(!$db->next_record()) - { - Horde::logMessage("SyncML: state->removeUID(type=$type,locid=$locid) : nothing to remove", __FILE__, __LINE__, PEAR_LOG_DEBUG); - return false; - } - - $guid = $db->f('map_guid'); + /** + * Removes all locid<->guid mappings for the given type. + * Returns always true. + */ + function removeAllUID($type) + { + $mapID = $this->_locName . $this->_sourceURI . $type; + + $db = clone($GLOBALS['egw']->db); + + $cols = array('map_guid'); + + $where = array ( + 'map_id' => $mapID + ); + + Horde::logMessage("SyncML: state->removeAllUID(type=$type)", __FILE__, __LINE__, PEAR_LOG_DEBUG); + + $db->delete('egw_contentmap', $where, __LINE__, __FILE__); + + return true; + } - #Horde::logMessage("SyncML: state->removeUID(type=$type,locid=$locid) : removing guid:$guid", __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $db->delete('egw_contentmap', $where, __LINE__, __FILE__); - - return $guid; - } + /** + * Removes the locid<->guid mapping for the given locid. Returns + * the guid that was removed or false if no mapping entry was + * found. + */ + function removeUID($type, $locid) + { + $mapID = $this->_locName . $this->_sourceURI . $type; + + $db = clone($GLOBALS['egw']->db); + + $cols = array('map_guid'); + + $where = array ( + 'map_id' => $mapID, + 'map_locuid' => $locid + ); + + $db->select('egw_contentmap', $cols, $where, __LINE__, __FILE__); + + if(!$db->next_record()) { + Horde::logMessage("SyncML: state->removeUID(type=$type,locid=$locid) : nothing to remove", __FILE__, __LINE__, PEAR_LOG_INFO); + return false; + } + + $guid = $db->f('map_guid'); + + Horde::logMessage("SyncML: state->removeUID(type=$type,locid=$locid) : removing guid:$guid", __FILE__, __LINE__, PEAR_LOG_DEBUG); + + $db->delete('egw_contentmap', $where, __LINE__, __FILE__); + + return $guid; + } /** * Puts a given client $locid and Horde server $guid pair into the @@ -334,39 +367,72 @@ class EGW_SyncML_State extends Horde_SyncML_State } - /** - * write clients device info to database - */ - function writeClientDeviceInfo() - { - if (!isset($this->_clientDeviceInfo) || !is_array($this->_clientDeviceInfo)) { - return false; - } + /** + * writes clients deviceinfo into database + */ + function writeClientDeviceInfo() { + if (!isset($this->_clientDeviceInfo) || !is_array($this->_clientDeviceInfo)) { + return false; + } + + $db = clone($GLOBALS['egw']->db); + + $cols = array( + 'dev_id', + ); + + $softwareVersion = !empty($this->_clientDeviceInfo['softwareVersion']) ? $this->_clientDeviceInfo['softwareVersion'] : ''; + $hardwareVersion = !empty($this->_clientDeviceInfo['hardwareVersion']) ? $this->_clientDeviceInfo['hardwareVersion'] : ''; + $firmwareVersion = !empty($this->_clientDeviceInfo['firmwareVersion']) ? $this->_clientDeviceInfo['firmwareVersion'] : ''; + + $where = array ( + 'dev_model' => $this->_clientDeviceInfo['model'], + 'dev_manufacturer' => $this->_clientDeviceInfo['manufacturer'], + 'dev_swversion' => $softwareVersion, + 'dev_hwversion' => $hardwareVersion, + 'dev_fwversion' => $firmwareVersion, + ); - $deviceID = $this->_locName . $this->_sourceURI; - - $data = array - ( - 'dev_id' => $deviceID, - 'dev_dtdversion' => $this->_clientDeviceInfo['DTDVersion'], - 'dev_numberofchanges' => $this->_clientDeviceInfo['supportNumberOfChanges'], - 'dev_largeobjs' => $this->_clientDeviceInfo['supportLargeObjs'], - 'dev_swversion' => $this->_clientDeviceInfo['softwareVersion'], - 'dev_oem' => $this->_clientDeviceInfo['oem'], - 'dev_model' => $this->_clientDeviceInfo['model'], - 'dev_manufacturer' => $this->_clientDeviceInfo['manufacturer'], - 'dev_devicetype' => $this->_clientDeviceInfo['deviceType'], - 'dev_deviceid' => $this->_clientDeviceInfo['deviceID'], - 'dev_datastore' => serialize($this->_clientDeviceInfo['dataStore']), - ); + $db->select('egw_syncmldevinfo', $cols, $where, __LINE__, __FILE__); + + if($db->next_record()) { + $deviceID = $db->f('dev_id'); - $where = array - ( - 'dev_id' => $deviceID, - ); - - $GLOBALS['egw']->db->insert('egw_syncmldevinfo', $data, $where, __LINE__, __FILE__); - } + $data = array ( + 'dev_datastore' => serialize($this->_clientDeviceInfo['dataStore']), + ); + + $db->update('egw_syncmldevinfo', $data, $where, __LINE__, __FILE__); + + } else { + $data = array ( + 'dev_dtdversion' => $this->_clientDeviceInfo['DTDVersion'], + 'dev_numberofchanges' => $this->_clientDeviceInfo['supportNumberOfChanges'] ? true : false, + 'dev_largeobjs' => $this->_clientDeviceInfo['supportLargeObjs'] ? true : false, + 'dev_utc' => $this->_clientDeviceInfo['UTC'] ? true : false, + 'dev_swversion' => $softwareVersion, + 'dev_hwversion' => $hardwareVersion, + 'dev_fwversion' => $firmwareVersion, + 'dev_oem' => $this->_clientDeviceInfo['oem'], + 'dev_model' => $this->_clientDeviceInfo['model'], + 'dev_manufacturer' => $this->_clientDeviceInfo['manufacturer'], + 'dev_devicetype' => $this->_clientDeviceInfo['deviceType'], + 'dev_datastore' => serialize($this->_clientDeviceInfo['dataStore']), + ); + + $db->insert('egw_syncmldevinfo', $data, $where, __LINE__, __FILE__); + + $deviceID = $db->get_last_insert_id('egw_syncmldevinfo', 'dev_id'); + } + + $where = $data = array ( + 'owner_locname' => $this->_locName, + 'owner_deviceid' => $this->_sourceURI, + 'owner_devid' => $deviceID, + ); + + $db->insert('egw_syncmldeviceowner', $data, $where, __LINE__, __FILE__); + } /** * After a successful sync, the client and server's Next Anchors diff --git a/phpgwapi/inc/horde/Horde/SyncML/Sync/SlowSync.php b/phpgwapi/inc/horde/Horde/SyncML/Sync/SlowSync.php index 5bbbb1ecd7..77d89db804 100644 --- a/phpgwapi/inc/horde/Horde/SyncML/Sync/SlowSync.php +++ b/phpgwapi/inc/horde/Horde/SyncML/Sync/SlowSync.php @@ -19,7 +19,7 @@ include_once 'Horde/SyncML/Sync/TwoWaySync.php'; * @package Horde_SyncML */ class Horde_SyncML_Sync_SlowSync extends Horde_SyncML_Sync_TwoWaySync { - function handleSync($currentCmdID, $hordeType, $syncType,&$output, $refts) { + function handleSync($currentCmdID, $hordeType, $syncType, &$output, $refts) { global $registry; $history = $GLOBALS['egw']->contenthistory; @@ -33,23 +33,11 @@ class Horde_SyncML_Sync_SlowSync extends Horde_SyncML_Sync_TwoWaySync { if(is_array($adds)) { while($guid = array_shift($adds)) { - #$guid_ts = max($history->getTSforAction($guid, 'add'),$history->getTSforAction($guid, 'modify')); - $sync_ts = $state->getChangeTS($syncType, $guid); - #Horde::logMessage("SyncML: slowsync timestamp add: $guid sync_ts: $sync_ts anchorNext: ". $serverAnchorNext.' / '.time(), __FILE__, __LINE__, PEAR_LOG_DEBUG); - // $sync_ts it got synced from client to server someone - // $sync_ts >= $serverAnchorNext it got synced from client to server in this sync package already - if ($sync_ts && $sync_ts >= $serverAnchorNext) { - // Change was done by us upon request of client. - // Don't mirror that back to the client. - //Horde::logMessage("SyncML: slowsync add: $guid ignored, came from client", __FILE__, __LINE__, PEAR_LOG_DEBUG); + if ($locID = $state->getLocID($syncType, $guid)) { + Horde::logMessage("SyncML: slowsync add to client: $guid ignored, already at client($locID)", __FILE__, __LINE__, PEAR_LOG_DEBUG); continue; } - #$locid = $state->getLocID($syncType, $guid); - - // Create an Add request for client. -# LK $contentType = $state->getPreferedContentTypeClient($syncType); - $contentType = $state->getPreferedContentTypeClient($this->_sourceLocURI); if(is_a($contentType, 'PEAR_Error')) { // Client did not sent devinfo @@ -60,9 +48,6 @@ class Horde_SyncML_Sync_SlowSync extends Horde_SyncML_Sync_TwoWaySync { $c = $registry->call($hordeType . '/export', array('guid' => $guid, 'contentType' => $contentType)); Horde::logMessage("SyncML: slowsync add to client $c", __FILE__, __LINE__, PEAR_LOG_DEBUG); if (!is_a($c, 'PEAR_Error')) { - // Item in history but not in database. Strange, but - // can happen. -#LK $cmd->setContent($state->convertServer2Client($c, $contentType)); $cmd->setContent($c); if($hordeType == 'sifcalendar' || $hordeType == 'sifcontacts' || $hordeType == 'siftasks') { $cmd->setContentFormat('b64'); @@ -74,7 +59,6 @@ class Horde_SyncML_Sync_SlowSync extends Horde_SyncML_Sync_TwoWaySync { $state->log('Server-Add'); // return if we have to much data - #Horde::logMessage("SyncML: ".' checking hordetype '.$hordeType , __FILE__, __LINE__, PEAR_LOG_DEBUG); if(++$counter >= MAX_ENTRIES && $hordeType != 'sifcalendar' && $hordeType != 'sifcontacts' && $hordeType != 'siftasks') { $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); return $currentCmdID; @@ -161,58 +145,30 @@ class Horde_SyncML_Sync_SlowSync extends Horde_SyncML_Sync_TwoWaySync { } $guid = false; - # if (is_a($command, 'Horde_SyncML_Command_Sync_Add')) { - # $guid = $registry->call($hordeType . '/import', - # array($state->convertClient2Server($syncItem->getContent(), $contentType), $contentType)); - # if (!is_a($guid, 'PEAR_Error')) { - # $ts = $history->getTSforAction($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); - # } else { - # $state->log("Client-AddFailure"); - # Horde::logMessage('SyncML: Error in adding client entry:' . $guid->message, __FILE__, __LINE__, PEAR_LOG_ERR); - # } - # } elseif (is_a($command, 'Horde_SyncML_Command_Sync_Replace')) { - #$guid = $state->getGlobalUID($type, $syncItem->getLocURI()); - $guid = $registry->call($hordeType . '/search', - array($state->convertClient2Server($syncItem->getContent(), $contentType), $contentType)); - Horde::logMessage('SyncML: found guid ' . $guid , __FILE__, __LINE__, PEAR_LOG_DEBUG); - $ok = false; - 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)); - if (!is_a($ok, 'PEAR_Error')) { - $ts = $history->getTSforAction($guid, 'modify'); - $state->setUID($type, $syncItem->getLocURI(), $guid, $ts); - #Horde::logMessage('SyncML: replaced entry due to client request guid: '. $guid .' LocURI: '. $syncItem->getLocURI() .' ts: '. $ts, __FILE__, __LINE__, PEAR_LOG_DEBUG); - $state->log("Client-Replace"); - $ok = true; - } else { - // Entry may have been deleted; try adding it. - $ok = false; - } - } - if (!$ok) { - // Entry does not exist in map or database: add a new - // one. - Horde::logMessage('SyncML: try to add contentype ' . $contentType .' to '. $hordeType, __FILE__, __LINE__, PEAR_LOG_DEBUG); - $guid = $registry->call($hordeType . '/import', - array($state->convertClient2Server($syncItem->getContent(), $contentType), $contentType)); - if (!is_a($guid, 'PEAR_Error')) { - $ts = $history->getTSforAction($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); - } else { - Horde::logMessage('SyncML: Error in replacing/add client entry:' . $guid->message, __FILE__, __LINE__, PEAR_LOG_ERR); - $state->log("Client-AddFailure"); - } + $guid = $registry->call($hordeType . '/search', + array($state->convertClient2Server($syncItem->getContent(), $contentType), $contentType)); + + if ($guid) { + # entry exists in database already. Just update the mapping + Horde::logMessage('SyncML: adding mapping for locuri:'. $syncItem->getLocURI() . ' and guid:' . $guid , __FILE__, __LINE__, PEAR_LOG_DEBUG); + $state->setUID($type, $syncItem->getLocURI(), $guid, mktime()); + $state->log("Client-Replace"); + } else { + # Entry does not exist in database: add a new one. + Horde::logMessage('SyncML: try to add contentype ' . $contentType .' to '. $hordeType, __FILE__, __LINE__, PEAR_LOG_DEBUG); + $guid = $registry->call($hordeType . '/import', + array($state->convertClient2Server($syncItem->getContent(), $contentType), $contentType)); + if (!is_a($guid, 'PEAR_Error')) { + $ts = $history->getTSforAction($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); + } else { + Horde::logMessage('SyncML: Error in replacing/add client entry:' . $guid->message, __FILE__, __LINE__, PEAR_LOG_ERR); + $state->log("Client-AddFailure"); } - # } + } } return true; diff --git a/phpgwapi/inc/horde/Horde/SyncML/Sync/TwoWaySync.php b/phpgwapi/inc/horde/Horde/SyncML/Sync/TwoWaySync.php index 47ec42f698..47c78574b4 100644 --- a/phpgwapi/inc/horde/Horde/SyncML/Sync/TwoWaySync.php +++ b/phpgwapi/inc/horde/Horde/SyncML/Sync/TwoWaySync.php @@ -19,6 +19,7 @@ include_once 'Horde/SyncML/Command/Sync/ContentSyncElement.php'; * @package Horde_SyncML */ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync { + function endSync($currentCmdID, &$output) { global $registry; @@ -35,12 +36,12 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync { $output, $refts); - if ($syncType == 'calendar' && $state->handleTasksInCalendar()) { - Horde::logMessage("SyncML: handling tasks in calendar sync", __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $currentCmdID = $this->handleSync($currentCmdID, 'tasks', $syncType, - $output, $refts); - } + #if ($syncType == 'calendar' && $state->handleTasksInCalendar()) { + # Horde::logMessage("SyncML: handling tasks in calendar sync", __FILE__, __LINE__, PEAR_LOG_DEBUG); + # + # $currentCmdID = $this->handleSync($currentCmdID, 'tasks', $syncType, + # $output, $refts); + #} return $currentCmdID; } @@ -163,92 +164,90 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync { } if(is_array($adds)) { - while($guid = array_shift($adds)) { - $guid_ts = $history->getTSforAction($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) { - // Change was done by us upon request of client. - // Don't mirror that back to the client. - Horde::logMessage("SyncML: add: $guid ignored, came from client", __FILE__, __LINE__, PEAR_LOG_DEBUG); - continue; - } - - $locid = $state->getLocID($syncType, $guid); - - if ($locid && $refts == 0) { - // For slow sync (ts=0): do not add data for which we - // have a locid again. This is a heuristic to avoid - // duplication of entries. - Horde::logMessage("SyncML: skipping add of guid $guid as there already is a locid $locid", __FILE__, __LINE__, PEAR_LOG_DEBUG); - continue; - } - Horde::logMessage("SyncML: add: $guid", __FILE__, __LINE__, PEAR_LOG_DEBUG); - - // Create an Add request for client. - $contentType = $state->getPreferedContentTypeClient($this->_sourceLocURI); - if(is_a($contentType, 'PEAR_Error')) { - // Client did not sent devinfo - $contentType = array('ContentType' => $state->getPreferedContentType($this->_targetLocURI)); - } - - $cmd = &new Horde_SyncML_Command_Sync_ContentSyncElement(); - $c = $registry->call($hordeType . '/export', - array( - 'guid' => $guid , - 'contentType' => $contentType , - ) - ); - - if (!is_a($c, 'PEAR_Error')) { - // Item in history but not in database. Strange, but can happen. - $cmd->setContent($c); - if($hordeType == 'sifcalendar' || $hordeType == 'sifcontacts' || $hordeType == 'siftasks') { - $cmd->setContentFormat('b64'); + while($guid = array_shift($adds)) { + $guid_ts = $history->getTSforAction($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) { + // Change was done by us upon request of client. + // Don't mirror that back to the client. + Horde::logMessage("SyncML: add: $guid ignored, came from client", __FILE__, __LINE__, PEAR_LOG_DEBUG); + continue; } - $cmd->setContentType($contentType['ContentType']); - $cmd->setSourceURI($guid); - $currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Add'); - $state->log('Server-Add'); - // return if we have to much data - if(++$counter >= MAX_ENTRIES && $hordeType != 'sifcalendar' && $hordeType != 'sifcontacts' &&$hordeType != 'siftasks') { - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; + $locid = $state->getLocID($syncType, $guid); + + if ($locid && $refts == 0) { + // For slow sync (ts=0): do not add data for which we + // have a locid again. This is a heuristic to avoid + // duplication of entries. + Horde::logMessage("SyncML: skipping add of guid $guid as there already is a locid $locid", __FILE__, __LINE__, PEAR_LOG_DEBUG); + continue; + } + Horde::logMessage("SyncML: add: $guid", __FILE__, __LINE__, PEAR_LOG_DEBUG); + + // Create an Add request for client. + $contentType = $state->getPreferedContentTypeClient($this->_sourceLocURI); + if(is_a($contentType, 'PEAR_Error')) { + // Client did not sent devinfo + $contentType = array('ContentType' => $state->getPreferedContentType($this->_targetLocURI)); + } + + $cmd = &new Horde_SyncML_Command_Sync_ContentSyncElement(); + $c = $registry->call($hordeType . '/export', + array( + 'guid' => $guid , + 'contentType' => $contentType , + ) + ); + + if (!is_a($c, 'PEAR_Error')) { + // Item in history but not in database. Strange, but can happen. + $cmd->setContent($c); + if($hordeType == 'sifcalendar' || $hordeType == 'sifcontacts' || $hordeType == 'siftasks') { + $cmd->setContentFormat('b64'); + } + $cmd->setContentType($contentType['ContentType']); + $cmd->setSourceURI($guid); + $currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Add'); + $state->log('Server-Add'); + + // return if we have to much data + if(++$counter >= MAX_ENTRIES && $hordeType != 'sifcalendar' && $hordeType != 'sifcontacts' &&$hordeType != 'siftasks') { + $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); + return $currentCmdID; + } } } } - } - Horde::logMessage("SyncML: handling sync ".$currentCmdID, __FILE__, __LINE__, PEAR_LOG_DEBUG); + #Horde::logMessage("SyncML: handling sync ".$currentCmdID, __FILE__, __LINE__, PEAR_LOG_DEBUG); $state->clearSync($syncType); return $currentCmdID; } - - function loadData() - { - global $registry; - - $state = &$_SESSION['SyncML.state']; - $syncType = $this->_targetLocURI; - $hordeType = str_replace('./','',$syncType); - $refts = $state->getServerAnchorLast($syncType); - Horde::logMessage("SyncML: reading changed items from database for $hordeType", __FILE__, __LINE__, PEAR_LOG_DEBUG); - $state->setChangedItems($hordeType, $registry->call($hordeType. '/listBy', array('action' => 'modify', 'timestamp' => $refts))); - - Horde::logMessage("SyncML: reading deleted items from database for $hordeType", __FILE__, __LINE__, PEAR_LOG_DEBUG); - $state->setDeletedItems($hordeType, $registry->call($hordeType. '/listBy', array('action' => 'delete', 'timestamp' => $refts))); - - Horde::logMessage("SyncML: reading added items from database for $hordeType", __FILE__, __LINE__, PEAR_LOG_DEBUG); - $state->setAddedItems($hordeType, $registry->call($hordeType. '/listBy', array('action' => 'add', 'timestamp' => $refts))); - - $this->_syncDataLoaded = TRUE; - - return count($state->getChangedItems($hordeType)) + - count($state->getDeletedItems($hordeType)) + - count($state->getAddedItems($hordeType)); - } - + function loadData() { + global $registry; + + $state = &$_SESSION['SyncML.state']; + $syncType = $this->_targetLocURI; + $hordeType = str_replace('./','',$syncType); + $refts = $state->getServerAnchorLast($syncType); + + Horde::logMessage("SyncML: reading changed items from database for $hordeType", __FILE__, __LINE__, PEAR_LOG_DEBUG); + $state->setChangedItems($hordeType, $registry->call($hordeType. '/listBy', array('action' => 'modify', 'timestamp' => $refts))); + + Horde::logMessage("SyncML: reading deleted items from database for $hordeType", __FILE__, __LINE__, PEAR_LOG_DEBUG); + $state->setDeletedItems($hordeType, $registry->call($hordeType. '/listBy', array('action' => 'delete', 'timestamp' => $refts))); + + Horde::logMessage("SyncML: reading added items from database for $hordeType", __FILE__, __LINE__, PEAR_LOG_DEBUG); + $state->setAddedItems($hordeType, $registry->call($hordeType. '/listBy', array('action' => 'add', 'timestamp' => $refts))); + + $this->_syncDataLoaded = TRUE; + + return count($state->getChangedItems($hordeType)) + + count($state->getDeletedItems($hordeType)) + + count($state->getAddedItems($hordeType)); + } }