2005-06-19 21:00:58 +02:00
< ? php
/**
* $Horde : framework / SyncML / SyncML / Sync . php , v 1.7 2004 / 09 / 14 04 : 27 : 05 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 {
/**
* Target , either contacts , notes , events ,
*/
var $_targetLocURI ;
var $_sourceLocURI ;
/**
* Return if all commands success .
*/
var $globalSuccess ;
/**
* This is the content type to use to export data .
*/
var $preferedContentType ;
/**
* Do have the sync data loaded from the database already ?
*/
var $syncDataLoaded ;
function & factory ( $alert )
{
2005-07-26 09:22:58 +02:00
Horde :: logMessage ( 'SyncML: new sync for alerttype ' . $alert , __FILE__ , __LINE__ , PEAR_LOG_DEBUG );
2005-06-19 21:00:58 +02:00
switch ( $alert ) {
case ALERT_TWO_WAY :
include_once 'Horde/SyncML/Sync/TwoWaySync.php' ;
return $sync = & new Horde_SyncML_Sync_TwoWaySync ();
case ALERT_SLOW_SYNC :
include_once 'Horde/SyncML/Sync/SlowSync.php' ;
return $sync = & new Horde_SyncML_Sync_SlowSync ();
case ALERT_ONE_WAY_FROM_CLIENT :
include_once 'Horde/SyncML/Sync/OneWayFromClientSync.php' ;
return $sync = & new Horde_SyncML_Sync_OneWayFromClientSync ();
case ALERT_REFRESH_FROM_CLIENT :
include_once 'Horde/SyncML/Sync/RefreshFromClientSync.php' ;
return $sync = & new Horde_SyncML_Sync_RefreshFromClientSync ();
case ALERT_ONE_WAY_FROM_SERVER :
include_once 'Horde/SyncML/Sync/OneWayFromServerSync.php' ;
return $sync = & new Horde_SyncML_Sync_OneWayFromServerSync ();
case ALERT_REFRESH_FROM_SERVER :
include_once 'Horde/SyncML/Sync/RefreshFromServerSync.php' ;
return $sync = & new Horde_SyncML_Sync_RefreshFromServerSync ();
}
require_once 'PEAR.php' ;
return PEAR :: raiseError ( 'Alert ' . $alert . ' not found.' );
}
function nextSyncCommand ( $currentCmdID , & $syncCommand , & $output )
{
$result = $this -> runSyncCommand ( $syncCommand );
return $syncCommand -> output ( $currentCmdID , $output );
}
function startSync ( $currentCmdID , & $output )
{
return $currentCmdID ;
}
function endSync ( $currentCmdID , & $output )
{
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 , deleted 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 );
if ( ! $contentType = $command -> getContentType ()) {
$contentType = $state -> getPreferedContentType ( $type );
}
if ( $this -> _targetLocURI == 'calendar' && strpos ( $command -> getContent (), 'BEGIN:VTODO' ) !== false ) {
$hordeType = 'tasks' ;
}
$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 ;
}
2005-06-19 21:00:58 +02:00
}