Commit 4260a916 authored by Sebastian Kummer's avatar Sebastian Kummer

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

Merge pull request #405 in ZP/z-push from feature/ZP-1071-open-shared-folder-api-expose-a-way to develop

* commit 'f46559f5':
  ZP-1071 Also set flags in the list (if not set).
  ZP-1071 Add documentation TODO, fixed variable names, fixed typo in regex.
  ZP-1071 Added ASDevice->SetAdditionalFolderList() reusing ASDevice->AddAdditionalFolder(), added ZPushAdmin::AdditionalFolderSetList() and exposed AdditionalFolderSetList() via WebserviceDevice.
  ZP-1071 Don't warn if the folder origin can not be determined for an unmapped folderid.
parents 3e21a96f f46559f5
......@@ -855,11 +855,12 @@ 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 $type AS foldertype of SYNC_FOLDER_TYPE_USER_*
* @param int $flags Additional flags, like DeviceManager::FLD_FLAGS_REPLYASUSER
* //TODO document $parentid and $checkDups (or remove this)
*
* @access public
* @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
if (!$folderid || !$name) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->AddAdditionalFolder(): No valid folderid ('%s') or name ('%s') sent. Aborting. ", $folderid, $name));
......@@ -887,6 +888,7 @@ class ASDevice extends StateObject {
}
// check if a folder with this ID or Name is already known on the device (regular folder)
if ($checkDups) {
foreach($this->GetHierarchyCache()->ExportFolders() as $syncedFolderid => $folder) {
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));
......@@ -899,6 +901,7 @@ class ASDevice extends StateObject {
return false;
}
}
}
// add the folder
$af = $this->additionalfolders;
......@@ -911,9 +914,6 @@ class ASDevice extends StateObject {
);
$this->additionalfolders = $af;
// generate an interger folderid for it
$id = $this->GetFolderIdForBackendId($folderid, true, DeviceManager::FLD_ORIGIN_SHARED, $name);
return true;
}
......@@ -991,6 +991,52 @@ class ASDevice extends StateObject {
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 $store the store where this folder is located, e.g. "SYSTEM" (for public folder) or an username/email address.
* @param array $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($store, $folders) {
// remove all folders already shared for this store
$newAF = array();
$noDupsCheck = array();
foreach($this->additionalfolders as $keepFolder) {
if ($keepFolder['store'] !== $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", $store, count($this->additionalfolders), count($newAF), count($noDupsCheck)));
// set remaining additional folders
$this->additionalfolders = $newAF;
// low level add
foreach($folders as $f) {
$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)));
// 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.
*
......
......@@ -500,7 +500,7 @@ class ZPushAdmin {
foreach ($device->GetAdditionalFolders() as $folder) {
$syncfolderid = $device->GetFolderIdForBackendId($folder['folderid'], false, false, null);
$folder['syncfolderid'] = $syncfolderid;
$folder['origin'] = Utils::GetFolderOriginStringFromId($syncfolderid);
$folder['origin'] = ($syncfolderid !== $folder['folderid'])?Utils::GetFolderOriginStringFromId($syncfolderid):'unknown';
$new_list[$folder['folderid']] = $folder;
}
foreach (ZPush::GetAdditionalSyncFolders() as $fid => $so) {
......@@ -513,7 +513,7 @@ class ZPushAdmin {
'syncfolderid' => $syncfolderid,
'name' => $so->displayname,
'type' => $so->type,
'origin' => Utils::GetFolderOriginStringFromId($syncfolderid),
'origin' => ($syncfolderid !== $fid)?Utils::GetFolderOriginStringFromId($syncfolderid):'unknown',
'flags' => 0, // static folders have no flags
);
}
......@@ -663,6 +663,55 @@ class ZPushAdmin {
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
*
......
......@@ -265,4 +265,47 @@ class WebserviceDevice {
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['flags'])) $folder['flags'] = 0;
$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("/[^0-9]/", "", $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