Commit c8d16112 authored by Sebastian Kummer's avatar Sebastian Kummer

Merge pull request #406 in ZP/z-push from...

Merge pull request #406 in ZP/z-push from feature/ZP-1072-open-shared-folders-api-add-folders to develop

* commit 'bc86a936':
  ZP-1072 Save different parentids in ASDevice->AddAdditionalFolder(), consider parentid when checking for duplicate names (may not occur in the same folder), order folders correctly, transport parentids when building SyncObjects for FolderSync.
parents eaab56a1 bc86a936
...@@ -855,7 +855,8 @@ class ASDevice extends StateObject { ...@@ -855,7 +855,8 @@ class ASDevice extends StateObject {
* @param string $name the name of the additional folder (has to be unique for all folders on the device). * @param string $name the name of the additional folder (has to be unique for all folders on the device).
* @param string $type AS foldertype of SYNC_FOLDER_TYPE_USER_* * @param string $type AS foldertype of SYNC_FOLDER_TYPE_USER_*
* @param int $flags Additional flags, like DeviceManager::FLD_FLAGS_REPLYASUSER * @param int $flags Additional flags, like DeviceManager::FLD_FLAGS_REPLYASUSER
* //TODO document $parentid and $checkDups (or remove this) * @param string $parentid the parentid of this folder.
* @param boolean $checkDups indicates if duplicate names and ids should be verified. Default: true
* *
* @access public * @access public
* @return boolean * @return boolean
...@@ -879,16 +880,29 @@ class ASDevice extends StateObject { ...@@ -879,16 +880,29 @@ class ASDevice extends StateObject {
return false; return false;
} }
// check if a folder with that Name is already in the list // check if a folder with that Name is already in the list and that it's parent exists
$parentFound = false;
foreach ($this->additionalfolders as $k => $folder) { foreach ($this->additionalfolders as $k => $folder) {
if ($folder['name'] == $name) { // TODO: this parentid check should go into fixstates!
ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->AddAdditionalFolder(): folder can not be added because there is already an additional folder with the same name: '%s'", $name)); if (!isset($folder['parentid'])) $folder['parentid'] = "0";
if ($folder['name'] == $name && $folder['parentid'] == $parentid) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->AddAdditionalFolder(): folder can not be added because there is already an additional folder with the same name in the same folder: '%s'", $name));
return false; return false;
} }
if ($folder['folderid'] == $parentid) {
$parentFound = true;
}
}
if ($parentid != '0' && !$parentFound) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->AddAdditionalFolder(): folder can not be added because the parent folder '%s' can not be found: '%s'", $parentid, $folderid));
return false;
} }
// check if a folder with this ID or Name is already known on the device (regular folder) // check if a folder with this ID or Name is already known on the device (regular folder)
if ($checkDups) { if ($checkDups) {
// in order to check for the parent-ids we need a shortid
$parentShortId = $this->GetFolderIdForBackendId($parentid, false, null, null);
foreach($this->GetHierarchyCache()->ExportFolders() as $syncedFolderid => $folder) { foreach($this->GetHierarchyCache()->ExportFolders() as $syncedFolderid => $folder) {
if ($syncedFolderid === $folderid || $folder->BackendId === $folderid) { if ($syncedFolderid === $folderid || $folder->BackendId === $folderid) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->AddAdditionalFolder(): folder can not be added because there is already a folder with the same folder id synchronized: '%s'", $folderid)); ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->AddAdditionalFolder(): folder can not be added because there is already a folder with the same folder id synchronized: '%s'", $folderid));
...@@ -896,8 +910,8 @@ class ASDevice extends StateObject { ...@@ -896,8 +910,8 @@ class ASDevice extends StateObject {
} }
// $folder is a SyncFolder object here // $folder is a SyncFolder object here
if ($folder->displayname == $name) { if ($folder->displayname == $name && ($folder->parentid == $parentid || $folder->parentid == $parentShortId)) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->AddAdditionalFolder(): folder can not be added because there is already a folder with the same name synchronized: '%s'", $name)); ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->AddAdditionalFolder(): folder can not be added because there is already a folder with the same name synchronized in the same parent: '%s'", $name));
return false; return false;
} }
} }
...@@ -908,12 +922,16 @@ class ASDevice extends StateObject { ...@@ -908,12 +922,16 @@ class ASDevice extends StateObject {
$af[$folderid] = array( $af[$folderid] = array(
'store' => $store, 'store' => $store,
'folderid' => $folderid, 'folderid' => $folderid,
'parentid' => $parentid,
'name' => $name, 'name' => $name,
'type' => $type, 'type' => $type,
'flags' => $flags, 'flags' => $flags,
); );
$this->additionalfolders = $af; $this->additionalfolders = $af;
// generate an interger folderid for it
$id = $this->GetFolderIdForBackendId($folderid, true, DeviceManager::FLD_ORIGIN_SHARED, $name);
return true; return true;
} }
...@@ -1024,8 +1042,39 @@ class ASDevice extends StateObject { ...@@ -1024,8 +1042,39 @@ class ASDevice extends StateObject {
// set remaining additional folders // set remaining additional folders
$this->additionalfolders = $newAF; $this->additionalfolders = $newAF;
// low level add // transform our array in a key/value array where folderids are keys and do some basic checks
$toOrder = array();
$ordered = array();
$validTypes = array(SYNC_FOLDER_TYPE_USER_CONTACT, SYNC_FOLDER_TYPE_USER_APPOINTMENT, SYNC_FOLDER_TYPE_USER_TASK, SYNC_FOLDER_TYPE_USER_MAIL, SYNC_FOLDER_TYPE_USER_NOTE, SYNC_FOLDER_TYPE_USER_JOURNAL);
foreach($folders as $f) { foreach($folders as $f) {
// fail early
if (!$f['folderid'] || !$f['name']) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->SetAdditionalFolderList(): No valid folderid ('%s') or name ('%s') sent. Aborting. ", $f['folderid'], $f['name']));
return false;
}
// check if type is of a additional user type
if (!in_array($f['type'], $validTypes)) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->SetAdditionalFolderList(): folder (id: '%s' - name: '%s') can not be added because the specified type '%s' is not a permitted user type.", $f['folderid'], $f['name'], $f['type']));
return false;
}
$toOrder[$f['folderid']] = $f;
}
// order the array, so folders with leafs come first
$this->orderAdditionalFoldersHierarchically($toOrder, $ordered);
// if there are folders that are not be positioned in the tree, we can't add them!
if (!empty($toOrder)) {
$s = "";
foreach($toOrder as $f) {
$s .= sprintf("'%s'(%s) ", $f['name'], $f['folderid']);
}
ZLog::Write(LOGLEVEL_ERROR, "ASDevice->SetAdditionalFolderList(): cannot proceed as these folders have invalid parentids (not found): ". $s);
return false;
}
foreach($ordered as $f) {
$status = $this->AddAdditionalFolder($store, $f['folderid'], $f['name'], $f['type'], $f['flags'], $f['parentid'], !isset($noDupsCheck[$f['folderid']])); $status = $this->AddAdditionalFolder($store, $f['folderid'], $f['name'], $f['type'], $f['flags'], $f['parentid'], !isset($noDupsCheck[$f['folderid']]));
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ASDevice->SetAdditionalFolderList(): set folder '%s' in additional folders list with status: %s", $f['name'], Utils::PrintAsString($status))); ZLog::Write(LOGLEVEL_DEBUG, sprintf("ASDevice->SetAdditionalFolderList(): set folder '%s' in additional folders list with status: %s", $f['name'], Utils::PrintAsString($status)));
// break if a folder can not be added // break if a folder can not be added
...@@ -1033,10 +1082,31 @@ class ASDevice extends StateObject { ...@@ -1033,10 +1082,31 @@ class ASDevice extends StateObject {
return false; return false;
} }
} }
return true; return true;
} }
/**
* Orders a list of folders so the parents are first in the array, all leaves come afterwards.
*
* @param array $toOrderFolders an array of folders, where the folderids are keys. This array should be empty at the end.
* @param array $orderedFolders the ordered array
* @param string $parentid the parentid to start with, if not set '0' (main folders) is used.
*/
private function orderAdditionalFoldersHierarchically(&$toOrderFolders, &$orderedFolders, $parentid = '0') {
// loop through the remaining folders that need to be ordered
foreach($toOrderFolders as $folder) {
// move folders with the matching parentid to the ordered array
if ($folder['parentid'] == $parentid) {
$fid = $folder['folderid'];
$orderedFolders[$fid] = $folder;
unset($toOrderFolders[$fid]);
reset($toOrderFolders);
// call recursively to move/order the leaves as well
$this->orderAdditionalFoldersHierarchically($toOrderFolders, $orderedFolders, $fid);
}
}
}
/** /**
* Generates the AS folder hash from the backend folder id, type and name. * Generates the AS folder hash from the backend folder id, type and name.
* *
......
...@@ -499,8 +499,12 @@ class DeviceManager { ...@@ -499,8 +499,12 @@ class DeviceManager {
$df['flags'] = 0; $df['flags'] = 0;
ZLog::Write(LOGLEVEL_WARN, sprintf("DeviceManager->GetAdditionalUserSyncFolders(): Additional folder '%s' has no flags. Please run 'z-push-admin -a fixstates' to fix this issue.", $df['name'])); ZLog::Write(LOGLEVEL_WARN, sprintf("DeviceManager->GetAdditionalUserSyncFolders(): Additional folder '%s' has no flags. Please run 'z-push-admin -a fixstates' to fix this issue.", $df['name']));
} }
if (!isset($df['parentid'])) {
$df['parentid'] = '0';
ZLog::Write(LOGLEVEL_WARN, sprintf("DeviceManager->GetAdditionalUserSyncFolders(): Additional folder '%s' has no parentid. // TODO FIX: Please run 'z-push-admin -a fixstates' to fix this issue.", $df['name']));
}
$folder = $this->getAdditionalSyncFolderObject($df['store'], $df['folderid'], $df['name'], $df['type'], $df['flags'], DeviceManager::FLD_ORIGIN_SHARED); $folder = $this->getAdditionalSyncFolderObject($df['store'], $df['folderid'], $df['parentid'], $df['name'], $df['type'], $df['flags'], DeviceManager::FLD_ORIGIN_SHARED);
$folders[$folder->BackendId] = $folder; $folders[$folder->BackendId] = $folder;
} }
...@@ -508,7 +512,7 @@ class DeviceManager { ...@@ -508,7 +512,7 @@ class DeviceManager {
if (KOE_CAPABILITY_GAB && $this->IsKoe() && KOE_GAB_STORE != "" && KOE_GAB_NAME != "") { if (KOE_CAPABILITY_GAB && $this->IsKoe() && KOE_GAB_STORE != "" && KOE_GAB_NAME != "") {
// if KOE_GAB_FOLDERID is set, use it // if KOE_GAB_FOLDERID is set, use it
if (KOE_GAB_FOLDERID != "") { if (KOE_GAB_FOLDERID != "") {
$folder = $this->getAdditionalSyncFolderObject(KOE_GAB_STORE, KOE_GAB_FOLDERID, KOE_GAB_NAME, SYNC_FOLDER_TYPE_USER_APPOINTMENT, 0, DeviceManager::FLD_ORIGIN_GAB); $folder = $this->getAdditionalSyncFolderObject(KOE_GAB_STORE, KOE_GAB_FOLDERID, '0', KOE_GAB_NAME, SYNC_FOLDER_TYPE_USER_APPOINTMENT, 0, DeviceManager::FLD_ORIGIN_GAB);
$folders[$folder->BackendId] = $folder; $folders[$folder->BackendId] = $folder;
} }
else { else {
...@@ -525,7 +529,7 @@ class DeviceManager { ...@@ -525,7 +529,7 @@ class DeviceManager {
} }
if ($backendGabId) { if ($backendGabId) {
$folders[$backendGabId] = $this->getAdditionalSyncFolderObject(KOE_GAB_STORE, $backendGabId, KOE_GAB_NAME, SYNC_FOLDER_TYPE_USER_APPOINTMENT, 0, DeviceManager::FLD_ORIGIN_GAB); $folders[$backendGabId] = $this->getAdditionalSyncFolderObject(KOE_GAB_STORE, $backendGabId, '0', KOE_GAB_NAME, SYNC_FOLDER_TYPE_USER_APPOINTMENT, 0, DeviceManager::FLD_ORIGIN_GAB);
} }
} }
} }
...@@ -1191,11 +1195,11 @@ class DeviceManager { ...@@ -1191,11 +1195,11 @@ class DeviceManager {
* @access private * @access private
* @returns SyncFolder * @returns SyncFolder
*/ */
private function getAdditionalSyncFolderObject($store, $folderid, $name, $type, $flags, $folderOrigin) { private function getAdditionalSyncFolderObject($store, $folderid, $parentid, $name, $type, $flags, $folderOrigin) {
$folder = new SyncFolder(); $folder = new SyncFolder();
$folder->BackendId = $folderid; $folder->BackendId = $folderid;
$folder->serverid = $this->GetFolderIdForBackendId($folder->BackendId, true, $folderOrigin, $name); $folder->serverid = $this->GetFolderIdForBackendId($folder->BackendId, true, $folderOrigin, $name);
$folder->parentid = 0; // only top folders are supported $folder->parentid = $this->GetFolderIdForBackendId($parentid);
$folder->displayname = $name; $folder->displayname = $name;
$folder->type = $type; $folder->type = $type;
// save store as custom property which is not streamed directly to the device // save store as custom property which is not streamed directly to the device
......
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