Commit e5657007 authored by Sebastian Kummer's avatar Sebastian Kummer

ZP-849 Changes:

- Move folders correctly with mapped and traditional profiles
- Changed IIChanges->ImportFolderChange() to return a SyncFolder object
to transport all ids.
- Added logging to Zarafa importer and folder move operations.

Released under the Affero GNU General Public License (AGPL) version 3.
parent 19c8e3eb
...@@ -164,7 +164,7 @@ class ImportChangesCombined implements IImportChanges { ...@@ -164,7 +164,7 @@ class ImportChangesCombined implements IImportChanges {
* @param object $folder SyncFolder * @param object $folder SyncFolder
* *
* @access public * @access public
* @return boolean/string status/id of the folder * @return boolean/SyncObject status/object with the ath least the serverid of the folder set
*/ */
public function ImportFolderChange($folder) { public function ImportFolderChange($folder) {
$id = $folder->serverid; $id = $folder->serverid;
...@@ -197,9 +197,11 @@ class ImportChangesCombined implements IImportChanges { ...@@ -197,9 +197,11 @@ class ImportChangesCombined implements IImportChanges {
} }
$this->icc = $this->backend->getBackend($backendid)->GetImporter(); $this->icc = $this->backend->getBackend($backendid)->GetImporter();
$res = $this->icc->ImportFolderChange($folder); $resFolder = $this->icc->ImportFolderChange($folder);
ZLog::Write(LOGLEVEL_DEBUG, 'ImportChangesCombined->ImportFolderChange() success'); ZLog::Write(LOGLEVEL_DEBUG, 'ImportChangesCombined->ImportFolderChange() success');
return $backendid.$this->backend->config['delimiter'].$res; $folder->serverid = $backendid . $this->backend->config['delimiter'] . $resFolder->serverid;
// TODO Check if move folder is supported ($parent is different). This is tricky, because you could tell e.g. a CardDAV folder to be moved to the trash of the IMAP backend on the mobile.
return $folder;
} }
/** /**
......
...@@ -557,12 +557,13 @@ class ImportChangesICS implements IImportChanges { ...@@ -557,12 +557,13 @@ class ImportChangesICS implements IImportChanges {
* @param object $folder SyncFolder * @param object $folder SyncFolder
* *
* @access public * @access public
* @return string id of the folder * @return boolean|SyncFolder false on error or a SyncFolder object with serverid and BackendId set (if available)
* @throws StatusException * @throws StatusException
*/ */
public function ImportFolderChange($folder) { public function ImportFolderChange($folder) {
$id = isset($folder->BackendId)?$folder->BackendId : false; $id = isset($folder->BackendId)?$folder->BackendId : false;
$parent = $folder->parentid; $parent = $folder->parentid;
$parent_org = $folder->parentid;
$displayname = u2wi($folder->displayname); $displayname = u2wi($folder->displayname);
$type = $folder->type; $type = $folder->type;
...@@ -596,14 +597,13 @@ class ImportChangesICS implements IImportChanges { ...@@ -596,14 +597,13 @@ class ImportChangesICS implements IImportChanges {
$props = mapi_getprops($newfolder, array(PR_SOURCE_KEY)); $props = mapi_getprops($newfolder, array(PR_SOURCE_KEY));
if (isset($props[PR_SOURCE_KEY])) { if (isset($props[PR_SOURCE_KEY])) {
$sourcekey = bin2hex($props[PR_SOURCE_KEY]); $folder->BackendId = bin2hex($props[PR_SOURCE_KEY]);
$folderid = ZPush::GetDeviceManager()->GetFolderIdForBackendId($sourcekey, true); $folder->serverid = ZPush::GetDeviceManager()->GetFolderIdForBackendId($folder->BackendId, true);
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ImportChangesICS->ImportFolderChange(): Created folder '%s' with id: '%s' backendid: '%s'", $displayname, $folderid, $sourcekey)); ZLog::Write(LOGLEVEL_DEBUG, sprintf("ImportChangesICS->ImportFolderChange(): Created folder '%s' with id: '%s' backendid: '%s'", $displayname, $folder->serverid, $folder->BackendId));
return $folderid; return $folder;
} }
else else
throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, folder created but PR_SOURCE_KEY not available: 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_SERVERERROR); throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, folder created but PR_SOURCE_KEY not available: 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_SERVERERROR);
return false;
} }
// open folder for update // open folder for update
...@@ -656,8 +656,13 @@ class ImportChangesICS implements IImportChanges { ...@@ -656,8 +656,13 @@ class ImportChangesICS implements IImportChanges {
if(! mapi_folder_copyfolder($sourceparentfolder, $entryid, $destfolder, $displayname, FOLDER_MOVE)) if(! mapi_folder_copyfolder($sourceparentfolder, $entryid, $destfolder, $displayname, FOLDER_MOVE))
throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, unable to move folder: 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_FOLDEREXISTS); throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, unable to move folder: 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_FOLDEREXISTS);
$folderProps = mapi_getprops($mfolder, array(PR_SOURCE_KEY)); // the parent changed, but we got a backendID as parent and have to return an AS folderid - the parent-backendId must be mapped at this point already
return $folderProps[PR_SOURCE_KEY]; if ($folder->parentid != 0) {
$folder->parentid = ZPush::GetDeviceManager()->GetFolderIdForBackendId($parent);
}
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ImportChangesICS->ImportFolderChange(): Moved folder '%s' with id: %s/%s from: %s to: %s/%s", $displayname, $folder->serverid, $folder->BackendId, bin2hex($props[PR_PARENT_SOURCE_KEY]), $folder->parentid, $parent_org));
return $folder;
} }
// update the display name // update the display name
...@@ -668,7 +673,7 @@ class ImportChangesICS implements IImportChanges { ...@@ -668,7 +673,7 @@ class ImportChangesICS implements IImportChanges {
throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, mapi_savechanges() failed: 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_SERVERERROR); throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, mapi_savechanges() failed: 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_SERVERERROR);
ZLog::Write(LOGLEVEL_DEBUG, "Imported changes for folder: $id"); ZLog::Write(LOGLEVEL_DEBUG, "Imported changes for folder: $id");
return $id; return true;
} }
/** /**
......
...@@ -190,7 +190,7 @@ class ChangesMemoryWrapper extends HierarchyCache implements IImportChanges, IEx ...@@ -190,7 +190,7 @@ class ChangesMemoryWrapper extends HierarchyCache implements IImportChanges, IEx
* @param SyncFolder $folder folder to be changed * @param SyncFolder $folder folder to be changed
* *
* @access public * @access public
* @return boolean * @return boolean/SyncObject status/object with the ath least the serverid of the folder set
*/ */
public function ImportFolderChange($folder) { public function ImportFolderChange($folder) {
// if the destinationImporter is set, then this folder should be processed by another importer // if the destinationImporter is set, then this folder should be processed by another importer
...@@ -204,17 +204,29 @@ class ChangesMemoryWrapper extends HierarchyCache implements IImportChanges, IEx ...@@ -204,17 +204,29 @@ class ChangesMemoryWrapper extends HierarchyCache implements IImportChanges, IEx
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->ImportFolderChange(): Set foldertype for folder '%s' from cache as it was not sent: '%s'", $folder->displayname, $folder->type)); ZLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->ImportFolderChange(): Set foldertype for folder '%s' from cache as it was not sent: '%s'", $folder->displayname, $folder->type));
} }
$ret = $this->destinationImporter->ImportFolderChange($folder); $retFolder = $this->destinationImporter->ImportFolderChange($folder);
// if the operation was sucessfull, update the HierarchyCache // if the operation was sucessfull, update the HierarchyCache
if ($ret) { if ($retFolder) {
// for folder creation, the serverid is not set and has to be updated before // if we get a folder back, we need to update some data in the cache
if (!isset($folder->serverid) || $folder->serverid == "") if (isset($retFolder->serverid) && $retFolder->serverid) {
$folder->serverid = $ret; // for folder creation, the serverid & backendid are not set and have to be updated
if (!isset($folder->serverid) || $folder->serverid == "") {
$folder->serverid = $retFolder->serverid;
if (isset($retFolder->BackendId) && $retFolder->BackendId) {
$folder->BackendId = $retFolder->BackendId;
}
}
// if the parentid changed (folder was moved) this needs to be updated as well
if ($retFolder->parentid != $folder->parentid) {
$folder->parentid = $retFolder->parentid;
}
}
$this->AddFolder($folder); $this->AddFolder($folder);
} }
return $ret; return $retFolder;
} }
// load into memory // load into memory
else { else {
......
...@@ -211,7 +211,7 @@ class ImportChangesStream implements IImportChanges { ...@@ -211,7 +211,7 @@ class ImportChangesStream implements IImportChanges {
* @param object $folder SyncFolder * @param object $folder SyncFolder
* *
* @access public * @access public
* @return string id of the folder * @return boolean/SyncObject status/object with the ath least the serverid of the folder set
*/ */
public function ImportFolderChange($folder) { public function ImportFolderChange($folder) {
// checks if the next message may cause a loop or is broken // checks if the next message may cause a loop or is broken
......
...@@ -209,7 +209,7 @@ class ImportChangesDiff extends DiffState implements IImportChanges { ...@@ -209,7 +209,7 @@ class ImportChangesDiff extends DiffState implements IImportChanges {
* @param object $folder SyncFolder * @param object $folder SyncFolder
* *
* @access public * @access public
* @return string id of the folder * @return boolean/SyncObject status/object with the ath least the serverid of the folder set
* @throws StatusException * @throws StatusException
*/ */
public function ImportFolderChange($folder) { public function ImportFolderChange($folder) {
...@@ -236,7 +236,8 @@ class ImportChangesDiff extends DiffState implements IImportChanges { ...@@ -236,7 +236,8 @@ class ImportChangesDiff extends DiffState implements IImportChanges {
if($stat) if($stat)
$this->updateState("change", $stat); $this->updateState("change", $stat);
return $stat["id"]; $folder->serverid = $stat["id"];
return $folder;
} }
/** /**
......
...@@ -121,7 +121,7 @@ interface IImportChanges extends IChanges { ...@@ -121,7 +121,7 @@ interface IImportChanges extends IChanges {
* @param object $folder SyncFolder * @param object $folder SyncFolder
* *
* @access public * @access public
* @return boolean/string status/id of the folder * @return boolean/SyncObject status/object with the ath least the serverid of the folder set
* @throws StatusException * @throws StatusException
*/ */
public function ImportFolderChange($folder); public function ImportFolderChange($folder);
......
...@@ -183,7 +183,7 @@ class FolderChange extends RequestProcessor { ...@@ -183,7 +183,7 @@ class FolderChange extends RequestProcessor {
// process incoming change // process incoming change
if (!$delete) { if (!$delete) {
// when creating, $folder->serverid is false, and the returned id is already mapped by the backend // when creating, $folder->serverid is false, and the returned id is already mapped by the backend
$serverid = $changesMem->ImportFolderChange($folder); $folder = $changesMem->ImportFolderChange($folder);
} }
else { else {
// delete folder // delete folder
...@@ -210,7 +210,7 @@ class FolderChange extends RequestProcessor { ...@@ -210,7 +210,7 @@ class FolderChange extends RequestProcessor {
self::$encoder->endTag(); self::$encoder->endTag();
self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SERVERENTRYID); self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SERVERENTRYID);
self::$encoder->content($serverid); self::$encoder->content($folder->serverid);
self::$encoder->endTag(); self::$encoder->endTag();
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment