Commit 1877117b authored by Sebastian Kummer's avatar Sebastian Kummer

ZP-1071 Added ASDevice->SetAdditionalFolderList() reusing

ASDevice->AddAdditionalFolder(), added
ZPushAdmin::AdditionalFolderSetList() and exposed
AdditionalFolderSetList() via WebserviceDevice. 

Released under the Affero GNU General Public License (AGPL) version 3.
parent e2884686
...@@ -859,7 +859,7 @@ class ASDevice extends StateObject { ...@@ -859,7 +859,7 @@ class ASDevice extends StateObject {
* @access public * @access public
* @return boolean * @return boolean
*/ */
public function AddAdditionalFolder($store, $folderid, $name, $type, $flags) { public function AddAdditionalFolder($store, $folderid, $name, $type, $flags, $parentid = 0, $checkDups = true) {
// check if a folderid and name were sent // check if a folderid and name were sent
if (!$folderid || !$name) { if (!$folderid || !$name) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->AddAdditionalFolder(): No valid folderid ('%s') or name ('%s') sent. Aborting. ", $folderid, $name)); ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->AddAdditionalFolder(): No valid folderid ('%s') or name ('%s') sent. Aborting. ", $folderid, $name));
...@@ -887,16 +887,18 @@ class ASDevice extends StateObject { ...@@ -887,16 +887,18 @@ class ASDevice extends StateObject {
} }
// 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)
foreach($this->GetHierarchyCache()->ExportFolders() as $syncedFolderid => $folder) { if ($checkDups) {
if ($syncedFolderid === $folderid || $folder->BackendId === $folderid) { foreach($this->GetHierarchyCache()->ExportFolders() as $syncedFolderid => $folder) {
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)); if ($syncedFolderid === $folderid || $folder->BackendId === $folderid) {
return false; 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));
} return false;
}
// $folder is a SyncFolder object here // $folder is a SyncFolder object here
if ($folder->displayname == $name) { if ($folder->displayname == $name) {
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: '%s'", $name));
return false; return false;
}
} }
} }
...@@ -911,9 +913,6 @@ class ASDevice extends StateObject { ...@@ -911,9 +913,6 @@ class ASDevice extends StateObject {
); );
$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;
} }
...@@ -933,7 +932,7 @@ class ASDevice extends StateObject { ...@@ -933,7 +932,7 @@ class ASDevice extends StateObject {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->EditAdditionalFolder(): No valid folderid ('%s') or name ('%s') sent. Aborting. ", $folderid, $name)); ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->EditAdditionalFolder(): No valid folderid ('%s') or name ('%s') sent. Aborting. ", $folderid, $name));
return false; return false;
} }
// check if a folder with this ID is known // check if a folder with this ID is known
if (!isset($this->additionalfolders[$folderid])) { if (!isset($this->additionalfolders[$folderid])) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->EditAdditionalFolder(): folder can not be edited because there is no folder known with this folder id: '%s'. Add the folder first.", $folderid)); ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->EditAdditionalFolder(): folder can not be edited because there is no folder known with this folder id: '%s'. Add the folder first.", $folderid));
...@@ -991,6 +990,52 @@ class ASDevice extends StateObject { ...@@ -991,6 +990,52 @@ class ASDevice extends StateObject {
return true; return true;
} }
/**
* Sets a list of additional folders of one store to the device.
* If there are additional folders for the set_store, that are not in the list they will be removed.
*
* @param string $set_store the store where this folder is located, e.g. "SYSTEM" (for public folder) or an username/email address.
* @param array $set_folders a list of folders to be set for this user. Other existing additional folders (that are not in this list)
* will be removed. The list is an array containing folders, where each folder is an array with the following keys:
* 'folderid' (string) the folder id of the additional folder.
* 'parentid' (string) the folderid of the parent folder. If no parent folder is set or the parent folder is not defined, '0' (main folder) is used.
* 'name' (string) the name of the additional folder (has to be unique for all folders on the device).
* 'type' (string) AS foldertype of SYNC_FOLDER_TYPE_USER_*
* 'flags' (int) Additional flags, like DeviceManager::FLD_FLAGS_REPLYASUSER
*
* @access public
* @return boolean
*/
public function SetAdditionalFolderList($set_store, $set_folders) {
// remove all folders already shared for this store
$newAF = array();
$noDupsCheck = array();
foreach($this->additionalfolders as $keepFolder) {
if ($keepFolder['store'] !== $set_store) {
$newAF[] = $keepFolder;
}
else {
$noDupsCheck[$keepFolder['folderid']] = true;
}
}
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ASDevice->SetAdditionalFolderList(): cleared additional folder lists of store '%s', total %d folders, kept %d and removed %d", $set_store, count($this->additionalfolders), count($newAF), count(array_keys($noDupsCheck))));
// set remaining additional folders
$this->additionalfolders = $newAF;
// low level add
foreach($set_folders as $f) {
$status = $this->AddAdditionalFolder($set_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)));
// break if a folder can not be added
if (!$status) {
return false;
}
}
return true;
}
/** /**
* 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.
* *
......
...@@ -663,6 +663,55 @@ class ZPushAdmin { ...@@ -663,6 +663,55 @@ class ZPushAdmin {
return false; return false;
} }
/**
* Sets a list of additional folders of one store to the given device and user.
* If there are additional folders for this store, that are not in the list they will be removed.
*
* @param string $user user of the device.
* @param string $devid device id of where the folder should be set.
* @param string $set_store the store where this folder is located, e.g. "SYSTEM" (for public folder) or an username/email address.
* @param array $set_folders a list of folders to be set for this user. Other existing additional folders (that are not in this list)
* will be removed. The list is an array containing folders, where each folder is an array with the following keys:
* 'folderid' (string) the folder id of the additional folder.
* 'parentid' (string) the folderid of the parent folder. If no parent folder is set or the parent folder is not defined, '0' (main folder) is used.
* 'name' (string) the name of the additional folder (has to be unique for all folders on the device).
* 'type' (string) AS foldertype of SYNC_FOLDER_TYPE_USER_*
* 'flags' (int) Additional flags, like DeviceManager::FLD_FLAGS_REPLYASUSER
*
* @access public
* @return boolean
*/
static public function AdditionalFolderSetList($user, $devid, $set_store, $set_folders) {
// load device data
$device = new ASDevice($devid, ASDevice::UNDEFINED, $user, ASDevice::UNDEFINED);
try {
// set device data
$device->SetData(ZPush::GetStateMachine()->GetState($devid, IStateMachine::DEVICEDATA), false);
// get the last hierarchy counter
$spa = ZPush::GetStateMachine()->GetState($devid, IStateMachine::FOLDERDATA, $device->GetFolderUUID());
list($uuid, $counter) = StateManager::ParseStateKey($spa->GetSyncKey());
// instantiate hierarchycache
$device->SetHierarchyCache(ZPush::GetStateMachine()->GetState($devid, IStateMachine::HIERARCHY, $device->GetFolderUUID(), $counter, false));
if ($device->IsNewDevice()) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::AdditionalFolderSetList(): data of user '%s' not synchronized on device '%s'. Aborting.", $user, $devid));
return false;
}
$status = $device->SetAdditionalFolderList($set_store, $set_folders);
if ($status && $device->GetData() !== false) {
ZPush::GetStateMachine()->SetState($device->GetData(), $devid, IStateMachine::DEVICEDATA);
}
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::AdditionalFolderSetList(): added '%s' folders of '%s' to additional folders list of device '%s' of user '%s' with status: %s", count($set_folders), $set_store, $devid, $user, Utils::PrintAsString($status)));
return $status;
}
catch (StateNotFoundException $e) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::AdditionalFolderSetList(): state for device '%s' of user '%s' can not be found or saved", $devid, $user));
return false;
}
return false;
}
/** /**
* Clears loop detection data * Clears loop detection data
* *
......
...@@ -265,4 +265,47 @@ class WebserviceDevice { ...@@ -265,4 +265,47 @@ class WebserviceDevice {
return $status; return $status;
} }
/**
* Sets a list of additional folders of one store to the given device and the Request::GetGETUser().
* If there are additional folders for this store, that are not in the list they will be removed.
*
* @param string $deviceId device id the folder should be added to.
* @param string $set_store the store where this folder is located, e.g. "SYSTEM" (for public folder) or an username/email address.
* @param array $set_folders a list of folders to be set for this user. Other existing additional folders (that are not in this list)
* will be removed. The list is an array containing folders, where each folder is an array with the following keys:
* 'folderid' (string) the folder id of the additional folder.
* 'parentid' (string) the folderid of the parent folder. If no parent folder is set or the parent folder is not defined, '0' (main folder) is used.
* 'name' (string) the name of the additional folder (has to be unique for all folders on the device).
* 'type' (string) AS foldertype of SYNC_FOLDER_TYPE_USER_*
* 'flags' (int) Additional flags, like DeviceManager::FLD_FLAGS_REPLYASUSER
*
* @access public
* @return boolean
*/
public function AdditionalFolderSetList($deviceId, $set_store, $set_folders) {
$user = Request::GetGETUser();
$deviceId = preg_replace("/[^A-Za-z0-9]/", "", $deviceId);
array_walk($set_folders, function(&$folder) {
if (!isset($folder['folderid'])) $folder['folderid'] = "";
if (!isset($folder['parentid'])) $folder['parentid'] = "0";
if (!isset($folder['type'])) $folder['type'] = SYNC_FOLDER_TYPE_USER_MAIL;
if (!isset($folder['folderid'])) $folder['folderid'] = "";
$folder['folderid'] = preg_replace("/[^A-Za-z0-9]/", "", $folder['folderid']);
$folder['parentid'] = preg_replace("/[^A-Za-z0-9]/", "", $folder['parentid']);
$folder['type'] = preg_replace("/[^0-9]/", "", $folder['type']);
$folder['flags'] = preg_replace("/type/", "", $folder['flags']);
});
$status = ZPushAdmin::AdditionalFolderSetList($user, $deviceId, $set_store, $set_folders);
if (!$status) {
ZPush::GetTopCollector()->AnnounceInformation(ZLog::GetLastMessage(LOGLEVEL_ERROR), true);
throw new SoapFault("ERROR", ZLog::GetLastMessage(LOGLEVEL_ERROR));
}
ZLog::Write(LOGLEVEL_INFO, sprintf("WebserviceDevice::AdditionalFolderSetList(): set '%d' folders for device '%s' of user '%s': %s", count($set_folders), $deviceId, $user, Utils::PrintAsString($status)));
ZPush::GetTopCollector()->AnnounceInformation("Set additional folders", true);
return $status;
}
} }
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