#include <SoObjects/Mailer/SOGoDraftObject.h>
#include <SoObjects/Mailer/SOGoMailFolder.h>
#include <SoObjects/Mailer/SOGoMailAccount.h>
+#include <SoObjects/Mailer/SOGoMailAccounts.h>
+#include <SoObjects/Mailer/SOGoMailIdentity.h>
#include <SoObjects/SOGo/WOContext+Agenor.h>
#include <SoObjects/SOGo/SOGoUser.h>
#include <NGMail/NGMimeMessage.h>
#include <NGMail/NGMimeMessageGenerator.h>
+#include <NGObjWeb/SoSubContext.h>
#include "common.h"
@implementation UIxMailEditor
static BOOL keepMailTmpFile = NO;
static BOOL showInternetMarker = NO;
+static BOOL useLocationBasedSentFolder = NO;
static NSDictionary *internetMailHeaders = nil;
static NSArray *infoKeys = nil;
keepMailTmpFile = [ud boolForKey:@"SOGoMailEditorKeepTmpFile"];
if (keepMailTmpFile)
NSLog(@"WARNING: keeping mail files.");
-
+
+ useLocationBasedSentFolder =
+ [ud boolForKey:@"SOGoUseLocationBasedSentFolder"];
+
/* Internet mail settings */
showInternetMarker = [ud boolForKey:@"SOGoShowInternetMarker"];
return nil;
}
-- (id)lookupSentFolder {
+- (id)lookupSentFolderUsingAccount {
SOGoMailAccount *account;
SOGoMailFolder *folder;
if (self->sentFolder != nil)
- return self;
+ return [self->sentFolder isNotNull] ? self->sentFolder : nil;;
account = [[self clientObject] mailAccountFolder];
if ([account isKindOfClass:[NSException class]]) return account;
return ((self->sentFolder = [folder retain]));
}
+- (SOGoMailIdentity *)selectedMailIdentity {
+ SOGoMailAccounts *accounts;
+ NSEnumerator *e;
+ SOGoMailIdentity *identity;
+
+ accounts = [[self clientObject] mailAccountsFolder];
+ if ([accounts isKindOfClass:[NSException class]]) return (id)accounts;
+
+ // TODO: This is still a hack because we detect the identity based on the
+ // from. In Agenor all of the identities have unique emails, but this
+ // is not required for SOGo.
+
+ if ([[self from] length] == 0)
+ return nil;
+
+ e = [[accounts fetchIdentitiesWithEmitterPermissions] objectEnumerator];
+ while ((identity = [e nextObject]) != nil) {
+ if ([[identity email] isEqualToString:[self from]])
+ return identity;
+ }
+ return nil;
+}
+
+- (id)lookupSentFolderUsingFrom {
+ // TODO: if we have the identity we could also support BCC
+ SOGoMailAccounts *accounts;
+ SOGoMailIdentity *identity;
+ SoSubContext *ctx;
+ NSString *sentFolderName;
+ NSArray *sentFolderPath;
+ NSException *error = nil;
+
+ if (self->sentFolder != nil)
+ return [self->sentFolder isNotNull] ? self->sentFolder : nil;;
+
+ identity = [self selectedMailIdentity];
+ if ([identity isKindOfClass:[NSException class]]) return identity;
+
+ if (![(sentFolderName = [identity sentFolderName]) isNotEmpty]) {
+ [self warnWithFormat:@"Identity has no sent folder name: %@", identity];
+ return nil;
+ }
+
+ // TODO: fixme, we treat the foldername as a hardcoded path from SOGoAccounts
+ // TODO: escaping of foldernames with slashes
+ // TODO: maybe the SOGoMailIdentity should have an 'account-identifier'
+ // which is used to lookup the account and _then_ perform an account
+ // local folder lookup? => would not be possible to have identities
+ // saving to different accounts.
+ sentFolderPath = [sentFolderName componentsSeparatedByString:@"/"];
+
+ accounts = [[self clientObject] mailAccountsFolder];
+ if ([accounts isKindOfClass:[NSException class]]) return (id)accounts;
+
+ ctx = [[SoSubContext alloc] initWithParentContext:[self context]];
+
+ self->sentFolder = [[accounts traversePathArray:sentFolderPath
+ inContext:ctx error:&error
+ acquire:NO] retain];
+ [ctx release]; ctx = nil;
+ if (error != nil) {
+ [self errorWithFormat:@"Sent-Folder lookup for identity %@ failed: %@",
+ identity, sentFolderPath];
+ return error;
+ }
+
+#if 0
+ [self logWithFormat:@"Sent-Folder: %@", sentFolderName];
+ [self logWithFormat:@" object: %@", self->sentFolder];
+#endif
+ return self->sentFolder;
+}
+
- (NSException *)storeMailInSentFolder:(NSString *)_path {
SOGoMailFolder *folder;
NSData *data;
id result;
- folder = [self lookupSentFolder];
+ folder = useLocationBasedSentFolder
+ ? [self lookupSentFolderUsingAccount]
+ : [self lookupSentFolderUsingFrom];
if ([folder isKindOfClass:[NSException class]]) return (id)folder;
+ if (folder == nil) return nil;
if ((data = [[NSData alloc] initWithContentsOfMappedFile:_path]) == nil) {
return [NSException exceptionWithHTTPStatus:500 /* server error */
- reason:@"could not temporary draft file!"];
+ reason:@"could not find temporary draft file!"];
}
result = [folder postData:data flags:@"seen"];
// TODO: all this could be handled by the SOGoDraftObject?
mailPath = [[self clientObject] saveMimeMessageToTemporaryFileWithHeaders:h];
-
+
/* then, send mail */
if ((error = [[self clientObject] sendMimeMessageAtPath:mailPath]) != nil) {
return error;
/* finally store in Sent */
-
+
if ((error = [self storeMailInSentFolder:mailPath]) != nil)
return error;