2005-06-19 21:00:58 +02:00
|
|
|
<?php
|
|
|
|
/**
|
2009-07-15 21:31:25 +02:00
|
|
|
* eGroupWare - SyncML based on Horde 3
|
|
|
|
*
|
2005-06-19 21:00:58 +02:00
|
|
|
* Slow sync may just work; I think most of the work is going to be
|
|
|
|
* done by the API.
|
|
|
|
*
|
|
|
|
*
|
2009-07-15 21:31:25 +02:00
|
|
|
* Using the PEAR Log class (which need to be installed!)
|
2005-06-19 21:00:58 +02:00
|
|
|
*
|
2009-07-15 21:31:25 +02:00
|
|
|
* @link http://www.egroupware.org
|
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
|
|
* @package api
|
|
|
|
* @subpackage horde
|
|
|
|
* @author Anthony Mills <amills@pyramid6.com>
|
|
|
|
* @author Joerg Lehrke <jlehrke@noc.de>
|
|
|
|
* @copyright (c) The Horde Project (http://www.horde.org/)
|
|
|
|
* @version $Id$
|
2005-06-19 21:00:58 +02:00
|
|
|
*/
|
2009-07-15 21:31:25 +02:00
|
|
|
include_once 'Horde/SyncML/Sync/TwoWaySync.php';
|
|
|
|
|
2005-06-19 21:00:58 +02:00
|
|
|
class Horde_SyncML_Sync_SlowSync extends Horde_SyncML_Sync_TwoWaySync {
|
2009-07-15 21:31:25 +02:00
|
|
|
|
2006-08-15 16:42:13 +02:00
|
|
|
function handleSync($currentCmdID, $hordeType, $syncType, &$output, $refts) {
|
2006-07-09 09:27:23 +02:00
|
|
|
global $registry;
|
2009-07-15 21:31:25 +02:00
|
|
|
|
2006-07-09 09:27:23 +02:00
|
|
|
$history = $GLOBALS['egw']->contenthistory;
|
|
|
|
$state = &$_SESSION['SyncML.state'];
|
2009-07-15 21:31:25 +02:00
|
|
|
$maxMsgSize = $state->getMaxMsgSizeClient();
|
|
|
|
$deviceInfo = $state->getClientDeviceInfo();
|
|
|
|
|
|
|
|
if (isset($deviceInfo['maxEntries'])) {
|
|
|
|
$maxEntries = $deviceInfo['maxEntries'];
|
|
|
|
if (!$maxMsgSize && !$maxEntries) {
|
|
|
|
// fallback to default
|
|
|
|
$maxEntries = MAX_ENTRIES;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$maxEntries = MAX_ENTRIES;
|
|
|
|
}
|
|
|
|
|
Big SyncML patch from Philip Herbert <pherbert(at)knauber.de>:
- change the processing of slowsync, to use the content_map instead of
trying to build a new one. This caused duplication issues on the
client if multiple similar records where stored, because only the first
one found in the server-db was matched, These duplicate entries at client
side had no entry at serverside, so deleting the wrong one
on the client (the content with a valid map entry) could cause
unwanted data loss at server side, because it is impossible for the
user to see what is a duplicate, and what is not.
see also:
http://www.nabble.com/again---syncml-duplication-issue-to20333619s3741.html
- reenabled UID from syncml clients, because it was partly used this caused
issues during SlowSync if the content was changed.
- infolog, calendar if a uid is found in the provided data, allway try to
find the corresponding content first using only the UID, instead of
using the content-id taken from content_map.
also fixed:
- a few fixes in ./notes
- creating an entry on the client that can not be imported,
(Example, Nokia E Series Appointment without a Title)
will no longer create an invalid content-map entry
However, at client side this is still counted in the Protocol as
Server-Add
2008-11-16 11:42:29 +01:00
|
|
|
$serverAnchorNext = $state->getServerAnchorNext($syncType);
|
2009-07-15 21:31:25 +02:00
|
|
|
|
Big SyncML patch from Philip Herbert <pherbert(at)knauber.de>:
- change the processing of slowsync, to use the content_map instead of
trying to build a new one. This caused duplication issues on the
client if multiple similar records where stored, because only the first
one found in the server-db was matched, These duplicate entries at client
side had no entry at serverside, so deleting the wrong one
on the client (the content with a valid map entry) could cause
unwanted data loss at server side, because it is impossible for the
user to see what is a duplicate, and what is not.
see also:
http://www.nabble.com/again---syncml-duplication-issue-to20333619s3741.html
- reenabled UID from syncml clients, because it was partly used this caused
issues during SlowSync if the content was changed.
- infolog, calendar if a uid is found in the provided data, allway try to
find the corresponding content first using only the UID, instead of
using the content-id taken from content_map.
also fixed:
- a few fixes in ./notes
- creating an entry on the client that can not be imported,
(Example, Nokia E Series Appointment without a Title)
will no longer create an invalid content-map entry
However, at client side this is still counted in the Protocol as
Server-Add
2008-11-16 11:42:29 +01:00
|
|
|
// now we remove all UID from contentmap that have not been verified in this slowsync
|
|
|
|
$state->removeOldUID($syncType, $serverAnchorNext);
|
2009-07-15 21:31:25 +02:00
|
|
|
|
|
|
|
if (isset($state->curSyncItem)) {
|
|
|
|
// Finish the pending sync item
|
|
|
|
$cmd = &$state->curSyncItem;
|
2010-02-09 11:44:15 +01:00
|
|
|
if (!is_a($cmd, 'Horde_SyncML_Command_Sync_ContentSyncElement')) {
|
|
|
|
// Conflict with other datastore
|
|
|
|
Horde :: logMessage("SyncML: handleSync($currentCmdID, $hordeType, $syncType) moreData conflict found",
|
2010-05-20 12:48:45 +02:00
|
|
|
__FILE__, __LINE__, PEAR_LOG_WARNING);
|
2010-02-09 11:44:15 +01:00
|
|
|
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
|
|
|
|
return $currentCmdID;
|
|
|
|
}
|
2009-07-15 21:31:25 +02:00
|
|
|
unset($state->curSyncItem);
|
|
|
|
$currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Sync');
|
|
|
|
|
|
|
|
// moreData split; save in session state and end current message
|
|
|
|
if ($cmd->hasMoreData()) {
|
|
|
|
$state->curSyncItem = &$cmd;
|
|
|
|
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
|
|
|
|
return $currentCmdID;
|
|
|
|
}
|
|
|
|
$state->incNumberOfElements();
|
|
|
|
}
|
|
|
|
|
2009-11-17 22:20:32 +01:00
|
|
|
$adds =& $state->getAddedItems($syncType);
|
|
|
|
$conflicts =& $state->getConflictItems($syncType);
|
|
|
|
Horde::logMessage('SyncML: ' .count($adds). ' added items found for ' .$syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
|
|
|
Horde::logMessage('SyncML: ' . count($conflicts) . ' items to delete on client found for ' . $syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
2009-07-15 21:31:25 +02:00
|
|
|
|
2009-11-17 22:20:32 +01:00
|
|
|
if (is_array($adds)) {
|
|
|
|
while ($guid = array_shift($adds)) {
|
2009-07-15 21:31:25 +02:00
|
|
|
$currentSize = $output->getOutputSize();
|
|
|
|
// return if we have to much data
|
|
|
|
if (($maxEntries && ($state->getNumberOfElements() >= $maxEntries)
|
|
|
|
&& isset($contentType['mayFragment'])
|
|
|
|
&& $contentType['mayFragment']) ||
|
|
|
|
($maxMsgSize && (($currentSize + MIN_MSG_LEFT * 2) > $maxMsgSize))) {
|
|
|
|
// put the item back in the queue
|
|
|
|
$adds[] = $guid;
|
|
|
|
$state->maxNumberOfElements();
|
|
|
|
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
|
|
|
|
return $currentCmdID;
|
|
|
|
}
|
|
|
|
|
2010-03-03 01:41:15 +01:00
|
|
|
if (($locID = $state->getLocID($syncType, $guid))) {
|
2009-11-20 08:24:00 +01:00
|
|
|
Horde::logMessage("SyncML: slowsync add to client: $guid ignored, already at client($locID)",
|
|
|
|
__FILE__, __LINE__, PEAR_LOG_DEBUG);
|
2006-07-09 09:27:23 +02:00
|
|
|
continue;
|
|
|
|
}
|
2009-07-15 21:31:25 +02:00
|
|
|
|
|
|
|
$guid_ts = $state->getSyncTSforAction($guid, 'add');
|
|
|
|
if ($guid_ts > $serverAnchorNext) {
|
|
|
|
// Change was made after we started this sync.
|
|
|
|
// Don't sent this now to the client.
|
2009-11-20 08:24:00 +01:00
|
|
|
Horde::logMessage("SyncML: slowsync add $guid is in our future",
|
|
|
|
__FILE__, __LINE__, PEAR_LOG_DEBUG);
|
2009-07-15 21:31:25 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
SyncML patches from patrick.bihan-faou-AT-mindstep.com (without
logout+mbstring stuff), small modification to use the already exiting
methodes to generate full name and fileas)
The code is commited to trunk only at the moment to allow testing of it.
If everything goes well, we intend to commit it to 1.4 branch too.
Here's the original description of the patch by Patrick:
- handles the default config for current versions of funambol (i.e. the
scard/stask/snote/scal locations)
- tries to be a bit smarter on how the data content should be encoded
based on what the client specified (sif+base64/vcard, / fragmented or
not, etc.)
- workaround a bug in some versions of funambol, where funambol does not
specify the proper sif type for the type of requested data
- imported patch #117 from egw's tracker
- make sure that the logs generated by the horde code go to stderr so
they can be view in the webserver's logs
- as much as possible reduce code duplication. For example, the
categories are handled in the parent classes for both the SIF avn VCAL
formats for each type of data (addressbook,infolog,calendar).
- make sure the code can handle more than one categories in each
direction
- treat the 'sony ericsson' vendor string just like 'sonyericsson', the
newer phones apparently have a space in the vendor string... (this
touches some files in the icalsrv as well)
- handle notes: these should now work with everything (funambol or
other)
- remove more code duplication: the syncml "api" for the various data
types (calendar, contacts, infolog) is now common for both the vcard and
sif data formats (cf the files that need to be removed)
- handle the "privat" filter in infolog like the "private" filter (some
part of the code use the name without the trailing e)
- imported patch # 267 from egw's tracker
2007-09-29 12:29:48 +02:00
|
|
|
$contentType = $state->getPreferedContentTypeClient($this->_sourceLocURI, $this->_targetLocURI);
|
2006-07-09 09:27:23 +02:00
|
|
|
$c = $registry->call($hordeType . '/export', array('guid' => $guid, 'contentType' => $contentType));
|
2010-01-29 22:42:54 +01:00
|
|
|
|
|
|
|
if ($c === false) continue; // no content to export
|
|
|
|
|
2009-07-15 21:31:25 +02:00
|
|
|
if (is_a($c, 'PEAR_Error')) {
|
2009-11-20 08:24:00 +01:00
|
|
|
Horde::logMessage("SyncML: slowsync failed to export guid $guid:\n" . print_r($c, true),
|
|
|
|
__FILE__, __LINE__, PEAR_LOG_WARNING);
|
2009-07-15 21:31:25 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$size = strlen($c);
|
|
|
|
// return if we have to much data
|
|
|
|
if ($maxMsgSize && !$deviceInfo['supportLargeObjs']) {
|
|
|
|
if (($size + MIN_MSG_LEFT * 2) > $maxMsgSize) {
|
2009-11-20 08:24:00 +01:00
|
|
|
Horde::logMessage("SyncML: slowsync failed to export guid $guid due to size $size",
|
|
|
|
__FILE__, __LINE__, PEAR_LOG_ERROR);
|
2009-07-15 21:31:25 +02:00
|
|
|
continue;
|
2006-07-09 09:27:23 +02:00
|
|
|
}
|
2009-07-15 21:31:25 +02:00
|
|
|
if (($currentSize + $size + MIN_MSG_LEFT * 2) > $maxMsgSize) {
|
|
|
|
// put the item back in the queue
|
|
|
|
$adds[] = $guid;
|
2006-07-09 09:27:23 +02:00
|
|
|
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
|
|
|
|
return $currentCmdID;
|
|
|
|
}
|
|
|
|
}
|
2009-07-15 21:31:25 +02:00
|
|
|
|
2009-11-20 08:24:00 +01:00
|
|
|
Horde::logMessage("SyncML: slowsync add guid $guid to client\n$c",
|
|
|
|
__FILE__, __LINE__, PEAR_LOG_DEBUG);
|
2009-07-15 21:31:25 +02:00
|
|
|
$cmd = new Horde_SyncML_Command_Sync_ContentSyncElement();
|
|
|
|
$cmd->setContent($c);
|
|
|
|
$cmd->setContentType($contentType['ContentType']);
|
|
|
|
if (isset($contentType['ContentFormat'])) {
|
|
|
|
$cmd->setContentFormat($contentType['ContentFormat']);
|
|
|
|
}
|
|
|
|
$cmd->setGUID($guid);
|
|
|
|
$currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Add');
|
|
|
|
$state->log('Server-Add');
|
|
|
|
|
|
|
|
// moreData split; save in session state and end current message
|
|
|
|
if ($cmd->hasMoreData()) {
|
|
|
|
$state->curSyncItem = &$cmd;
|
|
|
|
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
|
|
|
|
return $currentCmdID;
|
|
|
|
}
|
|
|
|
$state->incNumberOfElements();
|
2006-03-21 14:49:13 +01:00
|
|
|
}
|
|
|
|
}
|
2009-11-17 22:20:32 +01:00
|
|
|
// handle remote deletes due to conflicts
|
|
|
|
if (count($conflicts) > 0) {
|
|
|
|
while ($locid = array_shift($conflicts)) {
|
|
|
|
$currentSize = $output->getOutputSize();
|
|
|
|
// return if we have to much data
|
|
|
|
if (($maxEntries && ($state->getNumberOfElements() >= $maxEntries)
|
|
|
|
&& isset ($contentType['mayFragment'])
|
|
|
|
&& $contentType['mayFragment'])
|
|
|
|
|| ($maxMsgSize
|
|
|
|
&& (($currentSize +MIN_MSG_LEFT * 2) > $maxMsgSize))) {
|
|
|
|
// put the item back in the queue
|
|
|
|
$conflicts[] = $locid;
|
|
|
|
$state->maxNumberOfElements();
|
|
|
|
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
|
|
|
|
return $currentCmdID;
|
|
|
|
}
|
2009-11-20 08:24:00 +01:00
|
|
|
Horde :: logMessage("SyncML: delete client locid: $locid",
|
|
|
|
__FILE__, __LINE__, PEAR_LOG_DEBUG);
|
2009-11-17 22:20:32 +01:00
|
|
|
// Create a Delete request for client.
|
|
|
|
$cmd = new Horde_SyncML_Command_Sync_ContentSyncElement();
|
|
|
|
$cmd->setLocURI($locid);
|
|
|
|
$currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Delete');
|
|
|
|
$state->log('Server-DeletedConflicts');
|
|
|
|
$state->removeUID($syncType, $locid);
|
2009-07-15 21:31:25 +02:00
|
|
|
|
2009-11-17 22:20:32 +01:00
|
|
|
// moreData split; save in session state and end current message
|
|
|
|
if ($cmd->hasMoreData()) {
|
|
|
|
$state->curSyncItem = & $cmd;
|
|
|
|
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
|
|
|
|
return $currentCmdID;
|
|
|
|
}
|
|
|
|
$state->incNumberOfElements();
|
|
|
|
}
|
|
|
|
}
|
2009-11-20 08:24:00 +01:00
|
|
|
Horde::logMessage("SyncML: All items handled for sync $syncType",
|
|
|
|
__FILE__, __LINE__, PEAR_LOG_DEBUG);
|
2009-07-15 21:31:25 +02:00
|
|
|
|
|
|
|
$state->removeExpiredUID($syncType, $serverAnchorNext);
|
2006-07-09 09:27:23 +02:00
|
|
|
$state->clearSync($syncType);
|
2009-07-15 21:31:25 +02:00
|
|
|
|
2006-07-09 09:27:23 +02:00
|
|
|
return $currentCmdID;
|
2006-03-21 14:49:13 +01:00
|
|
|
}
|
2009-07-15 21:31:25 +02:00
|
|
|
|
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) {
|
|
|
|
global $registry;
|
|
|
|
$history = $GLOBALS['egw']->contenthistory;
|
|
|
|
$state = &$_SESSION['SyncML.state'];
|
2009-07-15 21:31:25 +02:00
|
|
|
|
SyncML patches from patrick.bihan-faou-AT-mindstep.com (without
logout+mbstring stuff), small modification to use the already exiting
methodes to generate full name and fileas)
The code is commited to trunk only at the moment to allow testing of it.
If everything goes well, we intend to commit it to 1.4 branch too.
Here's the original description of the patch by Patrick:
- handles the default config for current versions of funambol (i.e. the
scard/stask/snote/scal locations)
- tries to be a bit smarter on how the data content should be encoded
based on what the client specified (sif+base64/vcard, / fragmented or
not, etc.)
- workaround a bug in some versions of funambol, where funambol does not
specify the proper sif type for the type of requested data
- imported patch #117 from egw's tracker
- make sure that the logs generated by the horde code go to stderr so
they can be view in the webserver's logs
- as much as possible reduce code duplication. For example, the
categories are handled in the parent classes for both the SIF avn VCAL
formats for each type of data (addressbook,infolog,calendar).
- make sure the code can handle more than one categories in each
direction
- treat the 'sony ericsson' vendor string just like 'sonyericsson', the
newer phones apparently have a space in the vendor string... (this
touches some files in the icalsrv as well)
- handle notes: these should now work with everything (funambol or
other)
- remove more code duplication: the syncml "api" for the various data
types (calendar, contacts, infolog) is now common for both the vcard and
sif data formats (cf the files that need to be removed)
- handle the "privat" filter in infolog like the "private" filter (some
part of the code use the name without the trailing e)
- imported patch # 267 from egw's tracker
2007-09-29 12:29:48 +02:00
|
|
|
$type = $this->_targetLocURI;
|
2009-07-15 21:31:25 +02:00
|
|
|
|
|
|
|
$syncml_prefs = $GLOBALS['egw_info']['user']['preferences']['syncml'];
|
|
|
|
if (isset($syncml_prefs[$type])) {
|
|
|
|
$sync_conflicts = $syncml_prefs[$type];
|
|
|
|
} else {
|
|
|
|
$sync_conflicts = CONFLICT_SERVER_WINNING;
|
|
|
|
}
|
|
|
|
|
SyncML patches from patrick.bihan-faou-AT-mindstep.com (without
logout+mbstring stuff), small modification to use the already exiting
methodes to generate full name and fileas)
The code is commited to trunk only at the moment to allow testing of it.
If everything goes well, we intend to commit it to 1.4 branch too.
Here's the original description of the patch by Patrick:
- handles the default config for current versions of funambol (i.e. the
scard/stask/snote/scal locations)
- tries to be a bit smarter on how the data content should be encoded
based on what the client specified (sif+base64/vcard, / fragmented or
not, etc.)
- workaround a bug in some versions of funambol, where funambol does not
specify the proper sif type for the type of requested data
- imported patch #117 from egw's tracker
- make sure that the logs generated by the horde code go to stderr so
they can be view in the webserver's logs
- as much as possible reduce code duplication. For example, the
categories are handled in the parent classes for both the SIF avn VCAL
formats for each type of data (addressbook,infolog,calendar).
- make sure the code can handle more than one categories in each
direction
- treat the 'sony ericsson' vendor string just like 'sonyericsson', the
newer phones apparently have a space in the vendor string... (this
touches some files in the icalsrv as well)
- handle notes: these should now work with everything (funambol or
other)
- remove more code duplication: the syncml "api" for the various data
types (calendar, contacts, infolog) is now common for both the vcard and
sif data formats (cf the files that need to be removed)
- handle the "privat" filter in infolog like the "private" filter (some
part of the code use the name without the trailing e)
- imported patch # 267 from egw's tracker
2007-09-29 12:29:48 +02:00
|
|
|
$hordeType = $state->getHordeType($type);
|
2009-07-15 21:31:25 +02:00
|
|
|
|
2006-03-21 14:49:13 +01:00
|
|
|
$syncElementItems = $command->getSyncElementItems();
|
2009-07-15 21:31:25 +02:00
|
|
|
|
2006-03-21 14:49:13 +01:00
|
|
|
foreach($syncElementItems as $syncItem) {
|
2009-07-15 21:31:25 +02:00
|
|
|
|
2006-03-21 14:49:13 +01:00
|
|
|
if(!$contentType = $syncItem->getContentType()) {
|
|
|
|
$contentType = $state->getPreferedContentType($type);
|
|
|
|
}
|
2009-07-15 21:31:25 +02:00
|
|
|
|
SyncML patches from patrick.bihan-faou-AT-mindstep.com (without
logout+mbstring stuff), small modification to use the already exiting
methodes to generate full name and fileas)
The code is commited to trunk only at the moment to allow testing of it.
If everything goes well, we intend to commit it to 1.4 branch too.
Here's the original description of the patch by Patrick:
- handles the default config for current versions of funambol (i.e. the
scard/stask/snote/scal locations)
- tries to be a bit smarter on how the data content should be encoded
based on what the client specified (sif+base64/vcard, / fragmented or
not, etc.)
- workaround a bug in some versions of funambol, where funambol does not
specify the proper sif type for the type of requested data
- imported patch #117 from egw's tracker
- make sure that the logs generated by the horde code go to stderr so
they can be view in the webserver's logs
- as much as possible reduce code duplication. For example, the
categories are handled in the parent classes for both the SIF avn VCAL
formats for each type of data (addressbook,infolog,calendar).
- make sure the code can handle more than one categories in each
direction
- treat the 'sony ericsson' vendor string just like 'sonyericsson', the
newer phones apparently have a space in the vendor string... (this
touches some files in the icalsrv as well)
- handle notes: these should now work with everything (funambol or
other)
- remove more code duplication: the syncml "api" for the various data
types (calendar, contacts, infolog) is now common for both the vcard and
sif data formats (cf the files that need to be removed)
- handle the "privat" filter in infolog like the "private" filter (some
part of the code use the name without the trailing e)
- imported patch # 267 from egw's tracker
2007-09-29 12:29:48 +02:00
|
|
|
if (($contentType == 'text/x-vcalendar' || $contentType == 'text/calendar')
|
2009-07-15 21:31:25 +02:00
|
|
|
&& strpos($syncItem->getContent(), 'BEGIN:VTODO') !== false) {
|
2006-03-21 14:49:13 +01:00
|
|
|
$hordeType = 'tasks';
|
|
|
|
}
|
2009-07-15 21:31:25 +02:00
|
|
|
|
2006-03-21 14:49:13 +01:00
|
|
|
$guid = false;
|
2009-07-15 21:31:25 +02:00
|
|
|
|
2010-02-08 20:48:33 +01:00
|
|
|
$oguid = $state->getGlobalUID($type, $syncItem->getLocURI());
|
|
|
|
|
2006-08-15 16:42:13 +02:00
|
|
|
$guid = $registry->call($hordeType . '/search',
|
2010-02-08 20:48:33 +01:00
|
|
|
array($state->convertClient2Server($syncItem->getContent(), $contentType), $contentType, $oguid, $type));
|
2009-07-15 21:31:25 +02:00
|
|
|
|
2010-05-20 12:48:45 +02:00
|
|
|
if (!is_a($guid, 'PEAR_Error') && $guid) {
|
2009-07-15 21:31:25 +02:00
|
|
|
// Check if the found entry came from the client
|
|
|
|
$guid_ts = $state->getSyncTSforAction($guid, 'add');
|
|
|
|
$sync_ts = $state->getChangeTS($type, $guid);
|
2010-02-08 20:48:33 +01:00
|
|
|
if ($oguid != $guid && $sync_ts && $sync_ts == $guid_ts) {
|
2009-07-15 21:31:25 +02:00
|
|
|
// Entry came from the client, so we get a duplicate here
|
|
|
|
Horde::logMessage('SyncML: CONFLICT for locuri ' . $syncItem->getLocURI()
|
|
|
|
. ' guid ' . $guid , __FILE__, __LINE__, PEAR_LOG_WARNING);
|
|
|
|
if ($sync_conflicts != CONFLICT_RESOLVED_WITH_DUPLICATE) {
|
|
|
|
$state->log("Client-AddReplaceIgnored");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
# Entry exists in database already. Just update the mapping
|
|
|
|
Horde::logMessage('SyncML: adding mapping for locuri:'
|
|
|
|
. $syncItem->getLocURI() . ' and guid:' . $guid,
|
|
|
|
__FILE__, __LINE__, PEAR_LOG_DEBUG);
|
2010-03-03 01:41:15 +01:00
|
|
|
$state->setUID($type, $syncItem->getLocURI(), $guid);
|
2009-07-15 21:31:25 +02:00
|
|
|
$state->log("Client-Map");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($sync_conflicts > CONFLICT_RESOLVED_WITH_DUPLICATE) {
|
|
|
|
// We enforce the client not to change anything
|
|
|
|
if ($sync_conflicts > CONFLICT_CLIENT_CHANGES_IGNORED) {
|
|
|
|
// delete this item from client
|
|
|
|
Horde::logMessage('SyncML: Server RO! REMOVE ' . $syncItem->getLocURI()
|
|
|
|
. ' from client', __FILE__, __LINE__, PEAR_LOG_WARNING);
|
2009-11-11 21:16:34 +01:00
|
|
|
$state->addConflictItem($type, $syncItem->getLocURI());
|
2006-08-15 16:42:13 +02:00
|
|
|
} else {
|
2009-07-15 21:31:25 +02:00
|
|
|
Horde::logMessage('SyncML: Server RO! REJECT all client changes',
|
|
|
|
__FILE__, __LINE__, PEAR_LOG_WARNING);
|
|
|
|
$state->log("Client-AddReplaceIgnored");
|
2006-03-21 14:49:13 +01:00
|
|
|
}
|
2009-07-15 21:31:25 +02:00
|
|
|
$command->setStatus(RESPONSE_NO_EXECUTED);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add entry to the database.
|
|
|
|
$state->removeUID($type, $syncItem->getLocURI());
|
2009-11-20 08:24:00 +01:00
|
|
|
Horde::logMessage('SyncML: try to add contentype ' . $contentType .' to '. $hordeType,
|
|
|
|
__FILE__, __LINE__, PEAR_LOG_DEBUG);
|
2009-07-15 21:31:25 +02:00
|
|
|
$guid = $registry->call($hordeType . '/import',
|
|
|
|
array($state->convertClient2Server($syncItem->getContent(), $contentType), $contentType));
|
2010-05-20 12:48:45 +02:00
|
|
|
if (!is_a($guid, 'PEAR_Error') && $guid) {
|
2010-03-03 01:41:15 +01:00
|
|
|
$state->setUID($type, $syncItem->getLocURI(), $guid);
|
2009-07-15 21:31:25 +02:00
|
|
|
$state->log("Client-AddReplace");
|
2010-03-03 01:41:15 +01:00
|
|
|
Horde::logMessage('SyncML: replaced/added client entry as ' . $guid,
|
2009-11-20 08:24:00 +01:00
|
|
|
__FILE__, __LINE__, PEAR_LOG_DEBUG);
|
2009-07-15 21:31:25 +02:00
|
|
|
} else {
|
2009-11-20 08:24:00 +01:00
|
|
|
Horde::logMessage('SyncML: Error in replacing/add client entry:' . $guid->message,
|
|
|
|
__FILE__, __LINE__, PEAR_LOG_ERR);
|
2009-07-15 21:31:25 +02:00
|
|
|
$state->log("Client-AddFailure");
|
2006-08-15 16:42:13 +02:00
|
|
|
}
|
2006-03-21 14:49:13 +01:00
|
|
|
}
|
|
|
|
}
|
2009-07-15 21:31:25 +02:00
|
|
|
|
2006-10-04 20:16:58 +02:00
|
|
|
function loadData() {
|
|
|
|
global $registry;
|
2009-07-15 21:31:25 +02:00
|
|
|
|
2006-10-04 20:16:58 +02:00
|
|
|
$state = &$_SESSION['SyncML.state'];
|
|
|
|
$syncType = $this->_targetLocURI;
|
SyncML patches from patrick.bihan-faou-AT-mindstep.com (without
logout+mbstring stuff), small modification to use the already exiting
methodes to generate full name and fileas)
The code is commited to trunk only at the moment to allow testing of it.
If everything goes well, we intend to commit it to 1.4 branch too.
Here's the original description of the patch by Patrick:
- handles the default config for current versions of funambol (i.e. the
scard/stask/snote/scal locations)
- tries to be a bit smarter on how the data content should be encoded
based on what the client specified (sif+base64/vcard, / fragmented or
not, etc.)
- workaround a bug in some versions of funambol, where funambol does not
specify the proper sif type for the type of requested data
- imported patch #117 from egw's tracker
- make sure that the logs generated by the horde code go to stderr so
they can be view in the webserver's logs
- as much as possible reduce code duplication. For example, the
categories are handled in the parent classes for both the SIF avn VCAL
formats for each type of data (addressbook,infolog,calendar).
- make sure the code can handle more than one categories in each
direction
- treat the 'sony ericsson' vendor string just like 'sonyericsson', the
newer phones apparently have a space in the vendor string... (this
touches some files in the icalsrv as well)
- handle notes: these should now work with everything (funambol or
other)
- remove more code duplication: the syncml "api" for the various data
types (calendar, contacts, infolog) is now common for both the vcard and
sif data formats (cf the files that need to be removed)
- handle the "privat" filter in infolog like the "private" filter (some
part of the code use the name without the trailing e)
- imported patch # 267 from egw's tracker
2007-09-29 12:29:48 +02:00
|
|
|
$hordeType = $state->getHordeType($syncType);
|
2009-07-15 21:31:25 +02:00
|
|
|
$state->setTargetURI($syncType);
|
|
|
|
$future = $state->getServerAnchorNext($syncType);
|
|
|
|
|
2009-11-11 21:16:34 +01:00
|
|
|
$state->mergeAddedItems($syncType, $registry->call($hordeType. '/list', array('filter' => $this->_filterExpression)));
|
2009-11-20 08:24:00 +01:00
|
|
|
|
2006-10-04 20:16:58 +02:00
|
|
|
$this->_syncDataLoaded = TRUE;
|
2009-07-15 21:31:25 +02:00
|
|
|
|
2009-12-01 11:14:23 +01:00
|
|
|
return count($state->getAddedItems($syncType)) + count($state->getConflictItems($syncType));
|
2006-10-04 20:16:58 +02:00
|
|
|
}
|
2005-06-19 21:00:58 +02:00
|
|
|
}
|