diff --git a/NEWS b/NEWS index 35bba884d..38c6e8f3e 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,8 @@ Enhancements - Improve sync speed from Outlook by non-reprocessing already downloaded unread mails Bug fixes + - Sent mails are not longer in Drafts folder using Outlook + - Deleted mails are properly synced between Outlook profiles from the same account - Does not create a mail folder in other user's mailbox - Fix server-side crash with invalid events - Fix setting permissions for a folder with several users @@ -16,7 +18,6 @@ Bug fixes - Fix server side crash parsing rtf without color table - Weekly recurring events created in SOGo web interface are now shown in Outlook - Fix exception modifications import in recurrence series - - Sent mails are not longer in Drafts folder using Outlook - Fix server side crash parsing rtf emails with images (with word97 format) 2.2.15-zentyal2 (2015-03-16) diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index e8f25e183..07d1debe2 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -519,7 +519,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) *nextModseq; NSString *changeNumber, *uid, *messageKey; uint64_t lastModseqNbr; - EOQualifier *kvQualifier, *searchQualifier; + EOQualifier *searchQualifier; NSArray *uids, *changeNumbers; NSUInteger count, max; NSArray *fetchResults; @@ -560,14 +560,11 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) { lastModseqNbr = [lastModseq unsignedLongLongValue]; nextModseq = [NSNumber numberWithUnsignedLongLong: lastModseqNbr + 1]; - kvQualifier = [[EOKeyValueQualifier alloc] + searchQualifier = [[EOKeyValueQualifier alloc] initWithKey: @"modseq" operatorSelector: EOQualifierOperatorGreaterThanOrEqualTo value: nextModseq]; - searchQualifier = [[EOAndQualifier alloc] - initWithQualifiers: - kvQualifier, [self nonDeletedQualifier], nil]; - [kvQualifier release]; + [searchQualifier autorelease]; } else @@ -595,7 +592,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) fetchResults = [(NSDictionary *) [sogoObject fetchUIDs: uids - parts: [NSArray arrayWithObject: @"modseq"]] + parts: [NSArray arrayWithObjects: @"modseq", @"flags", nil]] objectForKey: @"fetch"]; /* NOTE: we sort items manually because Cyrus does not properly sort @@ -631,17 +628,22 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) if (!lastModseq || ([lastModseq compare: modseq] == NSOrderedAscending)) lastModseq = modseq; + + if ([[result objectForKey: @"flags"] containsObject: @"deleted"]) + [currentProperties setObject: changeNumber + forKey: @"SyncLastDeleteChangeNumber"]; } [currentProperties setObject: lastModseq forKey: @"SyncLastModseq"]; foundChange = YES; } - /* 2. we synchronise deleted UIDs */ + /* 2. we synchronise expunged UIDs */ if (initialLastModseq) { fetchResults = [(SOGoMailFolder *) sogoObject fetchUIDsOfVanishedItems: lastModseqNbr]; + max = [fetchResults count]; changeNumber = nil; @@ -769,7 +771,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) if (!messageEntry) { fetchResults = [(NSDictionary *) [sogoObject fetchUIDs: [NSArray arrayWithObject: messageUID] - parts: [NSArray arrayWithObject: @"modseq"]] + parts: [NSArray arrayWithObjects: @"modseq", @"flags", nil]] objectForKey: @"fetch"]; if ([fetchResults count] == 1) { @@ -795,6 +797,11 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) mapping = [currentProperties objectForKey: @"VersionMapping"]; [mapping setObject: modseq forKey: changeNumberStr]; + /* Store the last deleted change number if it is soft-deleted */ + if ([[result objectForKey: @"flags"] containsObject: @"deleted"]) + [currentProperties setObject: changeNumberStr + forKey: @"SyncLastDeleteChangeNumber"]; + /* Save the message */ [versionsMessage save]; return YES; @@ -1009,6 +1016,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) NSString *changeNumber; uint64_t modseq; NSDictionary *versionProperties; + EOQualifier *deletedQualifier, *kvQualifier, *searchQualifier; if (tableType == MAPISTORE_MESSAGE_TABLE) { @@ -1017,8 +1025,33 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) unsignedLongLongValue]; if (modseq > 0) { + /* Hard deleted items */ deletedUIDs = [(SOGoMailFolder *) sogoObject fetchUIDsOfVanishedItems: modseq]; + + /* Soft deleted items */ + kvQualifier = [[EOKeyValueQualifier alloc] + initWithKey: @"modseq" + operatorSelector: EOQualifierOperatorGreaterThanOrEqualTo + value: [NSNumber numberWithUnsignedLongLong: modseq]]; + deletedQualifier + = [[EOKeyValueQualifier alloc] + initWithKey: @"FLAGS" + operatorSelector: EOQualifierOperatorContains + value: [NSArray arrayWithObject: @"Deleted"]]; + + searchQualifier = [[EOAndQualifier alloc] + initWithQualifiers: + kvQualifier, deletedQualifier, nil]; + + deletedUIDs = [deletedUIDs arrayByAddingObjectsFromArray: + [sogoObject fetchUIDsMatchingQualifier: searchQualifier + sortOrdering: nil]]; + + [deletedQualifier release]; + [kvQualifier release]; + [searchQualifier release]; + deletedKeys = [deletedUIDs stringsWithFormat: @"%@.eml"]; if ([deletedUIDs count] > 0) {