2005-06-19 21:00:58 +02:00
< ? php
include_once 'Horde/SyncML/Sync/TwoWaySync.php' ;
/**
* Slow sync may just work ; I think most of the work is going to be
* done by the API .
*
* $Horde : framework / SyncML / SyncML / Sync / SlowSync . php , v 1.7 2004 / 05 / 26 17 : 32 : 50 chuck Exp $
*
* Copyright 2003 - 2004 Anthony Mills < amills @ pyramid6 . com >
*
* See the enclosed file COPYING for license information ( LGPL ) . If you
* did not receive this file , see http :// www . fsf . org / copyleft / lgpl . html .
*
* @ author Anthony Mills < amills @ pyramid6 . com >
* @ version $Revision $
* @ since Horde 3.0
* @ package Horde_SyncML
*/
class Horde_SyncML_Sync_SlowSync extends Horde_SyncML_Sync_TwoWaySync {
function handleSync ( $currentCmdID , $hordeType , $syncType , & $output , $refts )
{
global $registry ;
$history = $GLOBALS [ 'phpgw' ] -> contenthistory ;
$state = & $_SESSION [ 'SyncML.state' ];
$adds = & $state -> getAddedItems ( $hordeType );
#if($adds === FALSE)
#{
# Horde::logMessage("SyncML: reading added items from database", __FILE__, __LINE__, PEAR_LOG_DEBUG);
# $state->setAddedItems($hordeType, $registry->call($hordeType. '/list', array()));
# $adds = &$state->getAddedItems($hordeType);
#}
2006-03-21 14:49:13 +01:00
#Horde::logMessage("SyncML: ".count($adds). ' added items found for '.$hordeType , __FILE__, __LINE__, PEAR_LOG_DEBUG);
2005-06-19 21:00:58 +02:00
$serverAnchorNext = $state -> getServerAnchorNext ( $syncType );
2005-07-20 14:09:32 +02:00
$counter = 0 ;
2005-06-19 21:00:58 +02:00
while ( $guid = array_shift ( $adds ))
{
2006-03-21 14:49:13 +01:00
#$guid_ts = max($history->getTSforAction($guid, 'add'),$history->getTSforAction($guid, 'modify'));
$sync_ts = $state -> getChangeTS ( $syncType , $guid );
#Horde::logMessage("SyncML: slowsync timestamp add: $guid sync_ts: $sync_ts anchorNext: ". $serverAnchorNext.' / '.time(), __FILE__, __LINE__, PEAR_LOG_DEBUG);
// $sync_ts it got synced from client to server someone
// $sync_ts >= $serverAnchorNext it got synced from client to server in this sync package already
if ( $sync_ts && $sync_ts >= $serverAnchorNext ) {
// Change was done by us upon request of client.
// Don't mirror that back to the client.
//Horde::logMessage("SyncML: slowsync add: $guid ignored, came from client", __FILE__, __LINE__, PEAR_LOG_DEBUG);
continue ;
}
#$locid = $state->getLocID($syncType, $guid);
// Create an Add request for client.
2005-06-19 21:00:58 +02:00
# LK $contentType = $state->getPreferedContentTypeClient($syncType);
2006-03-21 14:49:13 +01:00
$contentType = $state -> getPreferedContentTypeClient ( $this -> _sourceLocURI );
if ( is_a ( $contentType , 'PEAR_Error' )) {
// Client did not sent devinfo
$contentType = array ( 'ContentType' => $state -> getPreferedContentType ( $this -> _targetLocURI ));
}
$cmd = & new Horde_SyncML_Command_Sync_ContentSyncElement ();
$c = $registry -> call ( $hordeType . '/export' , array ( 'guid' => $guid , 'contentType' => $contentType ));
#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
if ( ++ $counter >= MAX_ENTRIES )
{
$state -> setSyncStatus ( SERVER_SYNC_DATA_PENDING );
return $currentCmdID ;
}
}
}
#Horde::logMessage("SyncML: handling sync ".$currentCmdID, __FILE__, __LINE__, PEAR_LOG_DEBUG);
2005-06-19 21:00:58 +02:00
$state -> clearSync ( $syncType );
return $currentCmdID ;
}
2006-03-21 14:49:13 +01:00
/**
* 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 ) {
2006-04-07 10:11:17 +02:00
#Horde::logMessage('SyncML: content type is ' . $command->getContentType() .' moreData '. $command->_moreData, __FILE__, __LINE__, PEAR_LOG_DEBUG);
2006-03-21 14:49:13 +01:00
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 ;
}
2005-06-19 21:00:58 +02:00
function loadData ()
{
global $registry ;
$state = & $_SESSION [ 'SyncML.state' ];
$syncType = $this -> _targetLocURI ;
$hordeType = str_replace ( './' , '' , $syncType );
2006-03-21 14:49:13 +01:00
#Horde::logMessage("SyncML: reading added items from database for $hordeType", __FILE__, __LINE__, PEAR_LOG_DEBUG);
2005-06-19 21:00:58 +02:00
$state -> setAddedItems ( $hordeType , $registry -> call ( $hordeType . '/list' , array ()));
$adds = & $state -> getAddedItems ( $hordeType );
$this -> _syncDataLoaded = TRUE ;
return count ( $state -> getAddedItems ( $hordeType ));
}
}