Commit 54ab8e4b authored by Sebastian Kummer's avatar Sebastian Kummer

ZP-866 Save if a new state was being confirmed and should be used by

empty sync requests. If the state is not confirmed (requested at least
once by the mobile), the old state is used and the change is potentially
being exported again.

Released under the Affero GNU General Public License (AGPL) version 3.
parent 3b7ea727
......@@ -124,13 +124,14 @@ class SyncCollections implements Iterator {
* through a backend->Setup() to check permissions.
* If this fails a StatusException will be thrown.
* @param boolean $loadHierarchy (opt) if the hierarchy sync states should be loaded, default false
* @param boolean $confirmedOnly (opt) indicates if only confirmed states should be loaded, default: false
*
* @access public
* @throws StatusException with SyncCollections::ERROR_WRONG_HIERARCHY if permission check fails
* @throws StateInvalidException if the sync state can not be found or relation between states is invalid ($loadState = true)
* @return boolean
*/
public function LoadAllCollections($overwriteLoaded = false, $loadState = false, $checkPermissions = false, $loadHierarchy = false) {
public function LoadAllCollections($overwriteLoaded = false, $loadState = false, $checkPermissions = false, $loadHierarchy = false, $confirmedOnly = false) {
$this->loadStateManager();
// this operation should not remove old state counters
......@@ -142,12 +143,12 @@ class SyncCollections implements Iterator {
continue;
// Load Collection!
if (! $this->LoadCollection($folderid, $loadState, $checkPermissions))
if (! $this->LoadCollection($folderid, $loadState, $checkPermissions, $confirmedOnly))
$invalidStates = true;
}
// load the hierarchy data - there are no permissions to verify so we just set it to false
if ($loadHierarchy && !$this->LoadCollection(false, $loadState, false))
if ($loadHierarchy && !$this->LoadCollection(false, $loadState, false, false))
throw new StatusException("Invalid states found while loading hierarchy data. Forcing hierarchy sync");
if ($invalidStates)
......@@ -164,13 +165,14 @@ class SyncCollections implements Iterator {
* @param boolean $checkPermissions (opt) if set to true each folder will pass
* through a backend->Setup() to check permissions.
* If this fails a StatusException will be thrown.
* @param boolean $confirmedOnly (opt) indicates if only confirmed states should be loaded, default: false
*
* @access public
* @throws StatusException with SyncCollections::ERROR_WRONG_HIERARCHY if permission check fails
* @throws StateInvalidException if the sync state can not be found or relation between states is invalid ($loadState = true)
* @return boolean
*/
public function LoadCollection($folderid, $loadState = false, $checkPermissions = false) {
public function LoadCollection($folderid, $loadState = false, $checkPermissions = false, $confirmedOnly = false) {
$this->loadStateManager();
try {
......@@ -207,7 +209,7 @@ class SyncCollections implements Iterator {
if ($addStatus && $loadState === true) {
try {
// make sure the hierarchy cache is loaded when we are loading hierarchy states
$this->addparms[$folderid]["state"] = $this->stateManager->GetSyncState($spa->GetLatestSyncKey(), ($folderid === false));
$this->addparms[$folderid]["state"] = $this->stateManager->GetSyncState($spa->GetLatestSyncKey($confirmedOnly), ($folderid === false));
}
catch (StateNotFoundException $snfe) {
// if we can't find the state, first we should try a sync of that folder, so
......
......@@ -8,7 +8,7 @@
*
* Created : 11.04.2011
*
* Copyright 2007 - 2013 Zarafa Deutschland GmbH
* Copyright 2007 - 2016 Zarafa Deutschland GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
......@@ -53,12 +53,14 @@ class SyncParameters extends StateObject {
const SMSOPTIONS = "SMS";
private $synckeyChanged = false;
private $confirmationChanged = false;
private $currentCPO = self::DEFAULTOPTIONS;
protected $unsetdata = array(
'uuid' => false,
'uuidcounter' => false,
'uuidnewcounter' => false,
'counterconfirmed' => false,
'folderid' => false,
'referencelifetime' => 10,
'lastsynctime' => false,
......@@ -120,6 +122,12 @@ class SyncParameters extends StateObject {
// remove newSyncKey
unset($this->uuidNewCounter);
// the counter has been requested (and that way confirmed)
if ($this->counterconfirmed == false) {
$this->counterconfirmed = true;
$this->confirmationChanged = true;
}
return true;
}
......@@ -154,6 +162,8 @@ class SyncParameters extends StateObject {
throw new FatalException("SyncParameters->SetNewSyncKey(): new SyncKey must have the same UUID as current SyncKey");
$this->uuidNewCounter = $uuidNewCounter;
$this->counterconfirmed = false;
$this->confirmationChanged = true;
$this->synckeyChanged = true;
}
......@@ -185,12 +195,14 @@ class SyncParameters extends StateObject {
* When this is called the new key becomes the current key (if a new key is available).
* The current key is then returned.
*
* @param boolean $confirmedOnly indicates if only confirmed states should be considered, default: false
*
* @access public
* @return string
*/
public function GetLatestSyncKey() {
// New becomes old
if ($this->HasUuidNewCounter()) {
public function GetLatestSyncKey($confirmedOnly = false) {
// New becomes old if available - if $confirmedOnly then the counter needs to be confirmed
if ($this->HasUuidNewCounter() && (($confirmedOnly && $this->counterconfirmed) || !$confirmedOnly)) {
$this->uuidCounter = $this->uuidNewCounter;
unset($this->uuidNewCounter);
}
......@@ -288,7 +300,7 @@ class SyncParameters extends StateObject {
*/
public function IsExporterRunRequired($currentFolderStat, $doLog = false) {
// if the backend returned false as folderstat, we have to run the exporter
if ($currentFolderStat === false) {
if ($currentFolderStat === false || $this->confirmationChanged) {
$run = true;
}
else {
......
......@@ -6,7 +6,7 @@
*
* Created : 16.02.2012
*
* Copyright 2007 - 2015 Zarafa Deutschland GmbH
* Copyright 2007 - 2016 Zarafa Deutschland GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
......@@ -63,9 +63,9 @@ class Ping extends RequestProcessor {
// read from stream to see if the symc params are being sent
$params_present = self::$decoder->getElementStartTag(SYNC_PING_PING);
// Load all collections - do load states and check permissions
// Load all collections - do load states, check permissions and allow unconfirmed states
try {
$sc->LoadAllCollections(true, true, true, true);
$sc->LoadAllCollections(true, true, true, true, false);
}
catch (StateInvalidException $siex) {
// if no params are present, indicate to send params, else do hierarchy sync
......
......@@ -165,8 +165,8 @@ class Sync extends RequestProcessor {
$spa->DelFolderStat();
}
else if ($synckey !== false) {
if ($synckey !== $spa->GetSyncKey()) {
ZLog::Write(LOGLEVEL_DEBUG, "HandleSync(): Synckey does not match latest saved for this folder, removing folderstat to force Exporter setup");
if ($synckey !== $spa->GetSyncKey() && $synckey !== $spa->GetNewSyncKey()) {
ZLog::Write(LOGLEVEL_DEBUG, "HandleSync(): Synckey does not match latest saved for this folder, removing folderstat to force Exporter setup". $spa->GetSyncKey());
$spa->DelFolderStat();
}
$spa->SetSyncKey($synckey);
......@@ -579,9 +579,9 @@ class Sync extends RequestProcessor {
if ($status == SYNC_STATUS_SUCCESS && ($emptysync === true || $partial === true) ) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleSync(): Partial or Empty sync requested. Retrieving data of synchronized folders."));
// Load all collections - do not overwrite existing (received!), load states and check permissions
// Load all collections - do not overwrite existing (received!), load states, check permissions and only load confirmed states!
try {
$sc->LoadAllCollections(false, true, true, true);
$sc->LoadAllCollections(false, true, true, true, true);
}
catch (StateInvalidException $siex) {
$status = SYNC_STATUS_INVALIDSYNCKEY;
......
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