Commit d1dfee9c authored by Sebastian Kummer's avatar Sebastian Kummer

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

Merge pull request #89 in ZP/z-push from feature/ZP-735-add-option-to-delete-hierarchy-cache to develop

* commit 'e12c6cc5':
  ZP-735 Clearify the device switch and that this is the folder hierarchy.
  ZP-735 Add option to resync only the hierarchy of a specific user, device or all. When forcing resync, delete first all states of synchronized folders and afterwards the hierarchy, so the necessary information is still available. Reset contentData & ignoredMessages of the device ONLY when removing the hierarchy synckey, not when setting a new one.
parents e80f4b93 e12c6cc5
......@@ -542,7 +542,7 @@ class ASDevice extends StateObject {
if ($folderid === false) {
$this->hierarchyUuid = $uuid;
// when unsetting the hierarchycache, also remove saved contentdata and ignoredmessages
if ($folderid === false) {
if ($folderid === false && $uuid === false) {
$this->contentData = array();
$this->ignoredMessageIds = array();
$this->ignoredMessages = array();
......
......@@ -557,13 +557,13 @@ class DeviceManager {
public function ForceFullResync() {
ZLog::Write(LOGLEVEL_INFO, "Full device resync requested");
// delete hierarchy states
StateManager::UnLinkState($this->device, false);
// delete all other uuids
foreach ($this->device->GetAllFolderIds() as $folderid)
$uuid = StateManager::UnLinkState($this->device, $folderid);
// delete hierarchy states
StateManager::UnLinkState($this->device, false);
return true;
}
......@@ -748,7 +748,7 @@ class DeviceManager {
}
/**
* Returns the User Agent. This data is consolidated with data from Request::GetUserAgent()
* Returns the User Agent. This data is consolidated with data from Request::GetUserAgent()
* and the data saved in the ASDevice.
*
* @access public
......
......@@ -429,6 +429,38 @@ class ZPushAdmin {
return true;
}
/**
* Removes the hierarchydata of a device of a user so it will be re-synchronizated.
*
* @param string $user user of the device
* @param string $devid device id which should be wiped
*
* @return boolean
* @access public
*/
static public function ResyncHierarchy($user, $devid) {
// load device data
$device = new ASDevice($devid, ASDevice::UNDEFINED, $user, ASDevice::UNDEFINED);
try {
$device->SetData(ZPush::GetStateMachine()->GetState($devid, IStateMachine::DEVICEDATA), false);
if ($device->IsNewDevice()) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncHierarchy(): data of user '%s' not synchronized on device '%s'. Aborting.",$user, $devid));
return false;
}
// remove hierarchcache, but don't update the device, as the folder states are invalidated
StateManager::UnLinkState($device, false, false);
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::ResyncHierarchy(): deleted hierarchy states of device '%s' of user '%s'", $devid, $user));
}
catch (StateNotFoundException $e) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncHierarchy(): state for device '%s' of user '%s' can not be found or saved", $devid, $user));
return false;
}
return true;
}
/**
* Clears loop detection data
*
......
......@@ -140,12 +140,14 @@ class ZPushAdminCLI {
const COMMAND_SHOWLASTSYNC = 8;
const COMMAND_RESYNCFOLDER = 9;
const COMMAND_FIXSTATES = 10;
const COMMAND_RESYNCHIERARCHY = 11;
const TYPE_OPTION_EMAIL = "email";
const TYPE_OPTION_CALENDAR = "calendar";
const TYPE_OPTION_CONTACT = "contact";
const TYPE_OPTION_TASK = "task";
const TYPE_OPTION_NOTE = "note";
const TYPE_OPTION_HIERARCHY = "hierarchy";
static private $command;
static private $user = false;
......@@ -164,24 +166,25 @@ class ZPushAdminCLI {
return "Usage:\n\tz-push-admin.php -a ACTION [options]\n\n" .
"Parameters:\n\t-a list/wipe/remove/resync/clearloop\n\t[-u] username\n\t[-d] deviceid\n\n" .
"Actions:\n" .
"\tlist\t\t\t\t Lists all devices and synchronized users\n" .
"\tlist -u USER\t\t\t Lists all devices of user USER\n" .
"\tlist -d DEVICE\t\t\t Lists all users of device DEVICE\n" .
"\tlastsync\t\t\t Lists all devices and synchronized users and the last synchronization time\n" .
"\twipe -u USER\t\t\t Remote wipes all devices of user USER\n" .
"\twipe -d DEVICE\t\t\t Remote wipes device DEVICE\n" .
"\twipe -u USER -d DEVICE\t\t Remote wipes device DEVICE of user USER\n" .
"\tremove -u USER\t\t\t Removes all state data of all devices of user USER\n" .
"\tremove -d DEVICE\t\t Removes all state data of all users synchronized on device DEVICE\n" .
"\tremove -u USER -d DEVICE\t Removes all related state data of device DEVICE of user USER\n" .
"\tresync -u USER -d DEVICE\t Resynchronizes all data of device DEVICE of user USER\n" .
"\tresync -t TYPE \t\t\t Resynchronizes all folders of type $types for all devices and users.\n" .
"\tresync -t TYPE -u USER \t\t Resynchronizes all folders of type $types for the user USER.\n" .
"\tresync -t TYPE -u USER -d DEVICE Resynchronizes all folders of type $types for a specified device and user.\n" .
"\tresync -t FOLDERID -u USER\t Resynchronize the specified folder id only. The USER should be specified for better performance.\n" .
"\tclearloop\t\t\t Clears system wide loop detection data\n" .
"\tclearloop -d DEVICE -u USER\t Clears all loop detection data of a device DEVICE and an optional user USER\n" .
"\tfixstates\t\t\t Checks the states for integrity and fixes potential issues\n" .
"\tlist\t\t\t\t\t Lists all devices and synchronized users\n" .
"\tlist -u USER\t\t\t\t Lists all devices of user USER\n" .
"\tlist -d DEVICE\t\t\t\t Lists all users of device DEVICE\n" .
"\tlastsync\t\t\t\t Lists all devices and synchronized users and the last synchronization time\n" .
"\twipe -u USER\t\t\t\t Remote wipes all devices of user USER\n" .
"\twipe -d DEVICE\t\t\t\t Remote wipes device DEVICE\n" .
"\twipe -u USER -d DEVICE\t\t\t Remote wipes device DEVICE of user USER\n" .
"\tremove -u USER\t\t\t\t Removes all state data of all devices of user USER\n" .
"\tremove -d DEVICE\t\t\t Removes all state data of all users synchronized on device DEVICE\n" .
"\tremove -u USER -d DEVICE\t\t Removes all related state data of device DEVICE of user USER\n" .
"\tresync -u USER -d DEVICE\t\t Resynchronizes all data of device DEVICE of user USER\n" .
"\tresync -t TYPE \t\t\t\t Resynchronizes all folders of type $types for all devices and users.\n" .
"\tresync -t TYPE -u USER \t\t\t Resynchronizes all folders of type $types for the user USER.\n" .
"\tresync -t TYPE -u USER -d DEVICE\t Resynchronizes all folders of type $types for a specified device and user.\n" .
"\tresync -t FOLDERID -u USER\t\t Resynchronize the specified folder id only. The USER should be specified for better performance.\n" .
"\tresync -t hierarchy -u USER -d DEVICE\t Resynchronize the folder hierarchy data for an optional USER and optional DEVICE.\n" .
"\tclearloop\t\t\t\t Clears system wide loop detection data\n" .
"\tclearloop -d DEVICE -u USER\t\t Clears all loop detection data of a device DEVICE and an optional user USER\n" .
"\tfixstates\t\t\t\t Checks the states for integrity and fixes potential issues\n" .
"\n";
}
......@@ -243,9 +246,10 @@ class ZPushAdminCLI {
self::$type !== self::TYPE_OPTION_CONTACT &&
self::$type !== self::TYPE_OPTION_TASK &&
self::$type !== self::TYPE_OPTION_NOTE &&
self::$type !== self::TYPE_OPTION_HIERARCHY &&
strlen(self::$type) !== 44) {
self::$errormessage = "Wrong 'type'. Possible values are: ".
"'".self::TYPE_OPTION_EMAIL."', '".self::TYPE_OPTION_CALENDAR."', '".self::TYPE_OPTION_CONTACT."', '".self::TYPE_OPTION_TASK."', '".self::TYPE_OPTION_NOTE."' ".
"'".self::TYPE_OPTION_EMAIL."', '".self::TYPE_OPTION_CALENDAR."', '".self::TYPE_OPTION_CONTACT."', '".self::TYPE_OPTION_TASK."', '".self::TYPE_OPTION_NOTE."', ".self::TYPE_OPTION_HIERARCHY."' ".
"or a 44 byte long folder id (as hex).";
return;
}
......@@ -300,6 +304,9 @@ class ZPushAdminCLI {
else
self::$command = self::COMMAND_RESYNCDEVICE;
}
else if (self::$type === self::TYPE_OPTION_HIERARCHY) {
self::$command = self::COMMAND_RESYNCHIERARCHY;
}
else {
self::$command = self::COMMAND_RESYNCFOLDER;
}
......@@ -410,6 +417,18 @@ class ZPushAdminCLI {
self::CommandResyncFolder();
break;
case self::COMMAND_RESYNCHIERARCHY:
if (self::$device == false && self::$user == false) {
echo "Are you sure you want to re-synchronize the hierarchy of all devices and users [y/N]: ";
$confirm = strtolower(trim(fgets(STDIN)));
if ( !($confirm === 'y' || $confirm === 'yes')) {
echo "Aborted!\n";
exit(1);
}
}
self::CommandResyncHierarchy();
break;
case self::COMMAND_CLEARLOOP:
self::CommandClearLoopDetectionData();
break;
......@@ -588,6 +607,36 @@ class ZPushAdminCLI {
}
/**
* Command "Resync hierarchy"
* Resyncs a folder type of a specific device/user or of all users
*
* @return
* @access public
*/
static public function CommandResyncHierarchy() {
// if no device is specified, search for all devices of a user. If user is not set, all devices are returned.
if (self::$device === false) {
$devicelist = ZPushAdmin::ListDevices(self::$user);
if (empty($devicelist)) {
echo "\tno devices/users found\n";
return true;
}
}
else
$devicelist = array(self::$device);
foreach ($devicelist as $deviceId) {
$users = ZPushAdmin::ListUsers($deviceId);
foreach ($users as $user) {
if (self::$user && self::$user != $user)
continue;
self::resyncHierarchy($deviceId, $user);
}
}
}
/**
* Command to clear the loop detection data
* Mobiles may enter loop detection (one-by-one synchring due to timeouts / erros).
......@@ -670,6 +719,20 @@ class ZPushAdminCLI {
echo sprintf("Resync of %d folders of type %s on device '%s' of user '%s': %s\n", count($folders), $type, $deviceId, $user, ($stat)?'Requested':ZLog::GetLastMessage(LOGLEVEL_ERROR));
}
/**
* Resynchronizes the hierarchy of a device & user
*
* @param string $deviceId the id of the device
* @param string $user the user
*
* @return
* @access private
*/
static private function resyncHierarchy($deviceId, $user) {
$stat = ZPushAdmin::ResyncHierarchy($user, $deviceId);
echo sprintf("Removing hierarchy information for resync on device '%s' of user '%s': %s\n", $deviceId, $user, ($stat)?'Requested':ZLog::GetLastMessage(LOGLEVEL_ERROR));
}
/**
* Fixes the states for potential issues
*
......
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