Commit 2bf9b18a authored by Sebastian Kummer's avatar Sebastian Kummer

ZP-907 Added TypeReal (ignored) value to SyncFolder, assign

SYNC_FOLDER_TYPE_UNKNOWN to the list of contact types, added
Utils::ChangeFolderToTypeUnknownForKoe() and
Utils::IsFolderToBeProcessedByKoe(), exporting
SYNC_FOLDER_TYPE_USER_CONTACT as SYNC_FOLDER_TYPE_UNKNOWN when
synchronizing to OL+KOE, accepting folder update when KOE is done
patching the folder, patch additional folders when type is still
SYNC_FOLDER_TYPE_UNKNOWN, prevent Sync & Ping for not yet patched
folders.

Released under the Affero GNU General Public License (AGPL) version 3.
parent 917d7a35
......@@ -193,6 +193,10 @@ class ChangesMemoryWrapper extends HierarchyCache implements IImportChanges, IEx
$cacheFolder = $this->GetFolder($folder->serverid);
$folder->type = $cacheFolder->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));
if (isset($cacheFolder->TypeReal)) {
$folder->TypeReal = $cacheFolder->TypeReal;
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->ImportFolderChange(): Set REAL foldertype for folder '%s' from cache: '%s'", $folder->displayname, $folder->TypeReal));
}
}
// KOE ZO-42: When Notes folders are updated in Outlook, it tries to update the name (that fails by default, as it's a system folder)
......@@ -200,6 +204,12 @@ class ChangesMemoryWrapper extends HierarchyCache implements IImportChanges, IEx
if (($folder->type == SYNC_FOLDER_TYPE_NOTE || $folder->type == SYNC_FOLDER_TYPE_USER_NOTE) && ZPush::GetDeviceManager()->IsKoe()) {
$retFolder = false;
}
// KOE ZP-907: When a secondary contact folder is patched (update type & change name) don't import it through the backend
elseif ($folder->type == SYNC_FOLDER_TYPE_UNKNOWN && ZPush::GetDeviceManager()->IsKoe() && !Utils::IsFolderToBeProcessedByKoe($folder)) {
ZLog::Write(LOGLEVEL_DEBUG, "ChangesMemoryWrapper->ImportFolderChange(): Rewrote folder type to real type', as KOE patched the folder");
$folder->type = $folder->TypeReal;
$retFolder = $folder;
}
// do regular folder update
else {
$retFolder = $this->destinationImporter->ImportFolderChange($folder);
......@@ -332,9 +342,16 @@ class ChangesMemoryWrapper extends HierarchyCache implements IImportChanges, IEx
$change = $this->changes[$this->step];
if ($change[0] == self::CHANGE) {
if (! $this->GetFolder($change[1]->serverid, true))
if (! $this->GetFolder($change[1]->serverid, true)) {
$change[1]->flags = SYNC_NEWMESSAGE;
// ZP-907: if we are ADDING a secondary contact folder and Outlook is connected, rewrite the type to SYNC_FOLDER_TYPE_UNKNOWN and mark the foldername
// TODO: ZP-1124 this should only be done, if the feature is enabled and the KOE version supports this feature
if ($change[1]->type == SYNC_FOLDER_TYPE_USER_CONTACT && ZPush::GetDeviceManager()->IsKoe()) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->Synchronize(): Synchronizing folder '%s' as type SYNC_FOLDER_TYPE_UNKNOWN as Outlook is not able to handle secondary contact folders", $change[1]->displayname));
$change[1] = Utils::ChangeFolderToTypeUnknownForKoe($change[1]);
}
}
$this->exportImporter->ImportFolderChange($change[1]);
}
// deletion
......
......@@ -488,6 +488,14 @@ class DeviceManager {
}
$folder = $this->getAdditionalSyncFolderObject($df['store'], $df['folderid'], $df['parentid'], $df['name'], $df['type'], $df['flags'], DeviceManager::FLD_ORIGIN_SHARED);
// adjust additional folders so it matches not yet processed KOE type UNKNOWN folders
$type = $this->device->GetFolderType($folder->serverid);
if ($type !== $folder->type && $type == SYNC_FOLDER_TYPE_UNKNOWN) {
ZLog::Write(LOGLEVEL_DEBUG, "DeviceManager->GetAdditionalUserSyncFolders(): Modifying additional folder so it matches an unprocessed KOE folder");
$folder = Utils::ChangeFolderToTypeUnknownForKoe($folder);
}
$folders[$folder->BackendId] = $folder;
}
......
......@@ -145,7 +145,7 @@ class ZPush {
self::CLASS_NAME => "SyncContact",
self::CLASS_REQUIRESPROTOCOLVERSION => true,
self::CLASS_DEFAULTTYPE => SYNC_FOLDER_TYPE_CONTACT,
self::CLASS_OTHERTYPES => array(SYNC_FOLDER_TYPE_USER_CONTACT),
self::CLASS_OTHERTYPES => array(SYNC_FOLDER_TYPE_USER_CONTACT, SYNC_FOLDER_TYPE_UNKNOWN),
),
"Calendar" => array(
self::CLASS_NAME => "SyncAppointment",
......
......@@ -309,6 +309,7 @@ define("SYNC_FOLDERHIERARCHY_IGNORE_STORE","FolderHierarchy:IgnoreStore");
define("SYNC_FOLDERHIERARCHY_IGNORE_NOBCKENDFLD","FolderHierarchy:IgnoreNoBackendFolder");
define("SYNC_FOLDERHIERARCHY_IGNORE_BACKENDID","FolderHierarchy:IgnoreBackendId");
define("SYNC_FOLDERHIERARCHY_IGNORE_FLAGS","FolderHierarchy:IgnoreFlags");
define("SYNC_FOLDERHIERARCHY_IGNORE_TYPEREAL","FolderHierarchy:TypeReal");
// MeetingResponse
define("SYNC_MEETINGRESPONSE_CALENDARID","MeetingResponse:CalendarId");
......
......@@ -123,8 +123,8 @@ class FolderChange extends RequestProcessor {
if ($changesMem->GetChangeCount() > 0)
throw new StatusException("HandleFolderChange() can not proceed as there are unprocessed hierarchy changes", SYNC_FSSTATUS_SERVERERROR);
// any additional folders can not be modified!
if ($serverid !== false && ZPush::GetAdditionalSyncFolderStore($backendid))
// any additional folders can not be modified - with exception if they are of type SYNC_FOLDER_TYPE_UNKNOWN (ZP-907)
if ($serverid !== false && ZPush::GetAdditionalSyncFolderStore($backendid) && self::$deviceManager->GetFolderTypeFromCacheById($serverid) != SYNC_FOLDER_TYPE_UNKNOWN)
throw new StatusException("HandleFolderChange() can not change additional folders which are configured", SYNC_FSSTATUS_SYSTEMFOLDER);
// switch user store if this this happens inside an additional folder
......
......@@ -114,6 +114,11 @@ class Ping extends RequestProcessor {
// check if the HierarchyCache is available, if not, trigger a HierarchySync
try {
self::$deviceManager->GetFolderClassFromCacheByID($folderid);
// ZP-907: ignore all folders with SYNC_FOLDER_TYPE_UNKNOWN
if (self::$deviceManager->GetFolderTypeFromCacheById($folderid) == SYNC_FOLDER_TYPE_UNKNOWN) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): ignoring folder id '%s' as it's of type UNKNOWN ", $folderid));
continue;
}
}
catch (NoHierarchyCacheAvailableException $nhca) {
ZLog::Write(LOGLEVEL_INFO, sprintf("HandlePing(): unknown collection '%s', triggering HierarchySync", $folderid));
......@@ -271,6 +276,11 @@ class Ping extends RequestProcessor {
* @return boolean
*/
private function isClassValid($class, $spa) {
// ZP-907: Outlook might request a ping for such a folder, but we shouldn't answer it in any way
if (Request::IsOutlook() && self::$deviceManager->GetFolderTypeFromCacheById($spa->GetFolderId()) == SYNC_FOLDER_TYPE_UNKNOWN) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): ignoring folder id '%s' as it's of type UNKNOWN ", $spa->GetFolderId()));
return false;
}
if ($class == $spa->GetContentClass() ||
// KOE ZO-42: Notes are synched as Appointments
(self::$deviceManager->IsKoe() && KOE_CAPABILITY_NOTES && $class == "Calendar" && $spa->GetContentClass() == "Notes")
......
......@@ -772,6 +772,12 @@ class Sync extends RequestProcessor {
$setupExporter = false;
}
// ZP-907: never send changes of UNKNOWN folders to an Outlook client
if (Request::IsOutlook() && self::$deviceManager->GetFolderTypeFromCacheById($spa->GetFolderId()) == SYNC_FOLDER_TYPE_UNKNOWN && $spa->HasSyncKey()) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("Sync(): no exporter setup for '%s' as type is UNKNOWN.", $spa->GetFolderId()));
$setupExporter = false;
}
// compare the folder statistics if the backend supports this
if ($setupExporter && self::$backend->HasFolderStats()) {
// check if the folder stats changed -> if not, don't setup the exporter, there are no changes!
......
......@@ -36,6 +36,7 @@ class SyncFolder extends SyncObject {
public $NoBackendFolder;
public $BackendId;
public $Flags;
public $TypeReal;
function __construct() {
$mapping = array (
......@@ -65,6 +66,8 @@ class SyncFolder extends SyncObject {
SYNC_FOLDERHIERARCHY_IGNORE_FLAGS => array ( self::STREAMER_VAR => "Flags",
self::STREAMER_TYPE => self::STREAMER_TYPE_IGNORE),
SYNC_FOLDERHIERARCHY_IGNORE_TYPEREAL => array ( self::STREAMER_VAR => "TypeReal",
self::STREAMER_TYPE => self::STREAMER_TYPE_IGNORE),
);
parent::__construct($mapping);
......
......@@ -1164,6 +1164,32 @@ class Utils {
return $data;
}
/**
* Modifies a SyncFolder object, changing the type to SYNC_FOLDER_TYPE_UNKNOWN but saving the original type.
* It also appends a zero-width UTF-8 (U+200B) character to the name, which serves as marker.
*
* @param SyncFolder $folder
* @return SyncFolder
*/
public static function ChangeFolderToTypeUnknownForKoe($folder) {
// append an zero width UTF-8 space to the name
$folder->displayname .= hex2bin("e2808b");
$folder->TypeReal = $folder->type;
$folder->type = SYNC_FOLDER_TYPE_UNKNOWN;
return $folder;
}
/**
* Checks if the displayname of the folder contains the zero-width UTF-8 (U+200B) character marker.
*
* @param SyncFolder $folder
* @return boolean
*/
public static function IsFolderToBeProcessedByKoe($folder) {
return isset($folder->displayname) && substr($folder->displayname, -3) == hex2bin("e2808b");
}
}
......
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