forked from extern/egroupware
support for slowsync with search
added real working state machine SyncML conformance improvment
This commit is contained in:
parent
e15d167c87
commit
2dedbf0f7c
@ -127,8 +127,8 @@ class Horde_RPC_syncml extends Horde_RPC {
|
|||||||
$xml, $m)) {
|
$xml, $m)) {
|
||||||
$this->_charset = $m[1];
|
$this->_charset = $m[1];
|
||||||
}
|
}
|
||||||
NLS::setCharset($this->_charset);
|
#NLS::setCharset($this->_charset);
|
||||||
String::setDefaultCharset($this->_charset);
|
#String::setDefaultCharset($this->_charset);
|
||||||
|
|
||||||
/* Create the XML parser and set method references. */
|
/* Create the XML parser and set method references. */
|
||||||
$this->_parser = xml_parser_create_ns($this->_charset);
|
$this->_parser = xml_parser_create_ns($this->_charset);
|
||||||
|
@ -155,19 +155,25 @@ class Horde_SyncML_SyncMLHdr extends Horde_SyncML_ContentHandler {
|
|||||||
|
|
||||||
// It would seem multisync does not send the user name once it
|
// It would seem multisync does not send the user name once it
|
||||||
// has been authorized. Make sure we have a valid session id.
|
// has been authorized. Make sure we have a valid session id.
|
||||||
session_id('syncml' . preg_replace('/[^a-zA-Z0-9]/', '', $sourceURI . $sessionID));
|
if(!empty($_GET['syncml_sessionid'])) {
|
||||||
|
session_id($_GET['syncml_sessionid']);
|
||||||
|
Horde::logMessage('SyncML['. session_id() .']: reusing existing session', __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||||
|
} else {
|
||||||
|
#session_id('syncml' . preg_replace('/[^a-zA-Z0-9]/', '', $sourceURI . $sessionID));
|
||||||
|
session_id('syncml-' . md5(uniqid(rand(), true)));
|
||||||
|
Horde::logMessage('SyncML['. session_id() .']: starting new session for '.$this->_locName, __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||||
|
}
|
||||||
@session_start();
|
@session_start();
|
||||||
Horde::logMessage('SyncML: session id = ' . session_id(), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
|
||||||
|
|
||||||
if (!isset($_SESSION['SyncML.state'])) {
|
if (!isset($_SESSION['SyncML.state'])) {
|
||||||
// Create a new state if one does not already exist.
|
// Create a new state if one does not already exist.
|
||||||
Horde::logMessage('SyncML: new session state', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
Horde::logMessage('SyncML['. session_id() .']: create new session state variable', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
# LK $_SESSION['SyncML.state'] = &new Horde_SyncML_State($sourceURI, $locName, $sessionID);
|
# LK $_SESSION['SyncML.state'] = &new Horde_SyncML_State($sourceURI, $locName, $sessionID);
|
||||||
$_SESSION['SyncML.state'] = &new EGW_SyncML_State($sourceURI, $locName, $sessionID);
|
$_SESSION['SyncML.state'] = &new EGW_SyncML_State($sourceURI, $locName, $sessionID);
|
||||||
}
|
}
|
||||||
if($_SESSION['SyncML.state']->_isAuthorized)
|
#if($_SESSION['SyncML.state']->_isAuthorized)
|
||||||
Horde::logMessage('SyncML: is session authorized', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
# Horde::logMessage('SyncML['. session_id() .']: is session authorized', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
return $_SESSION['SyncML.state'];
|
return $_SESSION['SyncML.state'];
|
||||||
}
|
}
|
||||||
@ -202,11 +208,13 @@ class Horde_SyncML_SyncMLHdr extends Horde_SyncML_ContentHandler {
|
|||||||
*/
|
*/
|
||||||
// </SyncHdr></SyncML>
|
// </SyncHdr></SyncML>
|
||||||
// Find the state.
|
// Find the state.
|
||||||
|
#Horde::logMessage('SymcML: SyncHdr done. Try to load state from session.', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
$state = $this->getStateFromSession($this->_sourceURI, $this->_locName, $this->_sessionID);
|
$state = $this->getStateFromSession($this->_sourceURI, $this->_locName, $this->_sessionID);
|
||||||
|
|
||||||
$state->setVersion($this->_version);
|
$state->setVersion($this->_version);
|
||||||
$state->setMsgID($this->_msgID);
|
$state->setMsgID($this->_msgID);
|
||||||
$state->setTargetURI($this->_targetURI);
|
$state->setTargetURI($this->_targetURI);
|
||||||
|
$state->setWBXML(is_a($this->_output, 'XML_WBXML_Encoder'));
|
||||||
if(isset($this->_credData) && isset($this->_locName) && !$state->isAuthorized())
|
if(isset($this->_credData) && isset($this->_locName) && !$state->isAuthorized())
|
||||||
{
|
{
|
||||||
$state->setPassword($this->_credData);
|
$state->setPassword($this->_credData);
|
||||||
@ -262,7 +270,7 @@ class Horde_SyncML_SyncMLHdr extends Horde_SyncML_ContentHandler {
|
|||||||
}
|
}
|
||||||
$this->_credData = $tmp[1];
|
$this->_credData = $tmp[1];
|
||||||
|
|
||||||
Horde::logMessage('SyncML: $this->_locName: ' . $this->_locName, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage('SyncML['. session_id() .']: $this->_locName: ' . $this->_locName, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -344,15 +352,16 @@ class Horde_SyncML_SyncMLHdr extends Horde_SyncML_ContentHandler {
|
|||||||
$output->endElement($uri, 'LocURI');
|
$output->endElement($uri, 'LocURI');
|
||||||
$output->endElement($uri, 'Source');
|
$output->endElement($uri, 'Source');
|
||||||
|
|
||||||
#if(!strpos($this->_targetURI,'syncit'))
|
if(session_id() != '') {
|
||||||
#{
|
$output->startElement($uri, 'RespURI', $attrs);
|
||||||
# $output->startElement($uri, 'RespURI', $attrs);
|
if($_SERVER['HTTPS'] == 'on') {
|
||||||
# $output->characters($this->_targetURI.'?syncid='.$GLOBALS['sessionid'].'-'.$GLOBALS['phpgw_info']['user']['kp3']);
|
$httpPrefix = 'https://';
|
||||||
# $output->characters($this->_targetURI.'?after=20040101T133000Z-syncid=lars');
|
} else {
|
||||||
# $output->characters($this->_targetURI.'?sincit=10');
|
$httpPrefix = 'http://';
|
||||||
# $output->characters('http://192.168.4.227/horde/rpc.php?after=20040101T133000Z-username=lars');
|
}
|
||||||
# $output->endElement($uri, 'RespURI');
|
$output->characters($httpPrefix . $_SERVER['SERVER_NAME'] .':'. $_SERVER['SERVER_PORT'] . $_SERVER['PHP_SELF'] . '?syncml_sessionid=' . session_id());
|
||||||
#}
|
$output->endElement($uri, 'RespURI');
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
$output->startElement($uri, 'Meta', $attrs);
|
$output->startElement($uri, 'Meta', $attrs);
|
||||||
@ -437,6 +446,7 @@ class Horde_SyncML_SyncMLBody extends Horde_SyncML_ContentHandler {
|
|||||||
$state = & $_SESSION['SyncML.state'];
|
$state = & $_SESSION['SyncML.state'];
|
||||||
|
|
||||||
$this->_actionCommands = false; // so far, we have not seen commands that require action from our side
|
$this->_actionCommands = false; // so far, we have not seen commands that require action from our side
|
||||||
|
$state->_sendFinal = false;
|
||||||
|
|
||||||
// <SyncML><SyncBody>
|
// <SyncML><SyncBody>
|
||||||
$this->_output->startElement($uri, $element, $attrs);
|
$this->_output->startElement($uri, $element, $attrs);
|
||||||
@ -477,7 +487,7 @@ class Horde_SyncML_SyncMLBody extends Horde_SyncML_ContentHandler {
|
|||||||
// We've got to do something! This can't be the last
|
// We've got to do something! This can't be the last
|
||||||
// packet.
|
// packet.
|
||||||
$this->_actionCommands = true;
|
$this->_actionCommands = true;
|
||||||
Horde::logMessage("SyncML: found action commands <$element> " . $this->_actionCommands, __FILE__, __LINE__, PEAR_LOG_INFO);
|
Horde::logMessage('SyncML['. session_id() ."]: found action commands <$element> " . $this->_actionCommands, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch($element)
|
switch($element)
|
||||||
@ -490,7 +500,7 @@ class Horde_SyncML_SyncMLBody extends Horde_SyncML_ContentHandler {
|
|||||||
# break;
|
# break;
|
||||||
case 'Sync':
|
case 'Sync':
|
||||||
$state->setSyncStatus(CLIENT_SYNC_STARTED);
|
$state->setSyncStatus(CLIENT_SYNC_STARTED);
|
||||||
Horde::logMessage('SyncML: syncStatus(client sync started) ' . $state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_INFO);
|
Horde::logMessage('SyncML['. session_id() .']: syncStatus(client sync started) ' . $state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -502,65 +512,92 @@ class Horde_SyncML_SyncMLBody extends Horde_SyncML_ContentHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function endElement($uri, $element)
|
function endElement($uri, $element) {
|
||||||
{
|
switch ($this->_xmlStack) {
|
||||||
switch ($this->_xmlStack) {
|
case 2:
|
||||||
case 2:
|
// </SyncBody></SyncML>
|
||||||
// </SyncBody></SyncML>
|
$state = & $_SESSION['SyncML.state'];
|
||||||
$state = & $_SESSION['SyncML.state'];
|
|
||||||
|
if($state->getSyncStatus() == CLIENT_SYNC_FINNISHED && $state->getAlert222Received() == true) {
|
||||||
// send the sync reply
|
$state->setSyncStatus(CLIENT_SYNC_ACKNOWLEDGED);
|
||||||
// we do still have some data to send OR
|
$state->setAlert222Received(false);
|
||||||
// we should reply to the Sync command
|
}
|
||||||
$sync = &new Horde_SyncML_Command_Sync();
|
|
||||||
$this->_currentCmdID = $sync->syncToClient($this->_currentCmdID, $this->_output);
|
// send the sync reply
|
||||||
|
// we do still have some data to send OR
|
||||||
// send the Final tag if possible
|
// we should reply to the Sync command
|
||||||
if($state->getSyncStatus() != SERVER_SYNC_DATA_PENDING && $state->getSyncStatus() != CLIENT_SYNC_STARTED)
|
if($state->getSyncStatus() >= CLIENT_SYNC_ACKNOWLEDGED && $state->getSyncStatus() < SERVER_SYNC_FINNISHED) {
|
||||||
{
|
Horde::logMessage('SyncML sending syncdata to client '. CLIENT_SYNC_ACKNOWLEDGED .'/'. SERVER_SYNC_FINNISHED .'/'. $state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||||
$final = &new Horde_SyncML_Command_Final();
|
$sync = &new Horde_SyncML_Command_Sync();
|
||||||
$this->_currentCmdID = $final->output($this->_currentCmdID, $this->_output);
|
$this->_currentCmdID = $sync->syncToClient($this->_currentCmdID, $this->_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_output->endElement($uri, $element);
|
// send the Final tag if possible
|
||||||
|
#if($state->getSyncStatus() != SERVER_SYNC_DATA_PENDING && $state->getSyncStatus() != CLIENT_SYNC_STARTED) {
|
||||||
Horde::logMessage('SyncML: syncStatus ' . $state->getSyncStatus() .'actionCommands: '.$this->_actionCommands, __FILE__, __LINE__, PEAR_LOG_INFO);
|
if($state->getSyncStatus() >= SERVER_SYNC_FINNISHED || $state->_sendFinal) {
|
||||||
if (!$this->_actionCommands && $state->getSyncStatus() == SERVER_SYNC_FINNISHED) {
|
$final = &new Horde_SyncML_Command_Final();
|
||||||
// this packet did not contain any real actions, just status and map.
|
$this->_currentCmdID = $final->output($this->_currentCmdID, $this->_output);
|
||||||
// This means, we're through! The session can be closed and
|
}
|
||||||
// the Anchors saved for the next Sync
|
|
||||||
$state = & $_SESSION['SyncML.state'];
|
$this->_output->endElement($uri, $element);
|
||||||
Horde::logMessage('SyncML: sync' . session_id() . ' completed successfully!', __FILE__, __LINE__, PEAR_LOG_INFO);
|
|
||||||
$state->writeSyncSummary();
|
Horde::logMessage('SyncML['. session_id() .']: syncStatus ' . $state->getSyncStatus() .'actionCommands: '.$this->_actionCommands, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
$log = $state->getLog();
|
|
||||||
$s="";
|
if (!$this->_actionCommands && $state->getSyncStatus() == SERVER_SYNC_FINNISHED) {
|
||||||
foreach($log as $k => $v) {
|
// this packet did not contain any real actions, just status and map.
|
||||||
$s .= " $k=$v";
|
// This means, we're through! The session can be closed and
|
||||||
}
|
// the Anchors saved for the next Sync
|
||||||
Horde::logMessage('SyncML: summary:' . $s, __FILE__, __LINE__, PEAR_LOG_INFO);
|
$state = & $_SESSION['SyncML.state'];
|
||||||
// session can be closed here!
|
Horde::logMessage('SyncML['. session_id() .']: sync' . session_id() . ' completed successfully!', __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||||
#session_unset();
|
$state->writeSyncSummary();
|
||||||
#session_destroy();
|
$log = $state->getLog();
|
||||||
}
|
$s="";
|
||||||
|
foreach($log as $k => $v) {
|
||||||
|
$s .= " $k=$v";
|
||||||
|
}
|
||||||
|
Horde::logMessage('SyncML['. session_id() .']: summary:' . $s, __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||||
|
# Horde::logMessage('SyncML['. session_id() .']: destroying sync session '.session_id(), __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||||
|
# // session can be closed here!
|
||||||
|
# session_unset();
|
||||||
|
# session_destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->_actionCommands && $state->getSyncStatus() == SERVER_SYNC_ACKNOWLEDGED) {
|
||||||
|
// this packet did not contain any real actions, just status and map.
|
||||||
|
// This means, we're through! The session can be closed and
|
||||||
|
// the Anchors saved for the next Sync
|
||||||
|
$state = & $_SESSION['SyncML.state'];
|
||||||
|
Horde::logMessage('SyncML['. session_id() .']: sync' . session_id() . ' completed successfully!', __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||||
|
$state->writeSyncSummary();
|
||||||
|
$log = $state->getLog();
|
||||||
|
$s="";
|
||||||
|
foreach($log as $k => $v) {
|
||||||
|
$s .= " $k=$v";
|
||||||
|
}
|
||||||
|
Horde::logMessage('SyncML['. session_id() .']: summary:' . $s, __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||||
|
|
||||||
if (!$this->_actionCommands && $state->getSyncStatus() == SERVER_SYNC_FINNISHED && $this->_clientSentFinal) {
|
Horde::logMessage('SyncML['. session_id() .']: destroying sync session '.session_id(), __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||||
Horde::logMessage('SyncML: destroying sync session '.session_id(), __FILE__, __LINE__, PEAR_LOG_INFO);
|
// session can be closed here!
|
||||||
// session can be closed here!
|
session_unset();
|
||||||
session_unset();
|
session_destroy();
|
||||||
session_destroy();
|
}
|
||||||
}
|
if($state->getSyncStatus() == CLIENT_SYNC_FINNISHED) {
|
||||||
break;
|
$state->setSyncStatus(CLIENT_SYNC_ACKNOWLEDGED);
|
||||||
|
Horde::logMessage('SyncML['. session_id() .']: syncStatus(client sync acknowledged) '.$state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
case 3:
|
}
|
||||||
// </[Command]></SyncBody></SyncML>
|
|
||||||
$state = & $_SESSION['SyncML.state'];
|
break;
|
||||||
|
|
||||||
// this should be moved to case 2:
|
case 3:
|
||||||
if($element == 'Final')
|
// </[Command]></SyncBody></SyncML>
|
||||||
{
|
$state = & $_SESSION['SyncML.state'];
|
||||||
// make sure that we request devinfo, if we not have them already
|
|
||||||
|
// this should be moved to case 2:
|
||||||
|
if($element == 'Final')
|
||||||
|
{
|
||||||
|
// make sure that we request devinfo, if we not have them already
|
||||||
|
|
||||||
if(!$state->getClientDeviceInfo())
|
/* if(!$state->getClientDeviceInfo())
|
||||||
{
|
{
|
||||||
$attrs = array();
|
$attrs = array();
|
||||||
$this->_output->startElement($state->getURI(), 'Get', $attrs);
|
$this->_output->startElement($state->getURI(), 'Get', $attrs);
|
||||||
@ -587,43 +624,49 @@ class Horde_SyncML_SyncMLBody extends Horde_SyncML_ContentHandler {
|
|||||||
$this->_output->endElement($state->getURI(), 'Item');
|
$this->_output->endElement($state->getURI(), 'Item');
|
||||||
|
|
||||||
$this->_output->endElement($state->getURI(), 'Get');
|
$this->_output->endElement($state->getURI(), 'Get');
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
$this->_currentCommand->endElement($uri, $element);
|
|
||||||
|
$this->_currentCommand->endElement($uri, $element);
|
||||||
|
|
||||||
|
switch($element) {
|
||||||
|
case 'Final':
|
||||||
|
if($state->getSyncStatus() == CLIENT_SYNC_STARTED) {
|
||||||
|
$state->setSyncStatus(CLIENT_SYNC_FINNISHED);
|
||||||
|
Horde::logMessage('SyncML['. session_id() .']: syncStatus(client sync finnished) ' . $state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($state->getSyncStatus() == SERVER_SYNC_FINNISHED) {
|
||||||
|
$state->setSyncStatus(SERVER_SYNC_ACKNOWLEDGED);
|
||||||
|
Horde::logMessage('SyncML['. session_id() .']: syncStatus(server sync acknowledged) ' . $state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_clientSentFinal = true;
|
||||||
|
#Horde::logMessage('SyncML['. session_id() .']: Sync _syncTag = '. $state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$this->_currentCmdID = $this->_currentCommand->output($this->_currentCmdID, $this->_output);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($this->_currentCommand);
|
||||||
|
break;
|
||||||
|
|
||||||
switch($element)
|
default:
|
||||||
{
|
// </...></[Command]></SyncBody></SyncML>
|
||||||
case 'Final':
|
$this->_currentCommand->endElement($uri, $element);
|
||||||
if($state->getSyncStatus() == CLIENT_SYNC_STARTED)
|
break;
|
||||||
{
|
}
|
||||||
$state->setSyncStatus(CLIENT_SYNC_FINNISHED);
|
|
||||||
Horde::logMessage('SyncML: syncStatus(client sync finnished) ' . $state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_INFO);
|
parent::endElement($uri, $element);
|
||||||
}
|
}
|
||||||
$this->_clientSentFinal = true;
|
|
||||||
Horde::logMessage('SyncML: Sync _syncTag = '. $state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_INFO);
|
function characters($str) {
|
||||||
break;
|
if (isset($this->_currentCommand)) {
|
||||||
default:
|
$this->_currentCommand->characters($str);
|
||||||
$this->_currentCmdID = $this->_currentCommand->output($this->_currentCmdID, $this->_output);
|
}
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
unset($this->_currentCommand);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// </...></[Command]></SyncBody></SyncML>
|
|
||||||
$this->_currentCommand->endElement($uri, $element);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
parent::endElement($uri, $element);
|
|
||||||
}
|
|
||||||
|
|
||||||
function characters($str)
|
|
||||||
{
|
|
||||||
if (isset($this->_currentCommand)) {
|
|
||||||
$this->_currentCommand->characters($str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -196,11 +196,29 @@ class Horde_SyncML_Command_Alert extends Horde_SyncML_Command {
|
|||||||
$output->endElement($state->getURI(), 'Item');
|
$output->endElement($state->getURI(), 'Item');
|
||||||
$output->endElement($state->getURI(), 'Alert');
|
$output->endElement($state->getURI(), 'Alert');
|
||||||
|
|
||||||
|
$state->_sendFinal = true;
|
||||||
|
|
||||||
$currentCmdID++;
|
$currentCmdID++;
|
||||||
}
|
}
|
||||||
}
|
} elseif ($this->_alert == ALERT_NEXT_MESSAGE) {
|
||||||
else
|
$status = &new Horde_SyncML_Command_Status(RESPONSE_OK, 'Alert');
|
||||||
{
|
$status->setCmdRef($this->_cmdID);
|
||||||
|
if ($this->_targetLocURI != null) {
|
||||||
|
$status->setTargetRef((isset($this->_targetLocURIParameters) ? $this->_targetLocURI.'?/'.$this->_targetLocURIParameters : $this->_targetLocURI));
|
||||||
|
}
|
||||||
|
if ($this->_sourceLocURI != null) {
|
||||||
|
$status->setSourceRef($this->_sourceLocURI);
|
||||||
|
}
|
||||||
|
$status->setItemSourceLocURI($this->_sourceLocURI);
|
||||||
|
$status->setItemTargetLocURI(isset($this->_targetLocURIParameters) ? $this->_targetLocURI.'?/'.$this->_targetLocURIParameters : $this->_targetLocURI);
|
||||||
|
$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 = &new Horde_SyncML_Command_Status(RESPONSE_OK, 'Alert');
|
||||||
$status->setCmdRef($this->_cmdID);
|
$status->setCmdRef($this->_cmdID);
|
||||||
if ($this->_sourceLocURI != null) {
|
if ($this->_sourceLocURI != null) {
|
||||||
|
@ -44,6 +44,10 @@ class Horde_SyncML_Command_Status extends Horde_SyncML_Command {
|
|||||||
|
|
||||||
var $_itemDataAnchorLast;
|
var $_itemDataAnchorLast;
|
||||||
|
|
||||||
|
var $_itemTargetLocURI;
|
||||||
|
|
||||||
|
var $_itemSourceLocURI;
|
||||||
|
|
||||||
function Horde_SyncML_Command_Status($response = null, $cmd = null)
|
function Horde_SyncML_Command_Status($response = null, $cmd = null)
|
||||||
{
|
{
|
||||||
if ($response != null) {
|
if ($response != null) {
|
||||||
@ -85,13 +89,6 @@ class Horde_SyncML_Command_Status extends Horde_SyncML_Command {
|
|||||||
$output->characters($chars);
|
$output->characters($chars);
|
||||||
$output->endElement($state->getURI(), 'Cmd');
|
$output->endElement($state->getURI(), 'Cmd');
|
||||||
|
|
||||||
if (isset($this->_sourceRef)) {
|
|
||||||
$output->startElement($state->getURI(), 'SourceRef', $attrs);
|
|
||||||
$chars = $this->_sourceRef;
|
|
||||||
$output->characters($chars);
|
|
||||||
$output->endElement($state->getURI(), 'SourceRef');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($this->_targetRef)) {
|
if (isset($this->_targetRef)) {
|
||||||
$output->startElement($state->getURI(), 'TargetRef', $attrs);
|
$output->startElement($state->getURI(), 'TargetRef', $attrs);
|
||||||
$chars = $this->_targetRef;
|
$chars = $this->_targetRef;
|
||||||
@ -99,6 +96,13 @@ class Horde_SyncML_Command_Status extends Horde_SyncML_Command {
|
|||||||
$output->endElement($state->getURI(), 'TargetRef');
|
$output->endElement($state->getURI(), 'TargetRef');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($this->_sourceRef)) {
|
||||||
|
$output->startElement($state->getURI(), 'SourceRef', $attrs);
|
||||||
|
$chars = $this->_sourceRef;
|
||||||
|
$output->characters($chars);
|
||||||
|
$output->endElement($state->getURI(), 'SourceRef');
|
||||||
|
}
|
||||||
|
|
||||||
// If we are responding to the SyncHdr and we are not
|
// If we are responding to the SyncHdr and we are not
|
||||||
// authorized then request basic authorization.
|
// authorized then request basic authorization.
|
||||||
//
|
//
|
||||||
@ -170,9 +174,61 @@ class Horde_SyncML_Command_Status extends Horde_SyncML_Command {
|
|||||||
$output->endElement($state->getURI(), 'Item');
|
$output->endElement($state->getURI(), 'Item');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($this->_itemTargetLocURI) && isset($this->_itemSourceLocURI)) {
|
||||||
|
$output->startElement($state->getURI(), 'Item', $attrs);
|
||||||
|
|
||||||
|
$output->startElement($state->getURI(), 'Target', $attrs);
|
||||||
|
$output->startElement($state->getURI(), 'LocURI', $attrs);
|
||||||
|
$output->characters($this->_itemTargetLocURI);
|
||||||
|
$output->endElement($state->getURI(), 'LocURI');
|
||||||
|
$output->endElement($state->getURI(), 'Target');
|
||||||
|
|
||||||
|
$output->startElement($state->getURI(), 'Source', $attrs);
|
||||||
|
$output->startElement($state->getURI(), 'LocURI', $attrs);
|
||||||
|
$output->characters($this->_itemSourceLocURI);
|
||||||
|
$output->endElement($state->getURI(), 'LocURI');
|
||||||
|
$output->endElement($state->getURI(), 'Source');
|
||||||
|
|
||||||
|
$output->endElement($state->getURI(), 'Item');
|
||||||
|
}
|
||||||
|
|
||||||
$output->endElement($state->getURI(), 'Status');
|
$output->endElement($state->getURI(), 'Status');
|
||||||
|
|
||||||
$currentCmdID++;
|
$currentCmdID++;
|
||||||
|
|
||||||
|
// moredata pending request them
|
||||||
|
/* if($this->_response == RESPONSE_CHUNKED_ITEM_ACCEPTED_AND_BUFFERED) {
|
||||||
|
$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);
|
||||||
|
$output->characters(ALERT_NEXT_MESSAGE);
|
||||||
|
$output->endElement($state->getURI(), 'Data');
|
||||||
|
|
||||||
|
if (isset($this->_itemTargetLocURI) && isset($this->_itemSourceLocURI)) {
|
||||||
|
$output->startElement($state->getURI(), 'Item', $attrs);
|
||||||
|
|
||||||
|
$output->startElement($state->getURI(), 'Target', $attrs);
|
||||||
|
$output->startElement($state->getURI(), 'LocURI', $attrs);
|
||||||
|
$output->characters($this->_itemTargetLocURI);
|
||||||
|
$output->endElement($state->getURI(), 'LocURI');
|
||||||
|
$output->endElement($state->getURI(), 'Target');
|
||||||
|
|
||||||
|
$output->startElement($state->getURI(), 'Source', $attrs);
|
||||||
|
$output->startElement($state->getURI(), 'LocURI', $attrs);
|
||||||
|
$output->characters($this->_itemSourceLocURI);
|
||||||
|
$output->endElement($state->getURI(), 'LocURI');
|
||||||
|
$output->endElement($state->getURI(), 'Source');
|
||||||
|
}
|
||||||
|
|
||||||
|
$output->endElement($state->getURI(), 'Alert');
|
||||||
|
|
||||||
|
$currentCmdID++;
|
||||||
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
return $currentCmdID;
|
return $currentCmdID;
|
||||||
@ -248,4 +304,23 @@ class Horde_SyncML_Command_Status extends Horde_SyncML_Command {
|
|||||||
$this->_itemDataAnchorLast = $itemDataAnchorLast;
|
$this->_itemDataAnchorLast = $itemDataAnchorLast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setter for property itemSourceLocURI.
|
||||||
|
*
|
||||||
|
* @param string $itemSourceLocURI New value of property itemSourceLocURI.
|
||||||
|
*/
|
||||||
|
function setItemSourceLocURI($itemSourceLocURI)
|
||||||
|
{
|
||||||
|
$this->_itemSourceLocURI = $itemSourceLocURI;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setter for property itemTargetLocURI.
|
||||||
|
*
|
||||||
|
* @param string $itemTargetLocURI New value of property itemTargetLocURI.
|
||||||
|
*/
|
||||||
|
function setItemTargetLocURI($itemTargetLocURI)
|
||||||
|
{
|
||||||
|
$this->_itemTargetLocURI = $itemTargetLocURI;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,46 +22,48 @@ include_once 'Horde/SyncML/Sync/OneWayFromServerSync.php';
|
|||||||
*/
|
*/
|
||||||
class Horde_SyncML_Command_Sync extends Horde_Syncml_Command {
|
class Horde_SyncML_Command_Sync extends Horde_Syncml_Command {
|
||||||
|
|
||||||
var $_isInSource;
|
var $_isInSource;
|
||||||
var $_currentSyncElement;
|
var $_currentSyncElement;
|
||||||
var $_syncElements = array();
|
var $_syncElements = array();
|
||||||
|
|
||||||
|
function output($currentCmdID, &$output) {
|
||||||
|
|
||||||
|
$state = &$_SESSION['SyncML.state'];
|
||||||
|
|
||||||
|
$attrs = array();
|
||||||
|
|
||||||
|
Horde::logMessage('SyncML: $this->_targetURI = ' . $this->_targetURI, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
|
$status = &new Horde_SyncML_Command_Status(RESPONSE_OK, 'Sync');
|
||||||
|
|
||||||
|
// $status->setState($state);
|
||||||
|
|
||||||
|
$status->setCmdRef($this->_cmdID);
|
||||||
|
|
||||||
|
if ($this->_targetURI != null) {
|
||||||
|
$status->setTargetRef((isset($this->_targetURIParameters) ? $this->_targetURI.'?/'.$this->_targetURIParameters : $this->_targetURI));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->_sourceURI != null) {
|
||||||
|
$status->setSourceRef($this->_sourceURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentCmdID = $status->output($currentCmdID, $output);
|
||||||
|
|
||||||
|
if($sync = $state->getSync($this->_targetURI)) {
|
||||||
|
$currentCmdID = $sync->startSync($currentCmdID, $output);
|
||||||
|
|
||||||
|
foreach ($this->_syncElements as $element) {
|
||||||
|
$currentCmdID = $sync->nextSyncCommand($currentCmdID, $element, $output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function output($currentCmdID, &$output)
|
return $currentCmdID;
|
||||||
{
|
}
|
||||||
$state = &$_SESSION['SyncML.state'];
|
|
||||||
|
function getTargetURI() {
|
||||||
$attrs = array();
|
return $this->_targetURI;
|
||||||
|
}
|
||||||
Horde::logMessage('SyncML: $this->_targetURI = ' . $this->_targetURI, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
|
||||||
|
|
||||||
$status = &new Horde_SyncML_Command_Status(RESPONSE_OK, 'Sync');
|
|
||||||
// $status->setState($state);
|
|
||||||
$status->setCmdRef($this->_cmdID);
|
|
||||||
|
|
||||||
if ($this->_targetURI != null) {
|
|
||||||
$status->setTargetRef((isset($this->_targetURIParameters) ? $this->_targetURI.'?/'.$this->_targetURIParameters : $this->_targetURI));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->_sourceURI != null) {
|
|
||||||
$status->setSourceRef($this->_sourceURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
$currentCmdID = $status->output($currentCmdID, $output);
|
|
||||||
|
|
||||||
$sync = $state->getSync($this->_targetURI);
|
|
||||||
$currentCmdID = $sync->startSync($currentCmdID, $output);
|
|
||||||
|
|
||||||
foreach ($this->_syncElements as $element ) {
|
|
||||||
$currentCmdID = $sync->nextSyncCommand($currentCmdID, $element, $output);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $currentCmdID;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTargetURI()
|
|
||||||
{
|
|
||||||
return $this->_targetURI;
|
|
||||||
}
|
|
||||||
|
|
||||||
function startElement($uri, $element, $attrs)
|
function startElement($uri, $element, $attrs)
|
||||||
{
|
{
|
||||||
@ -96,7 +98,7 @@ class Horde_SyncML_Command_Sync extends Horde_Syncml_Command {
|
|||||||
Horde::logMessage('SyncML: starting sync to client', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
Horde::logMessage('SyncML: starting sync to client', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
$state = $_SESSION['SyncML.state'];
|
$state = $_SESSION['SyncML.state'];
|
||||||
if($state->getSyncStatus() == CLIENT_SYNC_FINNISHED || $state->getSyncStatus() == SERVER_SYNC_DATA_PENDING)
|
if($state->getSyncStatus() >= CLIENT_SYNC_ACKNOWLEDGED && $state->getSyncStatus() < SERVER_SYNC_FINNISHED)
|
||||||
{
|
{
|
||||||
$deviceInfo = $state->getClientDeviceInfo();
|
$deviceInfo = $state->getClientDeviceInfo();
|
||||||
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
|
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
|
||||||
|
@ -108,7 +108,7 @@ class Horde_SyncML_Command_Sync_ContentSyncElement extends Horde_SyncML_Command_
|
|||||||
|| isset($this->_locURI) || isset($this->targetURI)) {
|
|| isset($this->_locURI) || isset($this->targetURI)) {
|
||||||
$output->startElement($state->getURI(), 'Item', $attrs);
|
$output->startElement($state->getURI(), 'Item', $attrs);
|
||||||
// send only when sending adds
|
// send only when sending adds
|
||||||
if ($this->_locURI != null && strtolower($command) == 'add') {
|
if ($this->_locURI != null && (strtolower($command) == 'add')) {
|
||||||
$output->startElement($state->getURI(), 'Source', $attrs);
|
$output->startElement($state->getURI(), 'Source', $attrs);
|
||||||
$output->startElement($state->getURI(), 'LocURI', $attrs);
|
$output->startElement($state->getURI(), 'LocURI', $attrs);
|
||||||
$chars = substr($this->_locURI,0,39);
|
$chars = substr($this->_locURI,0,39);
|
||||||
|
@ -16,17 +16,18 @@ include_once 'Horde/SyncML/Command/Sync/SyncElement.php';
|
|||||||
* @package Horde_SyncML
|
* @package Horde_SyncML
|
||||||
*/
|
*/
|
||||||
class Horde_SyncML_Command_Sync_Replace extends Horde_SyncML_Command_Sync_SyncElement {
|
class Horde_SyncML_Command_Sync_Replace extends Horde_SyncML_Command_Sync_SyncElement {
|
||||||
|
function output($currentCmdID, &$output) {
|
||||||
function output($currentCmdID, &$output)
|
$status = &new Horde_SyncML_Command_Status($this->_status, 'Replace');
|
||||||
{
|
$status->setCmdRef($this->_cmdID);
|
||||||
$status = &new Horde_SyncML_Command_Status($this->_status, 'Replace');
|
|
||||||
$status->setCmdRef($this->_cmdID);
|
if (isset($this->_luid)) {
|
||||||
|
$status->setSourceRef($this->_luid);
|
||||||
if (isset($this->_luid)) {
|
}
|
||||||
$status->setSourceRef($this->_luid);
|
|
||||||
}
|
#$status->setItemSourceLocURI($this->_sourceLocURI);
|
||||||
|
#$status->setItemTargetLocURI(isset($this->_targetLocURIParameters) ? $this->_targetLocURI.'?/'.$this->_targetLocURIParameters : $this->_targetLocURI);
|
||||||
return $status->output($currentCmdID, $output);
|
|
||||||
}
|
return $status->output($currentCmdID, $output);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ include_once 'Horde/SyncML/Command.php';
|
|||||||
* $Horde: framework/SyncML/SyncML/Command/Sync/SyncElement.php,v 1.11 2004/07/02 19:24:44 chuck Exp $
|
* $Horde: framework/SyncML/SyncML/Command/Sync/SyncElement.php,v 1.11 2004/07/02 19:24:44 chuck Exp $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2004 Anthony Mills <amills@pyramid6.com>
|
* Copyright 2003-2004 Anthony Mills <amills@pyramid6.com>
|
||||||
|
* Copyright 2005-2006 Lars Kneschke <l.kneschke@metaways.de>
|
||||||
*
|
*
|
||||||
* See the enclosed file COPYING for license information (LGPL). If you
|
* See the enclosed file COPYING for license information (LGPL). If you
|
||||||
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
|
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
|
||||||
@ -17,75 +18,104 @@ include_once 'Horde/SyncML/Command.php';
|
|||||||
*/
|
*/
|
||||||
class Horde_SyncML_Command_Sync_SyncElement extends Horde_SyncML_Command {
|
class Horde_SyncML_Command_Sync_SyncElement extends Horde_SyncML_Command {
|
||||||
|
|
||||||
var $_luid;
|
var $_luid;
|
||||||
var $_guid;
|
var $_guid;
|
||||||
var $_isSource;
|
var $_isSource;
|
||||||
var $_content;
|
var $_content;
|
||||||
var $_contentType;
|
var $_contentType;
|
||||||
var $_status = RESPONSE_OK;
|
var $_status = RESPONSE_OK;
|
||||||
|
var $_items;
|
||||||
|
|
||||||
|
function &factory($command, $params = null) {
|
||||||
|
include_once 'Horde/SyncML/Command/Sync/SyncElementItem.php';
|
||||||
|
@include_once 'Horde/SyncML/Command/Sync/' . $command . '.php';
|
||||||
|
|
||||||
|
$class = 'Horde_SyncML_Command_Sync_' . $command;
|
||||||
|
|
||||||
|
if (class_exists($class)) {
|
||||||
|
#Horde::logMessage('SyncML: Class definition of ' . $class . ' found in SyncElement::factory.', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
return $element = &new $class($params);
|
||||||
|
} else {
|
||||||
|
Horde::logMessage('SyncML: Class definition of ' . $class . ' not found in SyncElement::factory.', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
require_once 'PEAR.php';
|
||||||
|
return PEAR::raiseError('Class definition of ' . $class . ' not found.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function &factory($command, $params = null)
|
function startElement($uri, $element, $attrs) {
|
||||||
{
|
parent::startElement($uri, $element, $attrs);
|
||||||
@include_once 'Horde/SyncML/Command/Sync/' . $command . '.php';
|
|
||||||
$class = 'Horde_SyncML_Command_Sync_' . $command;
|
switch ($this->_xmlStack) {
|
||||||
if (class_exists($class)) {
|
case 3:
|
||||||
#Horde::logMessage('SyncML: Class definition of ' . $class . ' found in SyncElement::factory.', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
if ($element == 'Source') {
|
||||||
return $element = &new $class($params);
|
$this->_isSource = true;
|
||||||
} else {
|
}
|
||||||
Horde::logMessage('SyncML: Class definition of ' . $class . ' not found in SyncElement::factory.', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
break;
|
||||||
require_once 'PEAR.php';
|
}
|
||||||
return PEAR::raiseError('Class definition of ' . $class . ' not found.');
|
}
|
||||||
}
|
|
||||||
}
|
function endElement($uri, $element) {
|
||||||
|
$search = array('/ *\n/','/ *$/m');
|
||||||
|
$replace = array('','');
|
||||||
|
|
||||||
|
switch ($this->_xmlStack) {
|
||||||
|
case 1:
|
||||||
|
// Need to add sync elements to the Sync method?
|
||||||
|
#error_log('total # of items: '.count($this->_items));
|
||||||
|
#error_log(print_r($this->_items[10], true));
|
||||||
|
break;
|
||||||
|
case 2;
|
||||||
|
if($element == 'Item') {
|
||||||
|
$item = new Horde_SyncML_Command_Sync_SyncElementItem();
|
||||||
|
|
||||||
function startElement($uri, $element, $attrs)
|
if($this->_luid) {
|
||||||
{
|
$item->setLocURI($this->_luid);
|
||||||
parent::startElement($uri, $element, $attrs);
|
$item->setContent($this->_content);
|
||||||
|
$item->setContentType($this->_contentType);
|
||||||
switch ($this->_xmlStack) {
|
|
||||||
case 3:
|
if($this->_contentSize)
|
||||||
if ($element == 'Source') {
|
$item->setContentType($this->_contentSize);
|
||||||
$this->_isSource = true;
|
if($this->_moreData)
|
||||||
}
|
$item->setMoreData($this->_moreData);
|
||||||
break;
|
|
||||||
}
|
$this->_items[$this->_luid] = $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
function endElement($uri, $element)
|
unset($this->_content);
|
||||||
{
|
unset($this->_contentSize);
|
||||||
$search = array('/ *\n/','/ *$/m');
|
unset($this->_luid);
|
||||||
$replace = array('','');
|
}
|
||||||
switch ($this->_xmlStack) {
|
break;
|
||||||
case 1:
|
case 3:
|
||||||
// Need to add sync elements to the Sync method?
|
if ($element == 'Source') {
|
||||||
break;
|
$this->_isSource = false;
|
||||||
|
} elseif ($element == 'Data') {
|
||||||
case 3:
|
$this->_content = $this->_chars;
|
||||||
if ($element == 'Source') {
|
} elseif ($element == 'MoreData') {
|
||||||
$this->_isSource = false;
|
$this->_moreData = TRUE;
|
||||||
} elseif ($element == 'Data') {
|
} elseif ($element == 'Type') {
|
||||||
$this->_content = $this->_chars;
|
if(empty($this->_contentType))
|
||||||
} elseif ($element == 'MoreData') {
|
$this->_contentType = trim($this->_chars);
|
||||||
$this->_moreData = TRUE;
|
}
|
||||||
} elseif ($element == 'Type') {
|
break;
|
||||||
if(!isset($this->_contentType))
|
|
||||||
$this->_contentType = trim($this->_chars);
|
case 4:
|
||||||
}
|
if ($element == 'LocURI' && $this->_isSource) {
|
||||||
break;
|
$this->_luid = trim($this->_chars);
|
||||||
|
} elseif ($element == 'Type') {
|
||||||
case 4:
|
$this->_contentType = trim($this->_chars);
|
||||||
if ($element == 'LocURI' && $this->_isSource) {
|
} elseif ($element == 'Size') {
|
||||||
$this->_luid = trim($this->_chars);
|
$this->_contentSize = trim($this->_chars);
|
||||||
} elseif ($element == 'Type') {
|
}
|
||||||
$this->_contentType = trim($this->_chars);
|
break;
|
||||||
} elseif ($element == 'Size') {
|
}
|
||||||
$this->_contentSize = trim($this->_chars);
|
|
||||||
}
|
parent::endElement($uri, $element);
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
function getSyncElementItems() {
|
||||||
parent::endElement($uri, $element);
|
return (array)$this->_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLocURI()
|
function getLocURI()
|
||||||
{
|
{
|
||||||
|
@ -126,8 +126,10 @@ define('NAME_SPACE_URI_DEVINF_1_1', 'syncml:devinf1.1');
|
|||||||
|
|
||||||
define('CLIENT_SYNC_STARTED', 1);
|
define('CLIENT_SYNC_STARTED', 1);
|
||||||
define('CLIENT_SYNC_FINNISHED', 2);
|
define('CLIENT_SYNC_FINNISHED', 2);
|
||||||
define('SERVER_SYNC_DATA_PENDING', 3);
|
define('CLIENT_SYNC_ACKNOWLEDGED', 3);
|
||||||
define('SERVER_SYNC_FINNISHED', 4);
|
define('SERVER_SYNC_DATA_PENDING', 4);
|
||||||
|
define('SERVER_SYNC_FINNISHED', 5);
|
||||||
|
define('SERVER_SYNC_ACKNOWLEDGED', 6);
|
||||||
|
|
||||||
define('MAX_DATA', 19);
|
define('MAX_DATA', 19);
|
||||||
define('MAX_ENTRIES', 10);
|
define('MAX_ENTRIES', 10);
|
||||||
@ -148,52 +150,55 @@ define('MAX_ENTRIES', 10);
|
|||||||
* @package Horde_SyncML
|
* @package Horde_SyncML
|
||||||
*/
|
*/
|
||||||
class Horde_SyncML_State {
|
class Horde_SyncML_State {
|
||||||
|
|
||||||
var $_sessionID;
|
var $_sessionID;
|
||||||
|
|
||||||
var $_verProto;
|
var $_verProto;
|
||||||
|
|
||||||
var $_msgID;
|
var $_msgID;
|
||||||
|
|
||||||
var $_targetURI;
|
var $_targetURI;
|
||||||
|
|
||||||
var $_sourceURI;
|
var $_sourceURI;
|
||||||
|
|
||||||
var $_version;
|
var $_version;
|
||||||
|
|
||||||
var $_locName;
|
var $_locName;
|
||||||
|
|
||||||
var $_password;
|
var $_password;
|
||||||
|
|
||||||
var $_isAuthorized;
|
var $_isAuthorized;
|
||||||
|
|
||||||
var $_uri;
|
var $_uri;
|
||||||
|
|
||||||
var $_uriMeta;
|
var $_uriMeta;
|
||||||
|
|
||||||
var $_syncs = array();
|
var $_syncs = array();
|
||||||
|
|
||||||
var $_clientAnchorNext = array(); // written to db after successful sync
|
var $_clientAnchorNext = array(); // written to db after successful sync
|
||||||
|
|
||||||
var $_serverAnchorLast = array();
|
var $_serverAnchorLast = array();
|
||||||
|
|
||||||
var $_serverAnchorNext = array(); // written to db after successful sync
|
var $_serverAnchorNext = array(); // written to db after successful sync
|
||||||
|
|
||||||
var $_clientDeviceInfo = array();
|
var $_clientDeviceInfo = array();
|
||||||
|
|
||||||
// array list of changed items, which need to be synced to the client
|
// array list of changed items, which need to be synced to the client
|
||||||
var $_changedItems;
|
var $_changedItems;
|
||||||
|
|
||||||
// array list of deleted items, which need to be synced to the client
|
// array list of deleted items, which need to be synced to the client
|
||||||
var $_deletedItems;
|
var $_deletedItems;
|
||||||
|
|
||||||
// array list of added items, which need to be synced to the client
|
// array list of added items, which need to be synced to the client
|
||||||
var $_addedItems;
|
var $_addedItems;
|
||||||
|
|
||||||
// bool flag that we need to more data
|
// bool flag that we need to more data
|
||||||
var $_syncStatus;
|
var $_syncStatus;
|
||||||
|
|
||||||
var $_log = array();
|
var $_log = array();
|
||||||
|
|
||||||
|
// stores if we received Alert 222 already
|
||||||
|
var $_receivedAlert222 = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance of Horde_SyncML_State.
|
* Creates a new instance of Horde_SyncML_State.
|
||||||
@ -465,11 +470,11 @@ class Horde_SyncML_State {
|
|||||||
* by a <SyncML xmlns="syncml:SYNCML1.1"> element. They require
|
* by a <SyncML xmlns="syncml:SYNCML1.1"> element. They require
|
||||||
* just <SyncML>. So don't use an ns for non wbxml devices.
|
* just <SyncML>. So don't use an ns for non wbxml devices.
|
||||||
*/
|
*/
|
||||||
# if ($this->isWBXML()) {
|
if ($this->isWBXML()) {
|
||||||
return $this->_uri;
|
return $this->_uri;
|
||||||
# } else {
|
} else {
|
||||||
# return '';
|
return '';
|
||||||
# }
|
}
|
||||||
}
|
}
|
||||||
function getURIMeta()
|
function getURIMeta()
|
||||||
{
|
{
|
||||||
@ -625,15 +630,42 @@ class Horde_SyncML_State {
|
|||||||
*/
|
*/
|
||||||
function getPreferedContentType($type)
|
function getPreferedContentType($type)
|
||||||
{
|
{
|
||||||
if ($type == 'contacts') {
|
# if ($type == 'contacts') {
|
||||||
return 'text/x-vcard';
|
# return 'text/x-vcard';
|
||||||
} elseif ($type == 'notes') {
|
# } elseif ($type == 'notes') {
|
||||||
return 'text/x-vnote';
|
# return 'text/x-vnote';
|
||||||
} elseif ($type == 'tasks') {
|
# } elseif ($type == 'tasks') {
|
||||||
return 'text/x-vcalendar';
|
# return 'text/x-vcalendar';
|
||||||
} elseif ($type == 'calendar') {
|
# } elseif ($type == 'calendar') {
|
||||||
return 'text/x-vcalendar';
|
# return 'text/x-vcalendar';
|
||||||
}
|
# }
|
||||||
|
switch($type) {
|
||||||
|
case 'contacts':
|
||||||
|
return 'text/x-vcard';
|
||||||
|
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;
|
||||||
|
|
||||||
|
case 'tasks':
|
||||||
|
return 'text/x-vcalendar';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'calendar':
|
||||||
|
return 'text/x-vcalendar';
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -889,4 +921,12 @@ class Horde_SyncML_State {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAlert222Received() {
|
||||||
|
return $this->_receivedAlert222;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setAlert222Received($_status) {
|
||||||
|
$this->_receivedAlert222 = (bool)$_status;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,13 +23,13 @@ class EGW_SyncML_State extends Horde_SyncML_State
|
|||||||
'map_guid' => $guid,
|
'map_guid' => $guid,
|
||||||
);
|
);
|
||||||
|
|
||||||
Horde::logMessage('SyncML: getChangeTS for ' . $mapID .' / '. $guid, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage('SyncML: getChangeTS for ' . $mapID .' / '. $guid, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
$db->select('egw_contentmap', $cols, $where, __LINE__, __FILE__);
|
$db->select('egw_contentmap', $cols, $where, __LINE__, __FILE__);
|
||||||
|
|
||||||
if($db->next_record())
|
if($db->next_record())
|
||||||
{
|
{
|
||||||
Horde::logMessage('SyncML: getChangeTS changets is ' . $db->from_timestamp($db->f('map_timestamp')), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage('SyncML: getChangeTS changets is ' . $db->from_timestamp($db->f('map_timestamp')), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
return $db->from_timestamp($db->f('map_timestamp'));
|
return $db->from_timestamp($db->f('map_timestamp'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ class EGW_SyncML_State extends Horde_SyncML_State
|
|||||||
{
|
{
|
||||||
$mapID = $this->_locName . $this->_sourceURI . $type;
|
$mapID = $this->_locName . $this->_sourceURI . $type;
|
||||||
|
|
||||||
Horde::logMessage('SyncML: search GlobalUID for ' . $mapID .' / '.$locid, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage('SyncML: search GlobalUID for ' . $mapID .' / '.$locid, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
$db = clone($GLOBALS['egw']->db);
|
$db = clone($GLOBALS['egw']->db);
|
||||||
|
|
||||||
@ -145,11 +145,12 @@ class EGW_SyncML_State extends Horde_SyncML_State
|
|||||||
'map_id' => $mapID,
|
'map_id' => $mapID,
|
||||||
'map_guid' => $guid
|
'map_guid' => $guid
|
||||||
);
|
);
|
||||||
|
Horde::logMessage('SyncML: search LocID for ' . $mapID .' / '.$guid, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
$db->select('egw_contentmap', $cols, $where, __LINE__, __FILE__);
|
$db->select('egw_contentmap', $cols, $where, __LINE__, __FILE__);
|
||||||
|
|
||||||
if($db->next_record())
|
if($db->next_record())
|
||||||
{
|
{
|
||||||
|
Horde::logMessage('SyncML: found LocID: '.$db->f('map_locuid'), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
return $db->f('map_locuid');
|
return $db->f('map_locuid');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,10 +181,10 @@ class EGW_SyncML_State extends Horde_SyncML_State
|
|||||||
|
|
||||||
$db->select('egw_syncmlsummary', $cols, $where, __LINE__, __FILE__);
|
$db->select('egw_syncmlsummary', $cols, $where, __LINE__, __FILE__);
|
||||||
|
|
||||||
Horde::logMessage("SyncML: get SYNCSummary for $deviceID", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage("SyncML: get SYNCSummary for $deviceID", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
if($db->next_record())
|
if($db->next_record())
|
||||||
{
|
{
|
||||||
Horde::logMessage("SyncML: get SYNCSummary for $deviceID serverts: ".$db->f('sync_serverts')." clients: ".$db->f('sync_clientts'), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage("SyncML: get SYNCSummary for $deviceID serverts: ".$db->f('sync_serverts')." clients: ".$db->f('sync_clientts'), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
$retData = array
|
$retData = array
|
||||||
(
|
(
|
||||||
'ClientAnchor' => $db->f('sync_clientts'),
|
'ClientAnchor' => $db->f('sync_clientts'),
|
||||||
@ -211,12 +212,12 @@ class EGW_SyncML_State extends Horde_SyncML_State
|
|||||||
$this->_locName .= '@'.$GLOBALS['phpgw_info']['server']['default_domain'];
|
$this->_locName .= '@'.$GLOBALS['phpgw_info']['server']['default_domain'];
|
||||||
}
|
}
|
||||||
|
|
||||||
Horde::logMessage('SyncML: Authenticate ' . $this->_locName . ' - ' . $this->_password, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage('SyncML: Authenticate ' . $this->_locName . ' - ' . $this->_password, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
if($GLOBALS['sessionid'] = $GLOBALS['egw']->session->create($this->_locName,$this->_password,'text','u'))
|
if($GLOBALS['sessionid'] = $GLOBALS['egw']->session->create($this->_locName,$this->_password,'text','u'))
|
||||||
{
|
{
|
||||||
$this->_isAuthorized = true;
|
$this->_isAuthorized = true;
|
||||||
Horde::logMessage('SyncML_EGW: Authentication of ' . $this->_locName . '/' . $GLOBALS['sessionid'] . ' succeded' , __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage('SyncML_EGW: Authentication of ' . $this->_locName . '/' . $GLOBALS['sessionid'] . ' succeded' , __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -264,7 +265,7 @@ class EGW_SyncML_State extends Horde_SyncML_State
|
|||||||
|
|
||||||
$guid = $db->f('map_guid');
|
$guid = $db->f('map_guid');
|
||||||
|
|
||||||
Horde::logMessage("SyncML: state->removeUID(type=$type,locid=$locid) : removing guid:$guid", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage("SyncML: state->removeUID(type=$type,locid=$locid) : removing guid:$guid", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
$db->delete('egw_contentmap', $where, __LINE__, __FILE__);
|
$db->delete('egw_contentmap', $where, __LINE__, __FILE__);
|
||||||
|
|
||||||
@ -295,7 +296,7 @@ class EGW_SyncML_State extends Horde_SyncML_State
|
|||||||
$ts = time();
|
$ts = time();
|
||||||
}
|
}
|
||||||
|
|
||||||
Horde::logMessage("SyncML: setUID $type, $locid, $guid, $ts ".count($guidParts), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage("SyncML: setUID $type, $locid, $guid, $ts ".count($guidParts), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
$db = clone($GLOBALS['egw']->db);
|
$db = clone($GLOBALS['egw']->db);
|
||||||
|
|
||||||
@ -312,9 +313,10 @@ class EGW_SyncML_State extends Horde_SyncML_State
|
|||||||
'map_expired' => 0,
|
'map_expired' => 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$db->delete('egw_contentmap', $where, __LINE__, __FILE__);
|
||||||
$db->insert('egw_contentmap', $data, $where, __LINE__, __FILE__);
|
$db->insert('egw_contentmap', $data, $where, __LINE__, __FILE__);
|
||||||
|
|
||||||
Horde::logMessage("SyncML: setUID $type, $locid, $guid, $ts $mapID", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage("SyncML: setUID $type, $locid, $guid, $ts $mapID", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,158 +85,146 @@ class Horde_SyncML_Sync {
|
|||||||
return $currentCmdID;
|
return $currentCmdID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Here's where the actual processing of a client-sent Sync
|
* Here's where the actual processing of a client-sent Sync
|
||||||
* Command takes place. Entries are added, deleted or replaced
|
* Command takes place. Entries are added, deleted or replaced
|
||||||
* from the server database by using Horde API (Registry) calls.
|
* from the server database by using Horde API (Registry) calls.
|
||||||
*/
|
*/
|
||||||
function runSyncCommand(&$command)
|
function runSyncCommand(&$command) {
|
||||||
{
|
#Horde::logMessage('SyncML: content type is ' . $command->getContentType() .' moreData '. $command->_moreData, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
Horde::logMessage('SyncML: content type is ' . $command->getContentType() .' moreData '. $command->_moreData, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
global $registry;
|
||||||
global $registry;
|
|
||||||
|
$history = $GLOBALS['egw']->contenthistory;
|
||||||
#require_once 'Horde/History.php';
|
|
||||||
#$history = &Horde_History::singleton();
|
$state = &$_SESSION['SyncML.state'];
|
||||||
$history = $GLOBALS['phpgw']->contenthistory;
|
|
||||||
|
if(isset($state->_moreData['luid'])) {
|
||||||
$state = &$_SESSION['SyncML.state'];
|
if(($command->_luid == $state->_moreData['luid'])) {
|
||||||
|
Horde::logMessage('SyncML: got next moreData chunk '.$command->getContent(), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
if(isset($state->_moreData['luid']))
|
$lastChunks = implode('',$state->_moreData['chunks']);
|
||||||
{
|
$command->_content = $lastChunks.$command->_content;
|
||||||
if(($command->_luid == $state->_moreData['luid']))
|
$stringlen1 = strlen($lastChunks);
|
||||||
{
|
$stringlen2 = strlen($command->_content);
|
||||||
$lastChunks = implode('',$state->_moreData['chunks']);
|
|
||||||
$command->_content = $lastChunks.$command->_content;
|
if(!$command->_moreData && strlen($command->_content) != $state->_moreData['contentSize']) {
|
||||||
$stringlen1 = strlen($lastChunks);
|
$command->_status = RESPONSE_SIZE_MISMATCH;
|
||||||
$stringlen2 = strlen($command->_content);
|
$state->_moreData = array();
|
||||||
|
|
||||||
if(!$command->_moreData &&
|
return;
|
||||||
strlen($command->_content)
|
} elseif(!$command->_moreData && strlen($command->_content) == $state->_moreData['contentSize']) {
|
||||||
!= $state->_moreData['contentSize']
|
$state->_moreData = array();
|
||||||
)
|
Horde::logMessage('SyncML: chunk ended successful type is ' . $command->getContentType() .' content is '. $command->getContent(), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
{
|
}
|
||||||
$command->_status = RESPONSE_SIZE_MISMATCH;
|
} else {
|
||||||
$state->_moreData = array();
|
// alert 223 needed too
|
||||||
|
#$command->_status = ALERT_NO_END_OF_DATA;
|
||||||
return;
|
|
||||||
}
|
$state->_moreData = array();
|
||||||
elseif(!$command->_moreData &&
|
|
||||||
strlen($command->_content)
|
return;
|
||||||
== $state->_moreData['contentSize']
|
}
|
||||||
)
|
}
|
||||||
{
|
|
||||||
$state->_moreData = array();
|
// don't add/replace the data currently, they are not yet complete
|
||||||
|
if($command->_moreData == TRUE) {
|
||||||
return;
|
$state->_moreData['chunks'][] = $command->_content;
|
||||||
}
|
$state->_moreData['luid'] = $command->_luid;
|
||||||
|
|
||||||
}
|
// gets only set with the first chunk of data
|
||||||
else
|
if(isset($command->_contentSize))
|
||||||
{
|
$state->_moreData['contentSize'] = $command->_contentSize;
|
||||||
// alert 223 needed too
|
|
||||||
#$command->_status = ALERT_NO_END_OF_DATA;
|
$command->_status = RESPONSE_CHUNKED_ITEM_ACCEPTED_AND_BUFFERED;
|
||||||
|
Horde::logMessage('SyncML: added moreData chunk '.$command->getContent(), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
$state->_moreData = array();
|
|
||||||
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
}
|
$hordeType = $type = $this->_targetLocURI;
|
||||||
|
// remove the './' from the beginning
|
||||||
// don't add/replace the data currently, they are not yet complete
|
$hordeType = str_replace('./','',$hordeType);
|
||||||
if($command->_moreData == TRUE)
|
if(!$contentType = $command->getContentType()) {
|
||||||
{
|
$contentType = $state->getPreferedContentType($type);
|
||||||
$state->_moreData['chunks'][] = $command->_content;
|
}
|
||||||
$state->_moreData['luid'] = $command->_luid;
|
|
||||||
|
if ($this->_targetLocURI == 'calendar' && strpos($command->getContent(), 'BEGIN:VTODO') !== false) {
|
||||||
// gets only set with the first chunk of data
|
$hordeType = 'tasks';
|
||||||
if(isset($command->_contentSize))
|
}
|
||||||
$state->_moreData['contentSize'] = $command->_contentSize;
|
|
||||||
|
|
||||||
$command->_status = RESPONSE_CHUNKED_ITEM_ACCEPTED_AND_BUFFERED;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$hordeType = $type = $this->_targetLocURI;
|
|
||||||
// remove the './' from the beginning
|
|
||||||
$hordeType = str_replace('./','',$hordeType);
|
|
||||||
if(!$contentType = $command->getContentType())
|
|
||||||
{
|
|
||||||
$contentType = $state->getPreferedContentType($type);
|
|
||||||
}
|
|
||||||
if ($this->_targetLocURI == 'calendar' && strpos($command->getContent(), 'BEGIN:VTODO') !== false) {
|
|
||||||
$hordeType = 'tasks';
|
|
||||||
}
|
|
||||||
|
|
||||||
$guid = false;
|
|
||||||
if (is_a($command, 'Horde_SyncML_Command_Sync_Add')) {
|
|
||||||
$guid = $registry->call($hordeType . '/import',
|
|
||||||
array($state->convertClient2Server($command->getContent(), $contentType), $contentType));
|
|
||||||
if (!is_a($guid, 'PEAR_Error')) {
|
|
||||||
$ts = $history->getTSforAction($guid, 'add');
|
|
||||||
$state->setUID($type, $command->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_Delete')) {
|
|
||||||
// We can't remove the mapping entry as we need to keep
|
|
||||||
// the timestamp information.
|
|
||||||
$guid = $state->removeUID($type, $command->getLocURI());
|
|
||||||
#$guid = $state->getGlobalUID($type, $command->getLocURI());
|
|
||||||
Horde::logMessage('SyncML: about to delete entry ' . $type .' / '. $guid . ' due to client request '.$command->getLocURI(), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
|
||||||
|
|
||||||
if (!is_a($guid, 'PEAR_Error') && $guid != false) {
|
|
||||||
$registry->call($hordeType . '/delete', array($guid));
|
|
||||||
#$ts = $history->getTSforAction($guid, 'delete');
|
|
||||||
#$state->setUID($type, $command->getLocURI(), $guid, $ts);
|
|
||||||
$state->log("Client-Delete");
|
|
||||||
Horde::logMessage('SyncML: deleted entry ' . $guid . ' due to client request', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
|
||||||
} else {
|
|
||||||
$state->log("Client-DeleteFailure");
|
|
||||||
Horde::logMessage('SyncML: Failure deleting client entry, maybe gone already on server. msg:'. $guid->message, __FILE__, __LINE__, PEAR_LOG_ERR);
|
|
||||||
}
|
|
||||||
} elseif (is_a($command, 'Horde_SyncML_Command_Sync_Replace')) {
|
|
||||||
$guid = $state->getGlobalUID($type, $command->getLocURI());
|
|
||||||
$ok = false;
|
|
||||||
if ($guid) {
|
|
||||||
Horde::logMessage('SyncML: locuri'. $command->getLocURI() . ' guid ' . $guid , __FILE__, __LINE__, PEAR_LOG_ERR);
|
|
||||||
// Entry exists: replace current one.
|
|
||||||
$ok = $registry->call($hordeType . '/replace',
|
|
||||||
array($guid, $state->convertClient2Server($command->getContent(), $contentType), $contentType));
|
|
||||||
if (!is_a($ok, 'PEAR_Error')) {
|
|
||||||
$ts = $history->getTSforAction($guid, 'modify');
|
|
||||||
$state->setUID($type, $command->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");
|
|
||||||
$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, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
|
||||||
$guid = $registry->call($hordeType . '/import',
|
|
||||||
array($state->convertClient2Server($command->getContent(), $contentType), $contentType));
|
|
||||||
if (!is_a($guid, 'PEAR_Error')) {
|
|
||||||
$ts = $history->getTSforAction($guid, 'add');
|
|
||||||
$state->setUID($type, $command->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 $guid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
$syncElementItems = $command->getSyncElementItems();
|
||||||
|
|
||||||
|
foreach($syncElementItems as $syncItem) {
|
||||||
|
|
||||||
|
$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_Delete')) {
|
||||||
|
// We can't remove the mapping entry as we need to keep
|
||||||
|
// the timestamp information.
|
||||||
|
$guid = $state->removeUID($type, $syncItem->getLocURI());
|
||||||
|
#$guid = $state->getGlobalUID($type, $syncItem->getLocURI());
|
||||||
|
Horde::logMessage('SyncML: about to delete entry ' . $type .' / '. $guid . ' due to client request '.$syncItem->getLocURI(), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
|
if (!is_a($guid, 'PEAR_Error') && $guid != false) {
|
||||||
|
$registry->call($hordeType . '/delete', array($guid));
|
||||||
|
#$ts = $history->getTSforAction($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);
|
||||||
|
} else {
|
||||||
|
$state->log("Client-DeleteFailure");
|
||||||
|
Horde::logMessage('SyncML: Failure deleting client entry, maybe gone already on server. msg:'. $guid->message, __FILE__, __LINE__, PEAR_LOG_ERR);
|
||||||
|
}
|
||||||
|
} elseif (is_a($command, 'Horde_SyncML_Command_Sync_Replace')) {
|
||||||
|
$guid = $state->getGlobalUID($type, $syncItem->getLocURI());
|
||||||
|
$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. ' 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, __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 $guid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,60 +36,190 @@ class Horde_SyncML_Sync_SlowSync extends Horde_SyncML_Sync_TwoWaySync {
|
|||||||
# $adds = &$state->getAddedItems($hordeType);
|
# $adds = &$state->getAddedItems($hordeType);
|
||||||
#}
|
#}
|
||||||
|
|
||||||
Horde::logMessage("SyncML: ".count($adds). ' added items found for '.$hordeType , __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage("SyncML: ".count($adds). ' added items found for '.$hordeType , __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
$serverAnchorNext = $state->getServerAnchorNext($syncType);
|
$serverAnchorNext = $state->getServerAnchorNext($syncType);
|
||||||
$counter = 0;
|
$counter = 0;
|
||||||
|
|
||||||
while($guid = array_shift($adds))
|
while($guid = array_shift($adds))
|
||||||
{
|
{
|
||||||
#$guid_ts = max($history->getTSforAction($guid, 'add'),$history->getTSforAction($guid, 'modify'));
|
#$guid_ts = max($history->getTSforAction($guid, 'add'),$history->getTSforAction($guid, 'modify'));
|
||||||
$sync_ts = $state->getChangeTS($syncType, $guid);
|
$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);
|
#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 it got synced from client to server someone
|
||||||
// $sync_ts >= $serverAnchorNext it got synced from client to server in this sync package already
|
// $sync_ts >= $serverAnchorNext it got synced from client to server in this sync package already
|
||||||
if ($sync_ts && $sync_ts >= $serverAnchorNext) {
|
if ($sync_ts && $sync_ts >= $serverAnchorNext) {
|
||||||
// Change was done by us upon request of client.
|
// Change was done by us upon request of client.
|
||||||
// Don't mirror that back to the client.
|
// Don't mirror that back to the client.
|
||||||
//Horde::logMessage("SyncML: slowsync add: $guid ignored, came from client", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
//Horde::logMessage("SyncML: slowsync add: $guid ignored, came from client", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
# $locid = $state->getLocID($syncType, $guid);
|
#$locid = $state->getLocID($syncType, $guid);
|
||||||
#
|
|
||||||
|
|
||||||
// Create an Add request for client.
|
// Create an Add request for client.
|
||||||
# LK $contentType = $state->getPreferedContentTypeClient($syncType);
|
# LK $contentType = $state->getPreferedContentTypeClient($syncType);
|
||||||
$contentType = $state->getPreferedContentTypeClient($this->_sourceLocURI);
|
|
||||||
|
|
||||||
$cmd = &new Horde_SyncML_Command_Sync_ContentSyncElement();
|
$contentType = $state->getPreferedContentTypeClient($this->_sourceLocURI);
|
||||||
$c = $registry->call($hordeType . '/export',
|
if(is_a($contentType, 'PEAR_Error')) {
|
||||||
array('guid' => $guid,
|
// Client did not sent devinfo
|
||||||
'contentType' => $contentType));
|
$contentType = array('ContentType' => $state->getPreferedContentType($this->_targetLocURI));
|
||||||
Horde::logMessage("SyncML: slowsync add to server $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);
|
|
||||||
$cmd->setContentType($contentType['ContentType']);
|
|
||||||
$cmd->setSourceURI($guid);
|
|
||||||
$currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Add');
|
|
||||||
$state->log('Server-Add');
|
|
||||||
|
|
||||||
// return if we have to much data
|
$cmd = &new Horde_SyncML_Command_Sync_ContentSyncElement();
|
||||||
if(++$counter >= MAX_ENTRIES)
|
$c = $registry->call($hordeType . '/export', array('guid' => $guid, 'contentType' => $contentType));
|
||||||
{
|
#Horde::logMessage("SyncML: slowsync add to server $c", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
|
if (!is_a($c, 'PEAR_Error')) {
|
||||||
return $currentCmdID;
|
// Item in history but not in database. Strange, but
|
||||||
}
|
// can happen.
|
||||||
}
|
#LK $cmd->setContent($state->convertServer2Client($c, $contentType));
|
||||||
}
|
$cmd->setContent($c);
|
||||||
Horde::logMessage("SyncML: handling sync ".$currentCmdID, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
$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)
|
||||||
|
{
|
||||||
|
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
|
||||||
|
return $currentCmdID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#Horde::logMessage("SyncML: handling sync ".$currentCmdID, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
$state->clearSync($syncType);
|
$state->clearSync($syncType);
|
||||||
|
|
||||||
return $currentCmdID;
|
return $currentCmdID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Here's where the actual processing of a client-sent Sync
|
||||||
|
* Command takes place. Entries are added or replaced
|
||||||
|
* from the server database by using Horde API (Registry) calls.
|
||||||
|
*/
|
||||||
|
function runSyncCommand(&$command) {
|
||||||
|
#Horde::logMessage('SyncML: content type is ' . $command->getContentType() .' moreData '. $command->_moreData, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
global $registry;
|
||||||
|
|
||||||
|
$history = $GLOBALS['egw']->contenthistory;
|
||||||
|
|
||||||
|
$state = &$_SESSION['SyncML.state'];
|
||||||
|
|
||||||
|
if(isset($state->_moreData['luid'])) {
|
||||||
|
if(($command->_luid == $state->_moreData['luid'])) {
|
||||||
|
Horde::logMessage('SyncML: got next moreData chunk '.$command->getContent(), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
$lastChunks = implode('',$state->_moreData['chunks']);
|
||||||
|
$command->_content = $lastChunks.$command->_content;
|
||||||
|
$stringlen1 = strlen($lastChunks);
|
||||||
|
$stringlen2 = strlen($command->_content);
|
||||||
|
|
||||||
|
if(!$command->_moreData && strlen($command->_content) != $state->_moreData['contentSize']) {
|
||||||
|
$command->_status = RESPONSE_SIZE_MISMATCH;
|
||||||
|
$state->_moreData = array();
|
||||||
|
|
||||||
|
return;
|
||||||
|
} elseif(!$command->_moreData && strlen($command->_content) == $state->_moreData['contentSize']) {
|
||||||
|
$state->_moreData = array();
|
||||||
|
Horde::logMessage('SyncML: chunk ended successful type is ' . $command->getContentType() .' content is '. $command->getContent(), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// alert 223 needed too
|
||||||
|
#$command->_status = ALERT_NO_END_OF_DATA;
|
||||||
|
|
||||||
|
$state->_moreData = array();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't add/replace the data currently, they are not yet complete
|
||||||
|
if($command->_moreData == TRUE) {
|
||||||
|
$state->_moreData['chunks'][] = $command->_content;
|
||||||
|
$state->_moreData['luid'] = $command->_luid;
|
||||||
|
|
||||||
|
// gets only set with the first chunk of data
|
||||||
|
if(isset($command->_contentSize))
|
||||||
|
$state->_moreData['contentSize'] = $command->_contentSize;
|
||||||
|
|
||||||
|
$command->_status = RESPONSE_CHUNKED_ITEM_ACCEPTED_AND_BUFFERED;
|
||||||
|
Horde::logMessage('SyncML: added moreData chunk '.$command->getContent(), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hordeType = $type = $this->_targetLocURI;
|
||||||
|
// remove the './' from the beginning
|
||||||
|
$hordeType = str_replace('./','',$hordeType);
|
||||||
|
|
||||||
|
$syncElementItems = $command->getSyncElementItems();
|
||||||
|
|
||||||
|
foreach($syncElementItems as $syncItem) {
|
||||||
|
if(!$contentType = $syncItem->getContentType()) {
|
||||||
|
$contentType = $state->getPreferedContentType($type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->_targetLocURI == 'calendar' && strpos($syncItem->getContent(), 'BEGIN:VTODO') !== false) {
|
||||||
|
$hordeType = 'tasks';
|
||||||
|
}
|
||||||
|
|
||||||
|
$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));
|
||||||
|
$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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# }
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function loadData()
|
function loadData()
|
||||||
{
|
{
|
||||||
@ -99,7 +229,7 @@ class Horde_SyncML_Sync_SlowSync extends Horde_SyncML_Sync_TwoWaySync {
|
|||||||
$syncType = $this->_targetLocURI;
|
$syncType = $this->_targetLocURI;
|
||||||
$hordeType = str_replace('./','',$syncType);
|
$hordeType = str_replace('./','',$syncType);
|
||||||
|
|
||||||
Horde::logMessage("SyncML: reading added items from database for $hordeType", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage("SyncML: reading added items from database for $hordeType", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
$state->setAddedItems($hordeType, $registry->call($hordeType. '/list', array()));
|
$state->setAddedItems($hordeType, $registry->call($hordeType. '/list', array()));
|
||||||
$adds = &$state->getAddedItems($hordeType);
|
$adds = &$state->getAddedItems($hordeType);
|
||||||
$this->_syncDataLoaded = TRUE;
|
$this->_syncDataLoaded = TRUE;
|
||||||
|
@ -45,74 +45,71 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync {
|
|||||||
return $currentCmdID;
|
return $currentCmdID;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSync($currentCmdID, $hordeType, $syncType,&$output, $refts)
|
function handleSync($currentCmdID, $hordeType, $syncType,&$output, $refts) {
|
||||||
{
|
global $registry;
|
||||||
global $registry;
|
|
||||||
|
// array of Items which got modified, but got never send to the client before
|
||||||
// array of Items which got modified, but got never send to the client before
|
$missedAdds = array();
|
||||||
$missedAdds = array();
|
|
||||||
|
$history = $GLOBALS['phpgw']->contenthistory;
|
||||||
#require_once 'Horde/History.php';
|
$state = &$_SESSION['SyncML.state'];
|
||||||
#$history = &Horde_History::singleton();
|
$counter = 0;
|
||||||
$history = $GLOBALS['phpgw']->contenthistory;
|
|
||||||
$state = &$_SESSION['SyncML.state'];
|
$changes = &$state->getChangedItems($hordeType);
|
||||||
$counter = 0;
|
$deletes = &$state->getDeletedItems($hordeType);
|
||||||
|
$adds = &$state->getAddedItems($hordeType);
|
||||||
$changes = &$state->getChangedItems($hordeType);
|
|
||||||
$deletes = &$state->getDeletedItems($hordeType);
|
Horde::logMessage("SyncML: ".count($changes).' changed items found for '.$hordeType, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
$adds = &$state->getAddedItems($hordeType);
|
Horde::logMessage("SyncML: ".count($deletes).' deleted items found for '.$hordeType, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
Horde::logMessage("SyncML: ".count($adds). ' added items found for '.$hordeType , __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
Horde::logMessage("SyncML: ".count($changes).' changed items found for '.$hordeType, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
|
||||||
Horde::logMessage("SyncML: ".count($deletes).' deleted items found for '.$hordeType, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
while($guid = array_shift($changes)) {
|
||||||
Horde::logMessage("SyncML: ".count($adds). ' added items found for '.$hordeType , __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
$guid_ts = $history->getTSforAction($guid, 'modify');
|
||||||
|
$sync_ts = $state->getChangeTS($syncType, $guid);
|
||||||
while($guid = array_shift($changes))
|
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) {
|
||||||
$guid_ts = $history->getTSforAction($guid, 'modify');
|
// Change was done by us upon request of client.
|
||||||
$sync_ts = $state->getChangeTS($syncType, $guid);
|
// Don't mirror that back to the client.
|
||||||
Horde::logMessage("SyncML: timestamp modify guid_ts: $guid_ts sync_ts: $sync_ts", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
Horde::logMessage("SyncML: change: $guid ignored, came from client", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
if ($sync_ts && $sync_ts == $guid_ts) {
|
continue;
|
||||||
// Change was done by us upon request of client.
|
}
|
||||||
// Don't mirror that back to the client.
|
Horde::logMessage("SyncML: change $guid hs_ts:$guid_ts dt_ts:" . $state->getChangeTS($syncType, $guid), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
Horde::logMessage("SyncML: change: $guid ignored, came from client", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
$locid = $state->getLocID($syncType, $guid);
|
||||||
continue;
|
if (!$locid) {
|
||||||
}
|
// somehow we missed to add, lets store the uid, so we add this entry later
|
||||||
Horde::logMessage("SyncML: change $guid hs_ts:$guid_ts dt_ts:" . $state->getChangeTS($syncType, $guid), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
$missedAdds[] = $guid;
|
||||||
$locid = $state->getLocID($syncType, $guid);
|
Horde::logMessage("SyncML: unable to create change for $guid: locid not found in map", __FILE__, __LINE__, PEAR_LOG_WARNING);
|
||||||
if (!$locid) {
|
continue;
|
||||||
// somehow we missed to add, lets store the uid, so we add this entry later
|
}
|
||||||
$missedAdds[] = $guid;
|
|
||||||
Horde::logMessage("SyncML: unable to create change for $guid: locid not found in map", __FILE__, __LINE__, PEAR_LOG_WARNING);
|
// Create a replace request for client.
|
||||||
continue;
|
$contentType = $state->getPreferedContentTypeClient($this->_sourceLocURI);
|
||||||
}
|
if(is_a($contentType, 'PEAR_Error')) {
|
||||||
|
// Client did not sent devinfo
|
||||||
// Create a replace request for client.
|
$contentType = array('ContentType' => $state->getPreferedContentType($this->_targetLocURI));
|
||||||
# LK $contentType = $state->getPreferedContentTypeClient($syncType);
|
}
|
||||||
$contentType = $state->getPreferedContentTypeClient($this->_sourceLocURI);
|
$c = $registry->call($hordeType. '/export',
|
||||||
$c = $registry->call($hordeType. '/export',
|
array('guid' => $guid, 'contentType' => $contentType));
|
||||||
array('guid' => $guid, 'contentType' => $contentType));
|
if (!is_a($c, 'PEAR_Error')) {
|
||||||
if (!is_a($c, 'PEAR_Error')) {
|
// Item in history but not in database. Strange, but can happen.
|
||||||
// Item in history but not in database. Strange, but
|
Horde::logMessage("SyncML: change: $guid export content: $c", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
// can happen.
|
$cmd = &new Horde_SyncML_Command_Sync_ContentSyncElement();
|
||||||
Horde::logMessage("SyncML: change: $guid export content: $c", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
# LK $cmd->setContent($state->convertServer2Client($c, $contentType));
|
||||||
$cmd = &new Horde_SyncML_Command_Sync_ContentSyncElement();
|
$cmd->setContent($c);
|
||||||
# LK $cmd->setContent($state->convertServer2Client($c, $contentType));
|
$cmd->setSourceURI($guid);
|
||||||
$cmd->setContent($c);
|
$cmd->setTargetURI($locid);
|
||||||
$cmd->setSourceURI($guid);
|
$cmd->setContentType($contentType['ContentType']);
|
||||||
$cmd->setTargetURI($locid);
|
$currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Replace');
|
||||||
$cmd->setContentType($contentType['ContentType']);
|
$state->log('Server-Replace');
|
||||||
$currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Replace');
|
|
||||||
$state->log('Server-Replace');
|
// return if we have to much data
|
||||||
|
if(++$counter >= MAX_ENTRIES) {
|
||||||
// return if we have to much data
|
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
|
||||||
if(++$counter >= MAX_ENTRIES)
|
return $currentCmdID;
|
||||||
{
|
}
|
||||||
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
|
}
|
||||||
return $currentCmdID;
|
}
|
||||||
}
|
Horde::logMessage("SyncML: handling sync (changes done) ".$currentCmdID, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
}
|
|
||||||
}
|
|
||||||
Horde::logMessage("SyncML: handling sync ".$currentCmdID, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
|
||||||
|
|
||||||
// deletes
|
// deletes
|
||||||
while($guid = array_shift($deletes))
|
while($guid = array_shift($deletes))
|
||||||
@ -148,72 +145,74 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync {
|
|||||||
return $currentCmdID;
|
return $currentCmdID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Horde::logMessage("SyncML: handling sync ".$currentCmdID, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage("SyncML: handling sync ".$currentCmdID, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
// Get adds.
|
// Get adds.
|
||||||
if(count($missedAdds) > 0)
|
if(count($missedAdds) > 0) {
|
||||||
{
|
Horde::logMessage("SyncML: add missed changes as adds ".count($adds).' / '.$missedAdds[0], __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
Horde::logMessage("SyncML: add missed changes as adds ".count($adds).' / '.$missedAdds[0], __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
$state->setAddedItems($hordeType, array_merge($adds, $missedAdds));
|
||||||
$state->setAddedItems($hordeType, array_merge($adds, $missedAdds));
|
$adds = &$state->getAddedItems($hordeType);
|
||||||
$adds = &$state->getAddedItems($hordeType);
|
Horde::logMessage("SyncML: merged adds counter ".count($adds).' / '.$adds[0], __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
Horde::logMessage("SyncML: merged adds counter ".count($adds).' / '.$adds[0], __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
}
|
||||||
}
|
|
||||||
while($guid = array_shift($adds))
|
while($guid = array_shift($adds)) {
|
||||||
{
|
$guid_ts = $history->getTSforAction($guid, 'add');
|
||||||
#if($tempCounter > 10) continue;
|
$sync_ts = $state->getChangeTS($syncType, $guid);
|
||||||
$guid_ts = $history->getTSforAction($guid, 'add');
|
Horde::logMessage("SyncML: timestamp add $guid guid_ts: $guid_ts sync_ts: $sync_ts", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
$sync_ts = $state->getChangeTS($syncType, $guid);
|
if ($sync_ts && $sync_ts == $guid_ts) {
|
||||||
Horde::logMessage("SyncML: timestamp add $guid guid_ts: $guid_ts sync_ts: $sync_ts", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
// Change was done by us upon request of client.
|
||||||
if ($sync_ts && $sync_ts == $guid_ts) {
|
// Don't mirror that back to the client.
|
||||||
// Change was done by us upon request of client.
|
Horde::logMessage("SyncML: add: $guid ignored, came from client", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
// Don't mirror that back to the client.
|
continue;
|
||||||
Horde::logMessage("SyncML: add: $guid ignored, came from client", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
}
|
||||||
continue;
|
|
||||||
}
|
$locid = $state->getLocID($syncType, $guid);
|
||||||
|
|
||||||
$locid = $state->getLocID($syncType, $guid);
|
if ($locid && $refts == 0) {
|
||||||
|
// For slow sync (ts=0): do not add data for which we
|
||||||
if ($locid && $refts == 0) {
|
// have a locid again. This is a heuristic to avoid
|
||||||
// For slow sync (ts=0): do not add data for which we
|
// duplication of entries.
|
||||||
// have a locid again. This is a heuristic to avoid
|
Horde::logMessage("SyncML: skipping add of guid $guid as there already is a locid $locid", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
// duplication of entries.
|
continue;
|
||||||
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);
|
||||||
}
|
|
||||||
Horde::logMessage("SyncML: add: $guid", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
// Create an Add request for client.
|
||||||
|
$contentType = $state->getPreferedContentTypeClient($this->_sourceLocURI);
|
||||||
// Create an Add request for client.
|
if(is_a($contentType, 'PEAR_Error')) {
|
||||||
# LK $contentType = $state->getPreferedContentTypeClient($syncType);
|
// Client did not sent devinfo
|
||||||
$contentType = $state->getPreferedContentTypeClient($this->_sourceLocURI);
|
$contentType = array('ContentType' => $state->getPreferedContentType($this->_targetLocURI));
|
||||||
|
}
|
||||||
$cmd = &new Horde_SyncML_Command_Sync_ContentSyncElement();
|
|
||||||
$c = $registry->call($hordeType . '/export',
|
$cmd = &new Horde_SyncML_Command_Sync_ContentSyncElement();
|
||||||
array('guid' => $guid,
|
$c = $registry->call($hordeType . '/export',
|
||||||
'contentType' => $contentType));
|
array(
|
||||||
if (!is_a($c, 'PEAR_Error')) {
|
'guid' => $guid ,
|
||||||
// Item in history but not in database. Strange, but
|
'contentType' => $contentType ,
|
||||||
// can happen.
|
)
|
||||||
#LK $cmd->setContent($state->convertServer2Client($c, $contentType));
|
);
|
||||||
$cmd->setContent($c);
|
|
||||||
$cmd->setContentType($contentType['ContentType']);
|
if (!is_a($c, 'PEAR_Error')) {
|
||||||
$cmd->setSourceURI($guid);
|
// Item in history but not in database. Strange, but can happen.
|
||||||
$currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Add');
|
$cmd->setContent($c);
|
||||||
$state->log('Server-Add');
|
$cmd->setContentType($contentType['ContentType']);
|
||||||
|
$cmd->setSourceURI($guid);
|
||||||
// return if we have to much data
|
$currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Add');
|
||||||
if(++$counter >= MAX_ENTRIES)
|
$state->log('Server-Add');
|
||||||
{
|
|
||||||
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
|
// return if we have to much data
|
||||||
return $currentCmdID;
|
if(++$counter >= MAX_ENTRIES) {
|
||||||
}
|
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
|
||||||
}
|
return $currentCmdID;
|
||||||
}
|
}
|
||||||
Horde::logMessage("SyncML: handling sync ".$currentCmdID, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
}
|
||||||
|
}
|
||||||
$state->clearSync($syncType);
|
Horde::logMessage("SyncML: handling sync ".$currentCmdID, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
return $currentCmdID;
|
$state->clearSync($syncType);
|
||||||
}
|
|
||||||
|
return $currentCmdID;
|
||||||
|
}
|
||||||
|
|
||||||
function loadData()
|
function loadData()
|
||||||
{
|
{
|
||||||
@ -224,13 +223,13 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync {
|
|||||||
$hordeType = str_replace('./','',$syncType);
|
$hordeType = str_replace('./','',$syncType);
|
||||||
$refts = $state->getServerAnchorLast($syncType);
|
$refts = $state->getServerAnchorLast($syncType);
|
||||||
|
|
||||||
Horde::logMessage("SyncML: reading changed items from database", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage("SyncML: reading changed items from database", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
$state->setChangedItems($hordeType, $registry->call($hordeType. '/listBy', array('action' => 'modify', 'timestamp' => $refts)));
|
$state->setChangedItems($hordeType, $registry->call($hordeType. '/listBy', array('action' => 'modify', 'timestamp' => $refts)));
|
||||||
|
|
||||||
Horde::logMessage("SyncML: reading deleted items from database", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage("SyncML: reading deleted items from database", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
$state->setDeletedItems($hordeType, $registry->call($hordeType. '/listBy', array('action' => 'delete', 'timestamp' => $refts)));
|
$state->setDeletedItems($hordeType, $registry->call($hordeType. '/listBy', array('action' => 'delete', 'timestamp' => $refts)));
|
||||||
|
|
||||||
Horde::logMessage("SyncML: reading added items from database", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
#Horde::logMessage("SyncML: reading added items from database", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
$state->setAddedItems($hordeType, $registry->call($hordeType. '/listBy', array('action' => 'add', 'timestamp' => $refts)));
|
$state->setAddedItems($hordeType, $registry->call($hordeType. '/listBy', array('action' => 'add', 'timestamp' => $refts)));
|
||||||
|
|
||||||
$this->_syncDataLoaded = TRUE;
|
$this->_syncDataLoaded = TRUE;
|
||||||
|
@ -19,9 +19,9 @@ $conf['auth']['params']['username'] = 'Administrator';
|
|||||||
$conf['auth']['params']['requestuser'] = false;
|
$conf['auth']['params']['requestuser'] = false;
|
||||||
$conf['auth']['driver'] = 'auto';
|
$conf['auth']['driver'] = 'auto';
|
||||||
$conf['log']['priority'] = PEAR_LOG_DEBUG;
|
$conf['log']['priority'] = PEAR_LOG_DEBUG;
|
||||||
$conf['log']['ident'] = 'HORDE';
|
$conf['log']['ident'] = 'EGWSYNC';
|
||||||
$conf['log']['params'] = array();
|
$conf['log']['params'] = array();
|
||||||
$conf['log']['name'] = '/tmp/horde.log';
|
$conf['log']['name'] = '/tmp/egroupware_syncml.log';
|
||||||
$conf['log']['params']['append'] = true;
|
$conf['log']['params']['append'] = true;
|
||||||
$conf['log']['type'] = 'file';
|
$conf['log']['type'] = 'file';
|
||||||
$conf['log']['enabled'] = true;
|
$conf['log']['enabled'] = true;
|
||||||
|
@ -91,6 +91,16 @@ $this->applications['egwcontactssync'] = array(
|
|||||||
'menu_parent' => 'organizing'
|
'menu_parent' => 'organizing'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->applications['egwsifcontactssync'] = array(
|
||||||
|
'fileroot' => EGW_SERVER_ROOT.'/syncml/sifcontacts',
|
||||||
|
'webroot' => $this->applications['horde']['webroot'] . '/mnemo',
|
||||||
|
'icon' => $this->applications['horde']['webroot'] . '/mnemo/graphics/mnemo.gif',
|
||||||
|
'name' => _("SIF Contacts"),
|
||||||
|
'status' => 'active',
|
||||||
|
'provides' => 'sifcontacts',
|
||||||
|
'menu_parent' => 'organizing'
|
||||||
|
);
|
||||||
|
|
||||||
$this->applications['egwcalendarsync'] = array(
|
$this->applications['egwcalendarsync'] = array(
|
||||||
'fileroot' => EGW_SERVER_ROOT.'/syncml/calendar',
|
'fileroot' => EGW_SERVER_ROOT.'/syncml/calendar',
|
||||||
'webroot' => $this->applications['horde']['webroot'] . '/mnemo',
|
'webroot' => $this->applications['horde']['webroot'] . '/mnemo',
|
||||||
@ -111,3 +121,13 @@ $this->applications['egwtaskssync'] = array(
|
|||||||
'menu_parent' => 'organizing'
|
'menu_parent' => 'organizing'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->applications['egwsiftaskssync'] = array(
|
||||||
|
'fileroot' => EGW_SERVER_ROOT.'/syncml/siftasks',
|
||||||
|
'webroot' => $this->applications['horde']['webroot'] . '/mnemo',
|
||||||
|
'icon' => $this->applications['horde']['webroot'] . '/mnemo/graphics/mnemo.gif',
|
||||||
|
'name' => _("SIFTasks"),
|
||||||
|
'status' => 'active',
|
||||||
|
'provides' => 'siftasks',
|
||||||
|
'menu_parent' => 'organizing'
|
||||||
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user