mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-05-22 11:55:24 +00:00
Monotone-Parent: d0cc38cc291cb895f6e1f64d453e66215671d6a0
Monotone-Revision: 83572f5aa6453bbf0ec254ae1887286fb7e0c0a1 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2007-08-17T02:42:17 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
@@ -1,5 +1,20 @@
|
||||
2007-08-16 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* UI/MailerUI/UIxMailEditor.m ([-patchFlagsInStore]): removed
|
||||
useless stub method, of which the intention was implemented in
|
||||
SOGoDraftObject.
|
||||
([-lookupSentFolderUsingAccount]): removed obsolete method.
|
||||
([-selectedMailIdentity]): removed obsolete method.
|
||||
([-lookupSentFolderUsingFrom]): removed obsolete method.
|
||||
([-storeMailInSentFolder:_path]): removed obsolete method, of
|
||||
which the mechanism has been put in -[SOGoDraftObject sendMail]
|
||||
method.
|
||||
([UIxMailEditor -_saveFormInfo], [UIxMailEditor -defaultAction])
|
||||
([UIxMailEditor -saveAction], [UIxMailEditor -sendAction]):
|
||||
adapted algorithms to the new SOGoDraftObject methods.
|
||||
([-deleteAction]): removed method since local draft objects cannot
|
||||
be removed by the user.
|
||||
|
||||
* UI/MailerUI/UIxMailFolderActions.m ([UIxMailFolderActions
|
||||
-expungeAction]): new method replacing the one previously found in
|
||||
UIxMailListView.
|
||||
|
||||
+137
-360
@@ -24,9 +24,10 @@
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSUserDefaults.h>
|
||||
|
||||
#import <NGObjWeb/WORequest.h>
|
||||
#import <NGObjWeb/SoSubContext.h>
|
||||
#import <NGObjWeb/NSException+HTTP.h>
|
||||
#import <NGObjWeb/SoSubContext.h>
|
||||
#import <NGObjWeb/WORequest.h>
|
||||
#import <NGObjWeb/WOResponse.h>
|
||||
#import <NGExtensions/NSNull+misc.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <NGExtensions/NSString+misc.h>
|
||||
@@ -41,8 +42,9 @@
|
||||
#import <SoObjects/Mailer/SOGoMailFolder.h>
|
||||
#import <SoObjects/Mailer/SOGoMailAccount.h>
|
||||
#import <SoObjects/Mailer/SOGoMailAccounts.h>
|
||||
#import <SoObjects/Mailer/SOGoMailIdentity.h>
|
||||
#import <SoObjects/SOGo/SOGoUser.h>
|
||||
#import <SoObjects/SOGo/NSArray+Utilities.h>
|
||||
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
|
||||
#import <SOGoUI/UIxComponent.h>
|
||||
|
||||
/*
|
||||
@@ -51,9 +53,6 @@
|
||||
An mail editor component which works on SOGoDraftObject's.
|
||||
*/
|
||||
|
||||
@class NSArray, NSString;
|
||||
@class SOGoMailFolder;
|
||||
|
||||
@interface UIxMailEditor : UIxComponent
|
||||
{
|
||||
NSArray *to;
|
||||
@@ -61,7 +60,7 @@
|
||||
NSArray *bcc;
|
||||
NSString *subject;
|
||||
NSString *text;
|
||||
NSMutableArray *fromEMails;
|
||||
NSArray *fromEMails;
|
||||
NSString *from;
|
||||
SOGoMailFolder *sentFolder;
|
||||
|
||||
@@ -74,18 +73,18 @@
|
||||
|
||||
@implementation UIxMailEditor
|
||||
|
||||
static BOOL keepMailTmpFile = NO;
|
||||
static BOOL showInternetMarker = NO;
|
||||
static BOOL useLocationBasedSentFolder = NO;
|
||||
static BOOL keepMailTmpFile = NO;
|
||||
static BOOL showInternetMarker = NO;
|
||||
static BOOL useLocationBasedSentFolder = NO;
|
||||
static NSDictionary *internetMailHeaders = nil;
|
||||
static NSArray *infoKeys = nil;
|
||||
static NSArray *infoKeys = nil;
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
infoKeys = [[NSArray alloc] initWithObjects:
|
||||
@"subject", @"text", @"to", @"cc", @"bcc",
|
||||
@"subject", @"to", @"cc", @"bcc",
|
||||
@"from", @"replyTo",
|
||||
nil];
|
||||
|
||||
@@ -113,104 +112,114 @@ static NSArray *infoKeys = nil;
|
||||
{
|
||||
[sentFolder release];
|
||||
[fromEMails release];
|
||||
[from release];
|
||||
[text release];
|
||||
[from release];
|
||||
[text release];
|
||||
[subject release];
|
||||
[to release];
|
||||
[cc release];
|
||||
[bcc release];
|
||||
|
||||
[attachmentName release];
|
||||
[to release];
|
||||
[cc release];
|
||||
[bcc release];
|
||||
[attachmentName release];
|
||||
[attachmentNames release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (void) setFrom: (NSString *) _value
|
||||
- (void) setFrom: (NSString *) newFrom
|
||||
{
|
||||
ASSIGNCOPY(from, _value);
|
||||
ASSIGN (from, newFrom);
|
||||
}
|
||||
|
||||
- (NSString *) from
|
||||
{
|
||||
if (![from isNotEmpty])
|
||||
return [[[self context] activeUser] primaryEmail];
|
||||
NSDictionary *identity;
|
||||
|
||||
if (!from)
|
||||
{
|
||||
identity = [[context activeUser] primaryIdentity];
|
||||
from = [identity keysWithFormat: @"%{fullName} <%{email}>"];
|
||||
}
|
||||
|
||||
return from;
|
||||
}
|
||||
|
||||
- (void) setReplyTo: (NSString *) _ignore
|
||||
{
|
||||
}
|
||||
// - (void) setReplyTo: (NSString *) ignore
|
||||
// {
|
||||
// }
|
||||
|
||||
- (NSString *) replyTo
|
||||
{
|
||||
/* we are here for future extensibility */
|
||||
return @"";
|
||||
}
|
||||
// - (NSString *) replyTo
|
||||
// {
|
||||
// /* we are here for future extensibility */
|
||||
// return @"";
|
||||
// }
|
||||
|
||||
- (void) setSubject: (NSString *) _value
|
||||
- (void) setSubject: (NSString *) newSubject
|
||||
{
|
||||
ASSIGNCOPY(subject, _value);
|
||||
ASSIGN (subject, newSubject);
|
||||
}
|
||||
|
||||
- (NSString *) subject
|
||||
{
|
||||
return subject ? subject : @"";
|
||||
return subject;
|
||||
}
|
||||
|
||||
- (void) setText: (NSString *) _value
|
||||
- (void) setText: (NSString *) newText
|
||||
{
|
||||
ASSIGNCOPY(text, _value);
|
||||
ASSIGN (text, newText);
|
||||
}
|
||||
|
||||
- (NSString *) text
|
||||
{
|
||||
return [text isNotNull] ? text : @"";
|
||||
return text;
|
||||
}
|
||||
|
||||
- (void) setTo: (NSArray *)_value
|
||||
- (void) setTo: (NSArray *) newTo
|
||||
{
|
||||
ASSIGNCOPY(to, _value);
|
||||
if ([newTo isKindOfClass: [NSNull class]])
|
||||
newTo = nil;
|
||||
|
||||
ASSIGN (to, newTo);
|
||||
}
|
||||
|
||||
- (NSArray *) to
|
||||
{
|
||||
return [to isNotNull] ? to : [NSArray array];
|
||||
return to;
|
||||
}
|
||||
|
||||
- (void) setCc: (NSArray *) _value
|
||||
- (void) setCc: (NSArray *) newCc
|
||||
{
|
||||
ASSIGNCOPY(cc, _value);
|
||||
if ([newCc isKindOfClass: [NSNull class]])
|
||||
newCc = nil;
|
||||
|
||||
ASSIGN (cc, newCc);
|
||||
}
|
||||
|
||||
- (NSArray *) cc
|
||||
{
|
||||
return [cc isNotNull] ? cc : [NSArray array];
|
||||
return cc;
|
||||
}
|
||||
|
||||
- (void) setBcc: (NSArray *) _value
|
||||
- (void) setBcc: (NSArray *) newBcc
|
||||
{
|
||||
ASSIGNCOPY(bcc, _value);
|
||||
if ([newBcc isKindOfClass: [NSNull class]])
|
||||
newBcc = nil;
|
||||
|
||||
ASSIGN (bcc, newBcc);
|
||||
}
|
||||
|
||||
- (NSArray *) bcc
|
||||
{
|
||||
return [bcc isNotNull] ? bcc : [NSArray array];
|
||||
return bcc;
|
||||
}
|
||||
|
||||
- (BOOL) hasOneOrMoreRecipients
|
||||
{
|
||||
if ([[self to] count] > 0) return YES;
|
||||
if ([[self cc] count] > 0) return YES;
|
||||
if ([[self bcc] count] > 0) return YES;
|
||||
return NO;
|
||||
return (([to count] + [cc count] + [bcc count]) > 0);
|
||||
}
|
||||
|
||||
- (void) setAttachmentName: (NSString *) _attachmentName
|
||||
- (void) setAttachmentName: (NSString *) newAttachmentName
|
||||
{
|
||||
ASSIGN(attachmentName, _attachmentName);
|
||||
ASSIGN (attachmentName, newAttachmentName);
|
||||
}
|
||||
|
||||
- (NSString *) attachmentName
|
||||
@@ -222,223 +231,41 @@ static NSArray *infoKeys = nil;
|
||||
|
||||
- (NSArray *) fromEMails
|
||||
{
|
||||
NSEnumerator *emails;
|
||||
SOGoUser *activeUser;
|
||||
NSString *cn, *fullMail, *email;
|
||||
|
||||
NSArray *allIdentities;
|
||||
|
||||
if (!fromEMails)
|
||||
{
|
||||
fromEMails = [NSMutableArray new];
|
||||
activeUser = [context activeUser];
|
||||
cn = [activeUser cn];
|
||||
if ([cn length] == 0)
|
||||
cn = nil;
|
||||
emails = [[activeUser allEmails] objectEnumerator];
|
||||
email = [emails nextObject];
|
||||
while (email)
|
||||
{
|
||||
if (cn)
|
||||
fullMail = [NSString stringWithFormat: @"%@ <%@>", cn, email];
|
||||
else
|
||||
fullMail = email;
|
||||
[fromEMails addObject: fullMail];
|
||||
email = [emails nextObject];
|
||||
}
|
||||
allIdentities = [[context activeUser] allIdentities];
|
||||
fromEMails = [allIdentities keysWithFormat: @"%{fullName} <%{email}>"];
|
||||
[fromEMails retain];
|
||||
}
|
||||
|
||||
return fromEMails;
|
||||
}
|
||||
|
||||
/* title */
|
||||
|
||||
- (NSString *)panelTitle {
|
||||
return [self labelForKey:@"Compose Mail"];
|
||||
}
|
||||
|
||||
/* info loading */
|
||||
|
||||
- (void)loadInfo:(NSDictionary *)_info {
|
||||
- (void) loadInfo: (NSDictionary *) _info
|
||||
{
|
||||
if (![_info isNotNull]) return;
|
||||
[self debugWithFormat:@"loading info ..."];
|
||||
[self takeValuesFromDictionary:_info];
|
||||
}
|
||||
- (NSDictionary *)storeInfo {
|
||||
|
||||
- (NSDictionary *) storeInfo
|
||||
{
|
||||
[self debugWithFormat:@"storing info ..."];
|
||||
return [self valuesForKeys:infoKeys];
|
||||
}
|
||||
|
||||
/* requests */
|
||||
|
||||
- (BOOL) shouldTakeValuesFromRequest: (WORequest *) _rq
|
||||
inContext: (WOContext*) _c
|
||||
- (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
|
||||
inContext: (WOContext*) localContext
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
/* IMAP4 store */
|
||||
|
||||
- (NSException *) patchFlagsInStore
|
||||
{
|
||||
/*
|
||||
Flags we should set:
|
||||
if the draft is a reply => [message markAnswered]
|
||||
if the draft is a forward => [message addFlag:@"forwarded"]
|
||||
|
||||
This is hard, we would need to find the original message in Cyrus.
|
||||
*/
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id) lookupSentFolderUsingAccount
|
||||
{
|
||||
SOGoMailAccount *account;
|
||||
SOGoMailFolder *folder;
|
||||
|
||||
if (sentFolder != nil)
|
||||
return [sentFolder isNotNull] ? sentFolder : nil;;
|
||||
|
||||
account = [[self clientObject] mailAccountFolder];
|
||||
if ([account isKindOfClass:[NSException class]]) return account;
|
||||
|
||||
folder = [account sentFolderInContext:[self context]];
|
||||
if ([folder isKindOfClass:[NSException class]]) return folder;
|
||||
return ((sentFolder = [folder retain]));
|
||||
}
|
||||
|
||||
- (void) _presetFromBasedOnAccountsQueryParameter
|
||||
{
|
||||
/* preset the from field to the primary identity of the given account */
|
||||
/* Note: The compose action sets the 'accounts' query parameter */
|
||||
NSString *accountID;
|
||||
SOGoMailAccounts *accounts;
|
||||
SOGoMailAccount *account;
|
||||
SOGoMailIdentity *identity;
|
||||
|
||||
if (useLocationBasedSentFolder) /* from will be based on location */
|
||||
return;
|
||||
|
||||
if ([from isNotEmpty]) /* a from is already set */
|
||||
return;
|
||||
|
||||
accountID = [[[self context] request] formValueForKey:@"account"];
|
||||
if (![accountID isNotEmpty])
|
||||
return;
|
||||
|
||||
accounts = [[self clientObject] mailAccountsFolder];
|
||||
if ([accounts isExceptionOrNull])
|
||||
return; /* we don't treat this as an error but are tolerant */
|
||||
|
||||
account = [accounts lookupName:accountID inContext:[self context]
|
||||
acquire:NO];
|
||||
if ([account isExceptionOrNull])
|
||||
return; /* we don't treat this as an error but are tolerant */
|
||||
|
||||
identity = [account valueForKey:@"preferredIdentity"];
|
||||
if (![identity isNotNull]) {
|
||||
[self warnWithFormat:@"Account has no preferred identity: %@", account];
|
||||
return;
|
||||
}
|
||||
|
||||
[self setFrom: [identity email]];
|
||||
}
|
||||
|
||||
- (SOGoMailIdentity *) selectedMailIdentity
|
||||
{
|
||||
SOGoMailAccounts *accounts;
|
||||
NSEnumerator *e;
|
||||
SOGoMailIdentity *identity;
|
||||
|
||||
accounts = [[self clientObject] mailAccountsFolder];
|
||||
if ([accounts isExceptionOrNull]) 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 (sentFolder != nil)
|
||||
return [sentFolder isNotNull] ? 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]];
|
||||
|
||||
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: %@", sentFolder];
|
||||
#endif
|
||||
return sentFolder;
|
||||
}
|
||||
|
||||
- (NSException *) storeMailInSentFolder: (NSString *) _path
|
||||
{
|
||||
SOGoMailFolder *folder;
|
||||
NSData *data;
|
||||
id result;
|
||||
|
||||
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 find temporary draft file!"];
|
||||
}
|
||||
|
||||
result = [folder postData:data flags:@"seen"];
|
||||
[data release]; data = nil;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* actions */
|
||||
|
||||
- (NSDictionary *) _scanAttachmentFilenamesInRequest: (id) httpBody
|
||||
@@ -458,8 +285,8 @@ static NSArray *infoKeys = nil;
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
part = [parts objectAtIndex: count];
|
||||
header = [part headerForKey: @"content-disposition"];
|
||||
mimeType = [[part headerForKey: @"content-type"] stringValue];
|
||||
header = (NGMimeContentDispositionHeaderField *) [part headerForKey: @"content-disposition"];
|
||||
mimeType = [(NGMimeType *) [part headerForKey: @"content-type"] stringValue];
|
||||
attachment = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[header filename], @"filename",
|
||||
mimeType, @"mime-type", nil];
|
||||
@@ -506,26 +333,29 @@ static NSArray *infoKeys = nil;
|
||||
NSDictionary *info;
|
||||
NSException *error;
|
||||
BOOL success;
|
||||
SOGoDraftObject *co;
|
||||
|
||||
co = [self clientObject];
|
||||
[co fetchInfo];
|
||||
|
||||
success = YES;
|
||||
|
||||
if ([self _saveAttachments])
|
||||
{
|
||||
info = [self storeInfo];
|
||||
if (info)
|
||||
[co setHeaders: info];
|
||||
[co setText: text];
|
||||
error = [co storeInfo];
|
||||
if (error)
|
||||
{
|
||||
error = [[self clientObject] storeInfo:info];
|
||||
if (error)
|
||||
{
|
||||
[self errorWithFormat:@"failed to store draft: %@", error];
|
||||
// TODO: improve error handling
|
||||
success = NO;
|
||||
}
|
||||
[self errorWithFormat: @"failed to store draft: %@", error];
|
||||
// TODO: improve error handling
|
||||
success = NO;
|
||||
}
|
||||
}
|
||||
else
|
||||
success = NO;
|
||||
|
||||
|
||||
// TODO: wrap content
|
||||
|
||||
return success;
|
||||
@@ -543,13 +373,14 @@ static NSArray *infoKeys = nil;
|
||||
- (NSArray *) attachmentNames
|
||||
{
|
||||
NSArray *a;
|
||||
|
||||
|
||||
if (attachmentNames != nil)
|
||||
return attachmentNames;
|
||||
|
||||
|
||||
a = [[self clientObject] fetchAttachmentNames];
|
||||
a = [a sortedArrayUsingSelector:@selector(compare:)];
|
||||
a = [a sortedArrayUsingSelector: @selector (compare:)];
|
||||
attachmentNames = [a copy];
|
||||
|
||||
return attachmentNames;
|
||||
}
|
||||
|
||||
@@ -560,126 +391,72 @@ static NSArray *infoKeys = nil;
|
||||
|
||||
- (id) defaultAction
|
||||
{
|
||||
#if 0
|
||||
[self logWithFormat:@"edit action, load content from: %@",
|
||||
[self clientObject]];
|
||||
#endif
|
||||
|
||||
[self loadInfo:[[self clientObject] fetchInfo]];
|
||||
[self _presetFromBasedOnAccountsQueryParameter];
|
||||
SOGoDraftObject *co;
|
||||
|
||||
co = [self clientObject];
|
||||
[co fetchInfo];
|
||||
[self loadInfo: [co headers]];
|
||||
[self setText: [co text]];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) saveAction
|
||||
- (id <WOActionResults>) saveAction
|
||||
{
|
||||
return [self _saveFormInfo] ? self : [self failedToSaveFormResponse];
|
||||
id result;
|
||||
|
||||
if ([self _saveFormInfo])
|
||||
{
|
||||
result = [[self clientObject] save];
|
||||
if (!result)
|
||||
{
|
||||
result = [context response];
|
||||
[result setStatus: 204];
|
||||
}
|
||||
}
|
||||
else
|
||||
result = [self failedToSaveFormResponse];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSException *) validateForSend
|
||||
{
|
||||
// TODO: localize errors
|
||||
NSException *error;
|
||||
|
||||
if (![self hasOneOrMoreRecipients])
|
||||
error = [NSException exceptionWithHTTPStatus: 400 /* Bad Request */
|
||||
reason: @"Please select a recipient!"];
|
||||
else if ([[self subject] length] == 0)
|
||||
error = [NSException exceptionWithHTTPStatus: 400 /* Bad Request */
|
||||
reason: @"Please set a subject!"];
|
||||
else
|
||||
error = nil;
|
||||
|
||||
if (![self hasOneOrMoreRecipients]) {
|
||||
return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
|
||||
reason:@"Please select a recipient!"];
|
||||
}
|
||||
if ([[self subject] length] == 0) {
|
||||
return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
|
||||
reason:@"Please set a subject!"];
|
||||
}
|
||||
|
||||
return nil;
|
||||
return error;
|
||||
}
|
||||
|
||||
- (id <WOActionResults>) sendAction
|
||||
{
|
||||
NSException *error;
|
||||
NSString *mailPath;
|
||||
id <WOActionResults> result;
|
||||
|
||||
// TODO: need to validate whether we have a To etc
|
||||
|
||||
/* first, save form data */
|
||||
|
||||
if (![self _saveFormInfo])
|
||||
return [self failedToSaveFormResponse];
|
||||
|
||||
/* validate for send */
|
||||
|
||||
if ((error = [self validateForSend]) != nil) {
|
||||
id url;
|
||||
|
||||
url = [[error reason] stringByEscapingURL];
|
||||
url = [@"edit?error=" stringByAppendingString:url];
|
||||
return [self redirectToLocation:url];
|
||||
}
|
||||
|
||||
/* setup some extra headers if required */
|
||||
|
||||
/* save mail to file (so that we can upload the mail to Cyrus) */
|
||||
// TODO: all this could be handled by the SOGoDraftObject?
|
||||
|
||||
mailPath = [[self clientObject] saveMimeMessageToTemporaryFileWithHeaders: internetMailHeaders];
|
||||
|
||||
/* then, send mail */
|
||||
|
||||
if ((error = [[self clientObject] sendMimeMessageAtPath:mailPath]) != nil) {
|
||||
// TODO: improve error handling
|
||||
[[NSFileManager defaultManager] removeFileAtPath:mailPath handler:nil];
|
||||
return error;
|
||||
}
|
||||
|
||||
/* patch flags in store for replies etc */
|
||||
|
||||
if ((error = [self patchFlagsInStore]) != nil)
|
||||
return error;
|
||||
|
||||
/* finally store in Sent */
|
||||
|
||||
if ((error = [self storeMailInSentFolder:mailPath]) != nil)
|
||||
return error;
|
||||
|
||||
/* delete temporary mail file */
|
||||
|
||||
if (keepMailTmpFile)
|
||||
[self warnWithFormat:@"keeping mail file: '%@'", mailPath];
|
||||
else
|
||||
[[NSFileManager defaultManager] removeFileAtPath:mailPath handler:nil];
|
||||
mailPath = nil;
|
||||
|
||||
/* delete draft */
|
||||
|
||||
if ((error = [[self clientObject] delete]) != nil)
|
||||
return error;
|
||||
|
||||
if ([[[[self context] request] formValueForKey: @"nojs"] intValue])
|
||||
result = [self redirectToLocation: [self applicationPath]];
|
||||
else
|
||||
result = [self jsCloseWithRefreshMethod: nil];
|
||||
result = [self validateForSend];
|
||||
if (!result)
|
||||
{
|
||||
if ([self _saveFormInfo])
|
||||
{
|
||||
result = [[self clientObject] sendMail];
|
||||
if (!result)
|
||||
result = [self jsCloseWithRefreshMethod: nil];
|
||||
}
|
||||
else
|
||||
result = [self failedToSaveFormResponse];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (id) deleteAction
|
||||
{
|
||||
NSException *error;
|
||||
id page;
|
||||
|
||||
if ((error = [[self clientObject] delete]) != nil) {
|
||||
/* Note: we ignore 404: those are drafts which were not yet saved */
|
||||
if (![error httpStatus] == 404)
|
||||
return error;
|
||||
}
|
||||
|
||||
#if 1
|
||||
page = [self pageWithName:@"UIxMailWindowCloser"];
|
||||
[page takeValue:@"YES" forKey:@"refreshOpener"];
|
||||
return page;
|
||||
#else
|
||||
// TODO: if we just return nil, we produce a 500
|
||||
return [NSException exceptionWithHTTPStatus:204 /* No Content */
|
||||
reason:@"object was deleted."];
|
||||
#endif
|
||||
}
|
||||
|
||||
@end /* UIxMailEditor */
|
||||
|
||||
Reference in New Issue
Block a user