mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-03-06 07:36:24 +00:00
merge of 'baf4c7f8461dec960162ae0da21047d576421c14'
and 'fefb3f05edb2d5e5ba63661ae145d0369e47b444' Monotone-Parent: baf4c7f8461dec960162ae0da21047d576421c14 Monotone-Parent: fefb3f05edb2d5e5ba63661ae145d0369e47b444 Monotone-Revision: 9ef1fb2c66953b8ada0d55d0eec183621a71ebab Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2007-09-11T20:58:35 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
57
ChangeLog
57
ChangeLog
@@ -1,3 +1,60 @@
|
||||
2007-09-11 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* SoObjects/SOGo/SOGoFolder.m ([SOGoFolder
|
||||
+folderWithName:aNameandDisplayName:aDisplayNameinContainer:aContainer]):
|
||||
new method.
|
||||
([SOGoFolder -displayName]): new method.
|
||||
([SOGoFolder -delete]): accept to proceed only if nameInContainer
|
||||
!= "personal".
|
||||
|
||||
* SoObjects/Contacts/SOGoContactLDAPFolder.m
|
||||
([SOGoContactLDAPFolder
|
||||
+folderWithName:aNameandDisplayName:aDisplayNameinContainer:aContainer]):
|
||||
renamed from "contactFolderWithName..." for compatibility with SOGoFolder.
|
||||
|
||||
* SoObjects/Contacts/SOGoContactGCSFolder.m ([SOGoContactGCSFolder
|
||||
+contactFolderWithName:aNameandDisplayName:aDisplayNameinContainer:aContainer]):
|
||||
removed method, reimplemented in SOGoFolder.
|
||||
([SOGoContactGCSFolder -displayName]): removed method,
|
||||
reimplemented in SOGoFolder.
|
||||
([-delete]): removed method, modified in SOGoFolder.
|
||||
|
||||
* SoObjects/Contacts/SOGoContactFolders.[hm]: modified class to be
|
||||
a subclass of SOGoParentFolder.
|
||||
|
||||
* SoObjects/SOGo/SOGoParentFolder.[hm]: new class module derived
|
||||
from SOGoContactFolders and modified to be more content-independent.
|
||||
|
||||
* UI/MailerUI/UIxMailActions.m ([UIxMailActions -markMessageUnreadAction])
|
||||
([UIxMailActions -markMessageReadAction]): new methods moved from
|
||||
UIxMailListView and adapted to invoke the client object directly,
|
||||
since the previous versions had to to a lookup from the parent
|
||||
SOGoMailFolder.
|
||||
|
||||
* UI/MailerUI/UIxMailListView.m ([-markMessageUnreadAction]): move
|
||||
method into UIxMailActions.
|
||||
([-markMessageReadAction]): same as above.
|
||||
([-viewAction]): removed useless method.
|
||||
([-javaScriptOK]): removed useless method.
|
||||
([-isJavaScriptRequest]): removed useless method.
|
||||
([-lookupActiveMessage]): removed useless method.
|
||||
|
||||
* UI/Common/WODirectAction+SOGo.m ([WODirectAction
|
||||
-responseWithStatus:status]): new method that returns a WOResponse
|
||||
initialized with the specified status code.
|
||||
([WODirectAction -responseWith204]): new method that invokes the
|
||||
above one with "204" as parameter.
|
||||
([WODirectAction -redirectToLocation:newLocation]): rewrote method
|
||||
to make use of -responseWithStatus:.
|
||||
|
||||
* UI/SOGoUI/UIxComponent.m ([UIxComponent -responseWith204]): new
|
||||
method that returns a WOResponse initialized with the 204 status
|
||||
code.
|
||||
|
||||
* UI/MailerUI/UIxMailListView.m ([UIxMailListView -sortedUIDs]):
|
||||
always use a "not deleted" search qualifier along with the user
|
||||
qualifier (if present).
|
||||
|
||||
2007-09-10 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* UI/Contacts/UIxContactFoldersView.m ([UIxContactFoldersView
|
||||
|
||||
@@ -43,16 +43,6 @@
|
||||
|
||||
@protocol SOGoContactFolder <NSObject>
|
||||
|
||||
+ (id <SOGoContactFolder>) contactFolderWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (SOGoObject *) aContainer;
|
||||
|
||||
- (id <SOGoContactFolder>) initWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (SOGoObject *) aContainer;
|
||||
|
||||
- (NSString *) displayName;
|
||||
|
||||
- (NSArray *) lookupContactsWithFilter: (NSString *) filter
|
||||
sortBy: (NSString *) sortKey
|
||||
ordering: (NSComparisonResult) sortOrdering;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SOGoContactFolders.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006 Inverse groupe conseil
|
||||
* Copyright (C) 2006, 2007 Inverse groupe conseil
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
@@ -23,25 +23,9 @@
|
||||
#ifndef SOGOCONTACTFOLDERS_H
|
||||
#define SOGOCONTACTFOLDERS_H
|
||||
|
||||
#import <SOGo/SOGoObject.h>
|
||||
#import <SoObjects/SOGo/SOGoParentFolder.h>
|
||||
|
||||
@class NSMutableDictionary;
|
||||
@class NSString;
|
||||
@class WOResponse;
|
||||
|
||||
@interface SOGoContactFolders : SOGoObject
|
||||
{
|
||||
NSMutableDictionary *contactFolders;
|
||||
NSString *OCSPath;
|
||||
}
|
||||
|
||||
- (NSString *) defaultSourceName;
|
||||
|
||||
- (void) setBaseOCSPath: (NSString *) newOCSPath;
|
||||
|
||||
- (NSArray *) contactFolders;
|
||||
|
||||
- (WOResponse *) newFolderWithName: (NSString *) name;
|
||||
@interface SOGoContactFolders : SOGoParentFolder
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SOGoContactFolders.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006 Inverse groupe conseil
|
||||
* Copyright (C) 2006, 2007 Inverse groupe conseil
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
@@ -20,7 +20,6 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* exchange folder types: */
|
||||
/* MailItems IPF.Note
|
||||
ContactItems IPF.Contact
|
||||
AppointmentItems IPF.Appointment
|
||||
@@ -28,23 +27,25 @@
|
||||
TaskItems IPF.Task
|
||||
JournalItems IPF.Journal */
|
||||
|
||||
#import <Foundation/NSDictionary.h>
|
||||
// #import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSEnumerator.h>
|
||||
|
||||
#import <NGObjWeb/NSException+HTTP.h>
|
||||
#import <NGObjWeb/WOApplication.h>
|
||||
#import <NGObjWeb/WOContext.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGObjWeb/WOResponse.h>
|
||||
#import <NGObjWeb/SoUser.h>
|
||||
// #import <NGObjWeb/NSException+HTTP.h>
|
||||
// #import <NGObjWeb/WOApplication.h>
|
||||
// #import <NGObjWeb/WOContext.h>
|
||||
// #import <NGObjWeb/WOContext+SoObjects.h>
|
||||
// #import <NGObjWeb/WOResponse.h>
|
||||
// #import <NGObjWeb/SoUser.h>
|
||||
|
||||
#import <GDLContentStore/GCSFolderManager.h>
|
||||
#import <GDLContentStore/GCSChannelManager.h>
|
||||
#import <GDLAccess/EOAdaptorChannel.h>
|
||||
#import <GDLContentStore/NSURL+GCS.h>
|
||||
// #import <GDLContentStore/GCSFolderManager.h>
|
||||
// #import <GDLContentStore/GCSChannelManager.h>
|
||||
// #import <GDLAccess/EOAdaptorChannel.h>
|
||||
// #import <GDLContentStore/NSURL+GCS.h>
|
||||
|
||||
#import <SoObjects/SOGo/LDAPUserManager.h>
|
||||
#import <SoObjects/SOGo/SOGoPermissions.h>
|
||||
// #import <SoObjects/SOGo/SOGoPermissions.h>
|
||||
|
||||
#import "SOGoContactGCSFolder.h"
|
||||
#import "SOGoContactLDAPFolder.h"
|
||||
@@ -52,89 +53,14 @@
|
||||
|
||||
@implementation SOGoContactFolders
|
||||
|
||||
- (id) init
|
||||
+ (NSString *) gcsFolderType
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
contactFolders = nil;
|
||||
OCSPath = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
return @"Contact";
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
+ (Class) subFolderClass
|
||||
{
|
||||
if (contactFolders)
|
||||
[contactFolders release];
|
||||
if (OCSPath)
|
||||
[OCSPath release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) _fetchPersonalFolders: (NSString *) sql
|
||||
withChannel: (EOAdaptorChannel *) fc
|
||||
{
|
||||
NSArray *attrs;
|
||||
NSDictionary *row;
|
||||
SOGoContactGCSFolder *ab;
|
||||
BOOL hasPersonal;
|
||||
NSString *key, *path;
|
||||
|
||||
hasPersonal = NO;
|
||||
[fc evaluateExpressionX: sql];
|
||||
attrs = [fc describeResults: NO];
|
||||
row = [fc fetchAttributes: attrs withZone: NULL];
|
||||
while (row)
|
||||
{
|
||||
ab = [SOGoContactGCSFolder
|
||||
contactFolderWithName: [row objectForKey: @"c_path4"]
|
||||
andDisplayName: [row objectForKey: @"c_foldername"]
|
||||
inContainer: self];
|
||||
key = [row objectForKey: @"c_path4"];
|
||||
hasPersonal = (hasPersonal || [key isEqualToString: @"personal"]);
|
||||
[ab setOCSPath: [NSString stringWithFormat: @"%@/%@",
|
||||
OCSPath, key]];
|
||||
[contactFolders setObject: ab forKey: key];
|
||||
row = [fc fetchAttributes: attrs withZone: NULL];
|
||||
}
|
||||
|
||||
if (!hasPersonal)
|
||||
{
|
||||
ab = [SOGoContactGCSFolder contactFolderWithName: @"personal"
|
||||
andDisplayName: @"Contacts"
|
||||
inContainer: self];
|
||||
path = [NSString stringWithFormat:
|
||||
@"/Users/%@/Contacts/personal",
|
||||
[self ownerInContext: context]];
|
||||
[ab setOCSPath: path];
|
||||
[contactFolders setObject: ab forKey: @"personal"];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) appendPersonalSources
|
||||
{
|
||||
GCSChannelManager *cm;
|
||||
EOAdaptorChannel *fc;
|
||||
NSURL *folderLocation;
|
||||
NSString *sql;
|
||||
|
||||
cm = [GCSChannelManager defaultChannelManager];
|
||||
folderLocation
|
||||
= [[GCSFolderManager defaultFolderManager] folderInfoLocation];
|
||||
fc = [cm acquireOpenChannelForURL: folderLocation];
|
||||
if (fc)
|
||||
{
|
||||
sql = [NSString
|
||||
stringWithFormat: (@"SELECT c_path4, c_foldername FROM %@"
|
||||
@" WHERE c_path2 = '%@'"
|
||||
@" AND c_folder_type = 'Contact'"),
|
||||
[folderLocation gcsTableName], [self ownerInContext: context]];
|
||||
[self _fetchPersonalFolders: sql withChannel: fc];
|
||||
[cm releaseChannel: fc];
|
||||
// sql = [sql stringByAppendingFormat:@" WHERE %@ = '%@'",
|
||||
// uidColumnName, [self uid]];
|
||||
}
|
||||
return [SOGoContactGCSFolder class];
|
||||
}
|
||||
|
||||
- (void) appendSystemSources
|
||||
@@ -150,119 +76,13 @@
|
||||
while (currentSourceID)
|
||||
{
|
||||
displayName = [um displayNameForSourceWithID: currentSourceID];
|
||||
currentFolder = [SOGoContactLDAPFolder contactFolderWithName: currentSourceID
|
||||
currentFolder = [SOGoContactLDAPFolder folderWithName: currentSourceID
|
||||
andDisplayName: displayName
|
||||
inContainer: self];
|
||||
[currentFolder setLDAPSource: [um sourceWithID: currentSourceID]];
|
||||
[contactFolders setObject: currentFolder forKey: currentSourceID];
|
||||
[subFolders setObject: currentFolder forKey: currentSourceID];
|
||||
currentSourceID = [sourceIDs nextObject];
|
||||
}
|
||||
}
|
||||
|
||||
- (WOResponse *) newFolderWithName: (NSString *) name
|
||||
{
|
||||
SOGoContactGCSFolder *newFolder;
|
||||
WOResponse *response;
|
||||
|
||||
newFolder = [SOGoContactGCSFolder contactFolderWithName: name
|
||||
andDisplayName: name
|
||||
inContainer: self];
|
||||
if ([newFolder isKindOfClass: [NSException class]])
|
||||
response = (WOResponse *) newFolder;
|
||||
else
|
||||
{
|
||||
[newFolder setOCSPath: [NSString stringWithFormat: @"%@/%@",
|
||||
OCSPath, name]];
|
||||
if ([newFolder create])
|
||||
{
|
||||
response = [WOResponse new];
|
||||
[response setStatus: 201];
|
||||
[response autorelease];
|
||||
}
|
||||
else
|
||||
response = [NSException exceptionWithHTTPStatus: 400
|
||||
reason: @"The new folder could not be created"];
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
- (void) initContactSources
|
||||
{
|
||||
if (!contactFolders)
|
||||
{
|
||||
contactFolders = [NSMutableDictionary new];
|
||||
[self appendPersonalSources];
|
||||
[self appendSystemSources];
|
||||
}
|
||||
}
|
||||
|
||||
- (id) lookupName: (NSString *) name
|
||||
inContext: (WOContext *) lookupContext
|
||||
acquire: (BOOL) acquire
|
||||
{
|
||||
id obj;
|
||||
|
||||
/* first check attributes directly bound to the application */
|
||||
obj = [super lookupName: name inContext: lookupContext acquire: NO];
|
||||
if (!obj)
|
||||
{
|
||||
if (!contactFolders)
|
||||
[self initContactSources];
|
||||
|
||||
obj = [contactFolders objectForKey: name];
|
||||
if (!obj)
|
||||
obj = [NSException exceptionWithHTTPStatus: 404];
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
- (NSArray *) toManyRelationshipKeys
|
||||
{
|
||||
if (!contactFolders)
|
||||
[self initContactSources];
|
||||
|
||||
return [contactFolders allKeys];
|
||||
}
|
||||
|
||||
- (NSArray *) contactFolders
|
||||
{
|
||||
if (!contactFolders)
|
||||
[self initContactSources];
|
||||
|
||||
return [contactFolders allValues];
|
||||
}
|
||||
|
||||
/* acls */
|
||||
- (NSArray *) aclsForUser: (NSString *) uid
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL) davIsCollection
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *) davContentType
|
||||
{
|
||||
return @"httpd/unix-directory";
|
||||
}
|
||||
|
||||
- (void) setBaseOCSPath: (NSString *) newOCSPath
|
||||
{
|
||||
if (OCSPath)
|
||||
[OCSPath release];
|
||||
OCSPath = newOCSPath;
|
||||
if (OCSPath)
|
||||
[OCSPath retain];
|
||||
}
|
||||
|
||||
/* web interface */
|
||||
- (NSString *) defaultSourceName
|
||||
{
|
||||
return @"personal";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -30,9 +30,6 @@
|
||||
@class NSString;
|
||||
|
||||
@interface SOGoContactGCSFolder : SOGoFolder <SOGoContactFolder>
|
||||
{
|
||||
NSString *displayName;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -41,47 +41,11 @@
|
||||
|
||||
@implementation SOGoContactGCSFolder
|
||||
|
||||
+ (id <SOGoContactFolder>) contactFolderWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (SOGoObject *) aContainer
|
||||
{
|
||||
SOGoContactGCSFolder *folder;
|
||||
|
||||
folder = [[self alloc] initWithName: aName
|
||||
andDisplayName: aDisplayName
|
||||
inContainer: aContainer];
|
||||
[folder autorelease];
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[displayName release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id <SOGoContactFolder>) initWithName: (NSString *) newName
|
||||
andDisplayName: (NSString *) newDisplayName
|
||||
inContainer: (SOGoObject *) newContainer
|
||||
{
|
||||
if ((self = [self initWithName: newName
|
||||
inContainer: newContainer]))
|
||||
ASSIGN (displayName, newDisplayName);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) folderIsMandatory
|
||||
{
|
||||
return [nameInContainer isEqualToString: @"personal"];
|
||||
}
|
||||
|
||||
- (NSString *) displayName
|
||||
{
|
||||
return displayName;
|
||||
}
|
||||
|
||||
/* name lookup */
|
||||
|
||||
- (id <SOGoContactObject>) lookupContactWithId: (NSString *) recordId
|
||||
@@ -105,7 +69,6 @@
|
||||
BOOL isPut;
|
||||
|
||||
isPut = NO;
|
||||
/* first check attributes directly bound to the application */
|
||||
obj = [super lookupName:_key inContext:_ctx acquire:NO];
|
||||
if (!obj)
|
||||
{
|
||||
@@ -273,14 +236,6 @@
|
||||
return @"vcard-collection";
|
||||
}
|
||||
|
||||
- (NSException *) delete
|
||||
{
|
||||
return (([nameInContainer isEqualToString: @"personal"])
|
||||
? [NSException exceptionWithHTTPStatus: 403
|
||||
reason: @"the 'personal' folder cannot be deleted"]
|
||||
: [super delete]);
|
||||
}
|
||||
|
||||
// /* GET */
|
||||
|
||||
// - (id) GETAction: (id)_ctx
|
||||
|
||||
@@ -37,9 +37,12 @@
|
||||
BOOL ignoreSoObjectHunger;
|
||||
}
|
||||
|
||||
- (id <SOGoContactFolder>) initWithName: (NSString *) newName
|
||||
andDisplayName: (NSString *) newDisplayName
|
||||
inContainer: (SOGoObject *) newContainer;
|
||||
+ (id) folderWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (id) aContainer;
|
||||
- (id) initWithName: (NSString *) newName
|
||||
andDisplayName: (NSString *) newDisplayName
|
||||
inContainer: (id) newContainer;
|
||||
- (void) setLDAPSource: (LDAPSource *) newLdapSource;
|
||||
|
||||
@end
|
||||
|
||||
@@ -41,11 +41,11 @@
|
||||
|
||||
@implementation SOGoContactLDAPFolder
|
||||
|
||||
+ (id <SOGoContactFolder>) contactFolderWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (SOGoObject *) aContainer
|
||||
+ (id) folderWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (id) aContainer
|
||||
{
|
||||
SOGoContactLDAPFolder *folder;
|
||||
id folder;
|
||||
|
||||
folder = [[self alloc] initWithName: aName
|
||||
andDisplayName: aDisplayName
|
||||
@@ -68,9 +68,9 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id <SOGoContactFolder>) initWithName: (NSString *) newName
|
||||
andDisplayName: (NSString *) newDisplayName
|
||||
inContainer: (SOGoObject *) newContainer
|
||||
- (id) initWithName: (NSString *) newName
|
||||
andDisplayName: (NSString *) newDisplayName
|
||||
inContainer: (id) newContainer
|
||||
{
|
||||
if ((self = [self initWithName: newName
|
||||
inContainer: newContainer]))
|
||||
|
||||
@@ -21,8 +21,9 @@ FHS_HEADER_DIRS = SOGo
|
||||
|
||||
libSOGo_HEADER_FILES = \
|
||||
SOGoObject.h \
|
||||
SOGoFolder.h \
|
||||
SOGoContentObject.h \
|
||||
SOGoFolder.h \
|
||||
SOGoParentFolder.h \
|
||||
SOGoUserFolder.h \
|
||||
SOGoGroupsFolder.h \
|
||||
SOGoGroupFolder.h \
|
||||
@@ -50,8 +51,9 @@ libSOGo_HEADER_FILES = \
|
||||
|
||||
libSOGo_OBJC_FILES = \
|
||||
SOGoObject.m \
|
||||
SOGoFolder.m \
|
||||
SOGoContentObject.m \
|
||||
SOGoFolder.m \
|
||||
SOGoParentFolder.m \
|
||||
SOGoUserFolder.m \
|
||||
SOGoGroupsFolder.m \
|
||||
SOGoGroupFolder.m \
|
||||
|
||||
@@ -43,7 +43,8 @@
|
||||
|
||||
@interface SOGoFolder : SOGoObject
|
||||
{
|
||||
NSString *ocsPath;
|
||||
NSString *displayName;
|
||||
NSString *ocsPath;
|
||||
GCSFolder *ocsFolder;
|
||||
NSMutableDictionary *aclCache;
|
||||
}
|
||||
@@ -52,6 +53,15 @@
|
||||
|
||||
/* accessors */
|
||||
|
||||
+ (id) folderWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (id) aContainer;
|
||||
- (id) initWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (id) aContainer;
|
||||
|
||||
- (NSString *) displayName;
|
||||
|
||||
- (void) setOCSPath: (NSString *)_Path;
|
||||
- (NSString *) ocsPath;
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#import <Foundation/NSKeyValueCoding.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
|
||||
#import <NGObjWeb/NSException+HTTP.h>
|
||||
#import <NGObjWeb/SoObject.h>
|
||||
#import <NGObjWeb/SoObject+SoDAV.h>
|
||||
#import <NGObjWeb/SoSelectorInvocation.h>
|
||||
@@ -85,14 +86,30 @@ static NSString *defaultUserID = @"<default>";
|
||||
}
|
||||
sequence++;
|
||||
f = [[NSDate date] timeIntervalSince1970];
|
||||
|
||||
return [NSString stringWithFormat:@"%0X-%0X-%0X-%0X",
|
||||
pid, *(int *)&f, sequence++, random];
|
||||
pid, (int) f, sequence++, random];
|
||||
}
|
||||
|
||||
+ (id) folderWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (id) aContainer
|
||||
{
|
||||
id newFolder;
|
||||
|
||||
newFolder = [[self alloc] initWithName: aName
|
||||
andDisplayName: aDisplayName
|
||||
inContainer: aContainer];
|
||||
[newFolder autorelease];
|
||||
|
||||
return newFolder;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
displayName = nil;
|
||||
ocsPath = nil;
|
||||
ocsFolder = nil;
|
||||
aclCache = [NSMutableDictionary new];
|
||||
@@ -101,11 +118,23 @@ static NSString *defaultUserID = @"<default>";
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (id) aContainer
|
||||
{
|
||||
if ((self = [self initWithName: aName
|
||||
inContainer: aContainer]))
|
||||
ASSIGN (displayName, aDisplayName);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[ocsFolder release];
|
||||
[ocsPath release];
|
||||
[aclCache release];
|
||||
[displayName release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -154,6 +183,11 @@ static NSString *defaultUserID = @"<default>";
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSString *) displayName
|
||||
{
|
||||
return displayName;
|
||||
}
|
||||
|
||||
- (GCSFolder *) ocsFolder
|
||||
{
|
||||
GCSFolder *folder;
|
||||
@@ -196,7 +230,15 @@ static NSString *defaultUserID = @"<default>";
|
||||
|
||||
- (NSException *) delete
|
||||
{
|
||||
return [[self folderManager] deleteFolderAtPath: ocsPath];
|
||||
NSException *error;
|
||||
|
||||
if ([nameInContainer isEqualToString: @"personal"])
|
||||
error = [NSException exceptionWithHTTPStatus: 403
|
||||
reason: @"the 'personal' folder cannot be deleted"];
|
||||
else
|
||||
error = [[self folderManager] deleteFolderAtPath: ocsPath];
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
- (NSArray *) fetchContentObjectNames
|
||||
|
||||
50
SoObjects/SOGo/SOGoParentFolder.h
Normal file
50
SoObjects/SOGo/SOGoParentFolder.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* SOGoParentFolder.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006, 2007 Inverse groupe conseil
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef SOGOPARENTFOLDERS_H
|
||||
#define SOGOPARENTFOLDERS_H
|
||||
|
||||
#import "SOGoObject.h"
|
||||
|
||||
@class NSMutableDictionary;
|
||||
@class NSString;
|
||||
@class WOResponse;
|
||||
|
||||
@interface SOGoParentFolder : SOGoObject
|
||||
{
|
||||
NSMutableDictionary *subFolders;
|
||||
NSString *OCSPath;
|
||||
Class subFolderClass;
|
||||
}
|
||||
|
||||
+ (NSString *) gcsFolderType;
|
||||
+ (Class) subFolderClass;
|
||||
|
||||
- (void) setBaseOCSPath: (NSString *) newOCSPath;
|
||||
|
||||
- (NSArray *) subFolders;
|
||||
|
||||
- (NSException *) newFolderWithName: (NSString *) name;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* SOGOPARENTFOLDERS_H */
|
||||
240
SoObjects/SOGo/SOGoParentFolder.m
Normal file
240
SoObjects/SOGo/SOGoParentFolder.m
Normal file
@@ -0,0 +1,240 @@
|
||||
/* SOGoParentFolder.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006, 2007 Inverse groupe conseil
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import <NGObjWeb/NSException+HTTP.h>
|
||||
#import <GDLContentStore/GCSChannelManager.h>
|
||||
#import <GDLContentStore/GCSFolderManager.h>
|
||||
#import <GDLContentStore/NSURL+GCS.h>
|
||||
#import <GDLAccess/EOAdaptorChannel.h>
|
||||
|
||||
#import "SOGoFolder.h"
|
||||
|
||||
#import "SOGoParentFolder.h"
|
||||
|
||||
@implementation SOGoParentFolder
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
subFolders = nil;
|
||||
OCSPath = nil;
|
||||
subFolderClass = Nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[subFolders release];
|
||||
[OCSPath release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
+ (Class) subFolderClass
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return Nil;
|
||||
}
|
||||
|
||||
+ (NSString *) gcsFolderType
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void) setBaseOCSPath: (NSString *) newOCSPath
|
||||
{
|
||||
ASSIGN (OCSPath, newOCSPath);
|
||||
}
|
||||
|
||||
- (void) _fetchPersonalFolders: (NSString *) sql
|
||||
withChannel: (EOAdaptorChannel *) fc
|
||||
{
|
||||
NSArray *attrs;
|
||||
NSDictionary *row;
|
||||
SOGoFolder *folder;
|
||||
BOOL hasPersonal;
|
||||
NSString *key, *path;
|
||||
|
||||
if (!subFolderClass)
|
||||
subFolderClass = [[self class] subFolderClass];
|
||||
|
||||
hasPersonal = NO;
|
||||
[fc evaluateExpressionX: sql];
|
||||
attrs = [fc describeResults: NO];
|
||||
row = [fc fetchAttributes: attrs withZone: NULL];
|
||||
while (row)
|
||||
{
|
||||
folder
|
||||
= [subFolderClass folderWithName: [row objectForKey: @"c_path4"]
|
||||
andDisplayName: [row objectForKey: @"c_foldername"]
|
||||
inContainer: self];
|
||||
key = [row objectForKey: @"c_path4"];
|
||||
hasPersonal = (hasPersonal || [key isEqualToString: @"personal"]);
|
||||
[folder setOCSPath: [NSString stringWithFormat: @"%@/%@",
|
||||
OCSPath, key]];
|
||||
[subFolders setObject: folder forKey: key];
|
||||
row = [fc fetchAttributes: attrs withZone: NULL];
|
||||
}
|
||||
|
||||
if (!hasPersonal)
|
||||
{
|
||||
folder = [subFolderClass folderWithName: @"personal"
|
||||
andDisplayName: @"personal"
|
||||
inContainer: self];
|
||||
path = [NSString stringWithFormat: @"/Users/%@/%@/personal",
|
||||
[self ownerInContext: context],
|
||||
nameInContainer];
|
||||
[folder setOCSPath: path];
|
||||
[subFolders setObject: folder forKey: @"personal"];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) appendPersonalSources
|
||||
{
|
||||
GCSChannelManager *cm;
|
||||
EOAdaptorChannel *fc;
|
||||
NSURL *folderLocation;
|
||||
NSString *sql, *gcsFolderType;
|
||||
|
||||
cm = [GCSChannelManager defaultChannelManager];
|
||||
folderLocation
|
||||
= [[GCSFolderManager defaultFolderManager] folderInfoLocation];
|
||||
fc = [cm acquireOpenChannelForURL: folderLocation];
|
||||
if (fc)
|
||||
{
|
||||
gcsFolderType = [[self class] gcsFolderType];
|
||||
|
||||
sql
|
||||
= [NSString stringWithFormat: (@"SELECT c_path4, c_foldername FROM %@"
|
||||
@" WHERE c_path2 = '%@'"
|
||||
@" AND c_folder_type = '%@'"),
|
||||
[folderLocation gcsTableName],
|
||||
[self ownerInContext: context],
|
||||
gcsFolderType];
|
||||
[self _fetchPersonalFolders: sql withChannel: fc];
|
||||
[cm releaseChannel: fc];
|
||||
// sql = [sql stringByAppendingFormat:@" WHERE %@ = '%@'",
|
||||
// uidColumnName, [self uid]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) appendSystemSources
|
||||
{
|
||||
}
|
||||
|
||||
- (NSException *) newFolderWithName: (NSString *) name
|
||||
{
|
||||
SOGoFolder *newFolder;
|
||||
NSException *error;
|
||||
|
||||
if (!subFolderClass)
|
||||
subFolderClass = [[self class] subFolderClass];
|
||||
|
||||
newFolder = [subFolderClass folderWithName: name
|
||||
andDisplayName: name
|
||||
inContainer: self];
|
||||
if ([newFolder isKindOfClass: [NSException class]])
|
||||
error = (NSException *) newFolder;
|
||||
else
|
||||
{
|
||||
[newFolder setOCSPath: [NSString stringWithFormat: @"%@/%@",
|
||||
OCSPath, name]];
|
||||
if ([newFolder create])
|
||||
error = nil;
|
||||
else
|
||||
error = [NSException exceptionWithHTTPStatus: 400
|
||||
reason: @"The new folder could not be created"];
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
- (void) initSubFolders
|
||||
{
|
||||
if (!subFolders)
|
||||
{
|
||||
subFolders = [NSMutableDictionary new];
|
||||
[self appendPersonalSources];
|
||||
[self appendSystemSources];
|
||||
}
|
||||
}
|
||||
|
||||
- (id) lookupName: (NSString *) name
|
||||
inContext: (WOContext *) lookupContext
|
||||
acquire: (BOOL) acquire
|
||||
{
|
||||
id obj;
|
||||
|
||||
/* first check attributes directly bound to the application */
|
||||
obj = [super lookupName: name inContext: lookupContext acquire: NO];
|
||||
if (!obj)
|
||||
{
|
||||
if (!subFolders)
|
||||
[self initSubFolders];
|
||||
|
||||
obj = [subFolders objectForKey: name];
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
- (NSArray *) toManyRelationshipKeys
|
||||
{
|
||||
if (!subFolders)
|
||||
[self initSubFolders];
|
||||
|
||||
return [subFolders allKeys];
|
||||
}
|
||||
|
||||
- (NSArray *) subFolders
|
||||
{
|
||||
if (!subFolders)
|
||||
[self initSubFolders];
|
||||
|
||||
return [subFolders allValues];
|
||||
}
|
||||
|
||||
/* acls */
|
||||
- (NSArray *) aclsForUser: (NSString *) uid
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL) davIsCollection
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *) davContentType
|
||||
{
|
||||
return @"httpd/unix-directory";
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -37,6 +37,8 @@
|
||||
#import <SoObjects/SOGo/SOGoObject.h>
|
||||
#import <SoObjects/SOGo/SOGoPermissions.h>
|
||||
|
||||
#import "WODirectAction+SOGo.h"
|
||||
|
||||
#import "UIxFolderActions.h"
|
||||
|
||||
@implementation UIxFolderActions
|
||||
@@ -89,10 +91,9 @@
|
||||
NSMutableDictionary *folderSubscription;
|
||||
NSString *mailInvitationURL;
|
||||
|
||||
response = [context response];
|
||||
if ([owner isEqualToString: login])
|
||||
{
|
||||
[response setStatus: 403];
|
||||
response = [self responseWithStatus: 403];
|
||||
[response appendContentString:
|
||||
@"You cannot (un)subscribe to a folder that you own!"];
|
||||
}
|
||||
@@ -119,12 +120,12 @@
|
||||
mailInvitationURL
|
||||
= [[clientObject soURLToBaseContainerForCurrentUser]
|
||||
absoluteString];
|
||||
[response setStatus: 302];
|
||||
response = [self responseWithStatus: 302];
|
||||
[response setHeader: mailInvitationURL
|
||||
forKey: @"location"];
|
||||
}
|
||||
else
|
||||
[response setStatus: 204];
|
||||
response = [self responseWith204];
|
||||
}
|
||||
|
||||
return response;
|
||||
@@ -162,22 +163,14 @@
|
||||
|
||||
- (WOResponse *) canAccessContentAction
|
||||
{
|
||||
WOResponse *response;
|
||||
|
||||
response = [context response];
|
||||
[response setStatus: 204];
|
||||
|
||||
return response;
|
||||
return [self responseWith204];
|
||||
}
|
||||
|
||||
- (WOResponse *) _realFolderActivation: (BOOL) makeActive
|
||||
{
|
||||
WOResponse *response;
|
||||
NSMutableDictionary *folderSubscription, *folderDict;
|
||||
NSNumber *active;
|
||||
|
||||
response = [context response];
|
||||
|
||||
[self _setupContext];
|
||||
active = [NSNumber numberWithBool: makeActive];
|
||||
if ([owner isEqualToString: login])
|
||||
@@ -196,9 +189,8 @@
|
||||
}
|
||||
|
||||
[ud synchronize];
|
||||
[response setStatus: 204];
|
||||
|
||||
return response;
|
||||
return [self responseWith204];
|
||||
}
|
||||
|
||||
- (WOResponse *) activateFolderAction
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
@interface WODirectAction (SOGoExtension)
|
||||
|
||||
- (WOResponse *) responseWithStatus: (unsigned int) status;
|
||||
- (WOResponse *) responseWith204;
|
||||
- (WOResponse *) redirectToLocation: (NSString *) newLocation;
|
||||
|
||||
@end
|
||||
|
||||
@@ -28,15 +28,30 @@
|
||||
|
||||
@implementation WODirectAction (SOGoExtension)
|
||||
|
||||
- (WOResponse *) redirectToLocation: (NSString *) newLocation
|
||||
- (WOResponse *) responseWithStatus: (unsigned int) status
|
||||
{
|
||||
WOResponse *response;
|
||||
|
||||
response = [context response];
|
||||
[response setStatus: 302 /* moved */];
|
||||
[response setStatus: status];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
- (WOResponse *) responseWith204
|
||||
{
|
||||
return [self responseWithStatus: 204];
|
||||
}
|
||||
|
||||
- (WOResponse *) redirectToLocation: (NSString *) newLocation
|
||||
{
|
||||
WOResponse *response;
|
||||
|
||||
response = [self responseWithStatus: 302];
|
||||
[response setHeader: newLocation forKey: @"location"];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -52,8 +52,7 @@
|
||||
WORequest *request;
|
||||
|
||||
folders = [self clientObject];
|
||||
action = [NSString stringWithFormat: @"../%@/%@",
|
||||
[folders defaultSourceName],
|
||||
action = [NSString stringWithFormat: @"../personal/%@",
|
||||
actionName];
|
||||
|
||||
request = [[self context] request];
|
||||
@@ -82,7 +81,11 @@
|
||||
|
||||
name = [self queryParameterForKey: @"name"];
|
||||
if ([name length] > 0)
|
||||
response = [[self clientObject] newFolderWithName: name];
|
||||
{
|
||||
response = [[self clientObject] newFolderWithName: name];
|
||||
if (!response)
|
||||
response = [self responseWith204];
|
||||
}
|
||||
else
|
||||
response = [NSException exceptionWithHTTPStatus: 400
|
||||
reason: @"The name is missing"];
|
||||
@@ -111,8 +114,7 @@
|
||||
{
|
||||
uid = [currentContact objectForKey: @"c_uid"];
|
||||
if (uid && ![results objectForKey: uid])
|
||||
[results setObject: currentContact
|
||||
forKey: uid];
|
||||
[results setObject: currentContact forKey: uid];
|
||||
currentContact = [folderResults nextObject];
|
||||
}
|
||||
}
|
||||
@@ -202,7 +204,7 @@
|
||||
gcsFolders = [NSMutableArray new];
|
||||
[gcsFolders autorelease];
|
||||
|
||||
contactSubfolders = [[contactFolders contactFolders] objectEnumerator];
|
||||
contactSubfolders = [[contactFolders subFolders] objectEnumerator];
|
||||
currentContactFolder = [contactSubfolders nextObject];
|
||||
while (currentContactFolder)
|
||||
{
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#import <SoObjects/SOGo/SOGoUser.h>
|
||||
#import <SoObjects/Contacts/SOGoContactFolder.h>
|
||||
#import <SoObjects/Contacts/SOGoContactFolders.h>
|
||||
|
||||
#import "UIxContactsListViewContainer.h"
|
||||
|
||||
@@ -115,7 +116,7 @@
|
||||
|
||||
folderContainer = [[self clientObject] container];
|
||||
|
||||
return [folderContainer contactFolders];
|
||||
return [folderContainer subFolders];
|
||||
}
|
||||
|
||||
- (NSString *) currentContactFolderId
|
||||
|
||||
@@ -108,8 +108,7 @@
|
||||
rawFolders = [co allFolderPaths];
|
||||
folders = [self _jsonFolders: [rawFolders objectEnumerator]];
|
||||
|
||||
response = [context response];
|
||||
[response setStatus: 200];
|
||||
response = [self responseWithStatus: 200];
|
||||
[response setHeader: @"text/plain; charset=utf-8"
|
||||
forKey: @"content-type"];
|
||||
[response appendContentString: [folders jsonRepresentation]];
|
||||
|
||||
@@ -94,10 +94,7 @@
|
||||
|
||||
response = [[self clientObject] trashInContext: context];
|
||||
if (!response)
|
||||
{
|
||||
response = [context response];
|
||||
[response setStatus: 204];
|
||||
}
|
||||
response = [self responseWith204];
|
||||
|
||||
return response;
|
||||
}
|
||||
@@ -113,10 +110,7 @@
|
||||
response = [[self clientObject] moveToFolderNamed: destinationFolder
|
||||
inContext: context];
|
||||
if (!response)
|
||||
{
|
||||
response = [context response];
|
||||
[response setStatus: 204];
|
||||
}
|
||||
response = [self responseWith204];
|
||||
}
|
||||
else
|
||||
response = [NSException exceptionWithHTTPStatus: 500 /* Server Error */
|
||||
@@ -125,6 +119,30 @@
|
||||
return response;
|
||||
}
|
||||
|
||||
/* active message */
|
||||
|
||||
- (id) markMessageUnreadAction
|
||||
{
|
||||
id response;
|
||||
|
||||
response = [[self clientObject] removeFlags: @"seen"];
|
||||
if (!response)
|
||||
response = [self responseWith204];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
- (id) markMessageReadAction
|
||||
{
|
||||
id response;
|
||||
|
||||
response = [[self clientObject] addFlags: @"seen"];
|
||||
if (!response)
|
||||
response = [self responseWith204];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/* SOGoDraftObject */
|
||||
- (WOResponse *) editAction
|
||||
{
|
||||
@@ -158,10 +176,7 @@
|
||||
if (error)
|
||||
response = error;
|
||||
else
|
||||
{
|
||||
response = [context response];
|
||||
[response setStatus: 204];
|
||||
}
|
||||
response = [self responseWith204];
|
||||
|
||||
return response;
|
||||
}
|
||||
@@ -171,17 +186,15 @@
|
||||
WOResponse *response;
|
||||
NSString *filename;
|
||||
|
||||
response = [context response];
|
||||
|
||||
filename = [[context request] formValueForKey: @"filename"];
|
||||
if ([filename length] > 0)
|
||||
{
|
||||
response = [self responseWith204];
|
||||
[[self clientObject] deleteAttachmentWithName: filename];
|
||||
[response setStatus: 204];
|
||||
}
|
||||
else
|
||||
{
|
||||
[response setStatus: 500];
|
||||
response = [self responseWithStatus: 500];
|
||||
[response appendContentString: @"How did you end up here?"];
|
||||
}
|
||||
|
||||
|
||||
@@ -404,10 +404,7 @@ static NSArray *infoKeys = nil;
|
||||
{
|
||||
result = [[self clientObject] save];
|
||||
if (!result)
|
||||
{
|
||||
result = [context response];
|
||||
[result setStatus: 204];
|
||||
}
|
||||
result = [self responseWith204];
|
||||
}
|
||||
else
|
||||
result = [self failedToSaveFormResponse];
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#import <SoObjects/Mailer/SOGoMailAccount.h>
|
||||
#import <SoObjects/SOGo/NSObject+Utilities.h>
|
||||
|
||||
#import <UI/Common/WODirectAction+SOGo.h>
|
||||
|
||||
#import "UIxMailFolderActions.h"
|
||||
|
||||
@implementation UIxMailFolderActions
|
||||
@@ -49,7 +51,6 @@
|
||||
NSString *folderName;
|
||||
|
||||
co = [self clientObject];
|
||||
response = [context response];
|
||||
|
||||
folderName = [[context request] formValueForKey: @"name"];
|
||||
if ([folderName length] > 0)
|
||||
@@ -58,15 +59,15 @@
|
||||
error = [connection createMailbox: folderName atURL: [co imap4URL]];
|
||||
if (error)
|
||||
{
|
||||
[response setStatus: 500];
|
||||
response = [self responseWithStatus: 500];
|
||||
[response appendContentString: @"Unable to create folder."];
|
||||
}
|
||||
else
|
||||
[response setStatus: 204];
|
||||
response = [self responseWith204];
|
||||
}
|
||||
else
|
||||
{
|
||||
[response setStatus: 500];
|
||||
response = [self responseWithStatus: 500];
|
||||
[response appendContentString: @"Missing 'name' parameter."];
|
||||
}
|
||||
|
||||
@@ -100,7 +101,6 @@
|
||||
NSURL *srcURL, *destURL;
|
||||
|
||||
co = [self clientObject];
|
||||
response = [context response];
|
||||
|
||||
folderName = [[context request] formValueForKey: @"name"];
|
||||
if ([folderName length] > 0)
|
||||
@@ -112,15 +112,15 @@
|
||||
toURL: destURL];
|
||||
if (error)
|
||||
{
|
||||
[response setStatus: 500];
|
||||
response = [self responseWithStatus: 500];
|
||||
[response appendContentString: @"Unable to rename folder."];
|
||||
}
|
||||
else
|
||||
[response setStatus: 204];
|
||||
response = [self responseWith204];
|
||||
}
|
||||
else
|
||||
{
|
||||
[response setStatus: 500];
|
||||
response = [self responseWithStatus: 500];
|
||||
[response appendContentString: @"Missing 'name' parameter."];
|
||||
}
|
||||
|
||||
@@ -154,7 +154,6 @@
|
||||
NSURL *srcURL, *destURL;
|
||||
|
||||
co = [self clientObject];
|
||||
response = [context response];
|
||||
connection = [co imap4Connection];
|
||||
srcURL = [co imap4URL];
|
||||
destURL = [self _trashedURLOfFolder: srcURL
|
||||
@@ -164,11 +163,11 @@
|
||||
toURL: destURL];
|
||||
if (error)
|
||||
{
|
||||
[response setStatus: 500];
|
||||
response = [self responseWithStatus: 500];
|
||||
[response appendContentString: @"Unable to move folder."];
|
||||
}
|
||||
else
|
||||
[response setStatus: 204];
|
||||
response = [self responseWith204];
|
||||
|
||||
return response;
|
||||
}
|
||||
@@ -180,18 +179,17 @@
|
||||
WOResponse *response;
|
||||
|
||||
co = [self clientObject];
|
||||
response = [context response];
|
||||
|
||||
error = [co expunge];
|
||||
if (error)
|
||||
{
|
||||
[response setStatus: 500];
|
||||
response = [self responseWithStatus: 500];
|
||||
[response appendContentString: @"Unable to expunge folder."];
|
||||
}
|
||||
else
|
||||
{
|
||||
[co flushMailCaches];
|
||||
[response setStatus: 204];
|
||||
response = [self responseWith204];
|
||||
}
|
||||
|
||||
return response;
|
||||
@@ -207,7 +205,6 @@
|
||||
NSURL *currentURL;
|
||||
|
||||
co = [self clientObject];
|
||||
response = [context response];
|
||||
|
||||
error = [co addFlagsToAllMessages: @"deleted"];
|
||||
if (!error)
|
||||
@@ -226,11 +223,11 @@
|
||||
}
|
||||
if (error)
|
||||
{
|
||||
[response setStatus: 500];
|
||||
response = [self responseWithStatus: 500];
|
||||
[response appendContentString: @"Unable to empty the trash folder."];
|
||||
}
|
||||
else
|
||||
[response setStatus: 204];
|
||||
response = [self responseWith204];
|
||||
|
||||
return response;
|
||||
}
|
||||
@@ -242,7 +239,6 @@
|
||||
WOResponse *response;
|
||||
SOGoMailFolder *clientObject;
|
||||
|
||||
response = [context response];
|
||||
mailInvitationParam
|
||||
= [[context request] formValueForKey: @"mail-invitation"];
|
||||
if ([mailInvitationParam boolValue])
|
||||
@@ -257,7 +253,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
[response setStatus: 500];
|
||||
response = [self responseWithStatus: 500];
|
||||
[response appendContentString: @"How did you end up here?"];
|
||||
}
|
||||
|
||||
@@ -283,8 +279,7 @@
|
||||
NGImap4Client *client;
|
||||
NSString *responseString;
|
||||
|
||||
response = [context response];
|
||||
[response setStatus: 200];
|
||||
response = [self responseWithStatus: 200];
|
||||
[response setHeader: @"text/plain; charset=UTF-8"
|
||||
forKey: @"content-type"];
|
||||
|
||||
|
||||
@@ -221,10 +221,24 @@ static int attachmentFlagSize = 8096;
|
||||
|
||||
- (NSArray *) sortedUIDs
|
||||
{
|
||||
EOQualifier *fetchQualifier, *notDeleted;
|
||||
if (!sortedUIDs)
|
||||
{
|
||||
notDeleted = [EOQualifier qualifierWithQualifierFormat:
|
||||
@"(not (flags = %@))",
|
||||
@"deleted"];
|
||||
if (qualifier)
|
||||
{
|
||||
fetchQualifier = [[EOAndQualifier alloc] initWithQualifiers:
|
||||
notDeleted, qualifier,
|
||||
nil];
|
||||
[fetchQualifier autorelease];
|
||||
}
|
||||
else
|
||||
fetchQualifier = notDeleted;
|
||||
|
||||
sortedUIDs
|
||||
= [[self clientObject] fetchUIDsMatchingQualifier: qualifier
|
||||
= [[self clientObject] fetchUIDsMatchingQualifier: fetchQualifier
|
||||
sortOrdering: [self imap4SortOrdering]];
|
||||
[sortedUIDs retain];
|
||||
}
|
||||
@@ -407,36 +421,8 @@ static int attachmentFlagSize = 8096;
|
||||
return [self redirectToLocation:url];
|
||||
}
|
||||
|
||||
/* active message */
|
||||
|
||||
- (SOGoMailObject *) lookupActiveMessage
|
||||
{
|
||||
NSString *uid;
|
||||
|
||||
if ((uid = [[context request] formValueForKey: @"uid"]) == nil)
|
||||
return nil;
|
||||
|
||||
return [[self clientObject] lookupName: uid
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
}
|
||||
|
||||
/* actions */
|
||||
|
||||
- (BOOL) isJavaScriptRequest
|
||||
{
|
||||
return [[[context request] formValueForKey:@"jsonly"] boolValue];
|
||||
}
|
||||
|
||||
- (id) javaScriptOK
|
||||
{
|
||||
WOResponse *r;
|
||||
|
||||
r = [context response];
|
||||
[r setStatus:200 /* OK */];
|
||||
return r;
|
||||
}
|
||||
|
||||
- (int) firstMessageOfPageFor: (int) messageNbr
|
||||
{
|
||||
NSArray *messageNbrs;
|
||||
@@ -462,8 +448,7 @@ static int attachmentFlagSize = 8096;
|
||||
|
||||
if ([criteria isEqualToString: @"subject"])
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat:
|
||||
@"(subject doesContain: %@)",
|
||||
value];
|
||||
@"(subject doesContain: %@)", value];
|
||||
else if ([criteria isEqualToString: @"sender"])
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat:
|
||||
@"(sender doesContain: %@)", value];
|
||||
@@ -510,39 +495,6 @@ static int attachmentFlagSize = 8096;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) viewAction
|
||||
{
|
||||
return [self defaultAction];
|
||||
}
|
||||
|
||||
- (id) markMessageUnreadAction
|
||||
{
|
||||
NSException *error;
|
||||
|
||||
if ((error = [[self lookupActiveMessage] removeFlags:@"seen"]) != nil)
|
||||
// TODO: improve error handling
|
||||
return error;
|
||||
|
||||
if ([self isJavaScriptRequest])
|
||||
return [self javaScriptOK];
|
||||
|
||||
return [self redirectToLocation:@"view"];
|
||||
}
|
||||
|
||||
- (id) markMessageReadAction
|
||||
{
|
||||
NSException *error;
|
||||
|
||||
if ((error = [[self lookupActiveMessage] addFlags:@"seen"]) != nil)
|
||||
// TODO: improve error handling
|
||||
return error;
|
||||
|
||||
if ([self isJavaScriptRequest])
|
||||
return [self javaScriptOK];
|
||||
|
||||
return [self redirectToLocation:@"view"];
|
||||
}
|
||||
|
||||
- (id) getMailAction
|
||||
{
|
||||
// TODO: we might want to flush the caches?
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#import <Foundation/NSString.h>
|
||||
#import <SoObjects/Mailer/SOGoMailObject.h>
|
||||
|
||||
#import <UI/Common/WODirectAction+SOGo.h>
|
||||
|
||||
#import "UIxMailSourceView.h"
|
||||
|
||||
@implementation UIxMailSourceView
|
||||
@@ -36,8 +38,7 @@
|
||||
|
||||
source = [[self clientObject] contentAsString];
|
||||
|
||||
response = [context response];
|
||||
[response setStatus: 200];
|
||||
response = [self responseWithStatus: 200];
|
||||
[response setHeader: @"text/plain; charset=utf-8"
|
||||
forKey: @"content-type"];
|
||||
[response appendContentString: source];
|
||||
|
||||
@@ -142,37 +142,42 @@ static NSString *mailETag = nil;
|
||||
|
||||
- (id) defaultAction
|
||||
{
|
||||
WOResponse *response;
|
||||
NSString *s;
|
||||
|
||||
/* check etag to see whether we really must rerender */
|
||||
if (mailETag != nil ) {
|
||||
/*
|
||||
Note: There is one thing which *can* change for an existing message,
|
||||
those are the IMAP4 flags (and annotations, which we do not use).
|
||||
Since we don't render the flags, it should be OK, if this changes
|
||||
we must embed the flagging into the etag.
|
||||
*/
|
||||
NSString *s;
|
||||
|
||||
if ((s = [[context request] headerForKey:@"if-none-match"])) {
|
||||
if ([s rangeOfString:mailETag].length > 0) { /* not perfectly correct */
|
||||
/* client already has the proper entity */
|
||||
// [self logWithFormat:@"MATCH: %@ (tag %@)", s, mailETag];
|
||||
|
||||
if (![[self clientObject] doesMailExist]) {
|
||||
return [NSException exceptionWithHTTPStatus:404 /* Not Found */
|
||||
reason:@"message got deleted"];
|
||||
if (mailETag)
|
||||
{
|
||||
/*
|
||||
Note: There is one thing which *can* change for an existing message,
|
||||
those are the IMAP4 flags (and annotations, which we do not use).
|
||||
Since we don't render the flags, it should be OK, if this changes
|
||||
we must embed the flagging into the etag.
|
||||
*/
|
||||
s = [[context request] headerForKey: @"if-none-match"];
|
||||
if (s)
|
||||
{
|
||||
if ([s rangeOfString:mailETag].length > 0) /* not perfectly correct */
|
||||
{
|
||||
/* client already has the proper entity */
|
||||
// [self logWithFormat:@"MATCH: %@ (tag %@)", s, mailETag];
|
||||
|
||||
if (![[self clientObject] doesMailExist]) {
|
||||
return [NSException exceptionWithHTTPStatus:404 /* Not Found */
|
||||
reason:@"message got deleted"];
|
||||
}
|
||||
|
||||
response = [context response];
|
||||
[response setStatus: 304 /* Not Modified */];
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
[[context response] setStatus:304 /* Not Modified */];
|
||||
return [context response];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ([self message] == nil) {
|
||||
// TODO: redirect to proper error
|
||||
if (![self message]) // TODO: redirect to proper error
|
||||
return [NSException exceptionWithHTTPStatus:404 /* Not Found */
|
||||
reason:@"did not find specified message!"];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -115,16 +115,6 @@
|
||||
protectedBy = "View";
|
||||
pageName = "UIxMailListView";
|
||||
};
|
||||
markMessageUnread = {
|
||||
protectedBy = "View";
|
||||
pageName = "UIxMailListView";
|
||||
actionName = "markMessageUnread";
|
||||
};
|
||||
markMessageRead = {
|
||||
protectedBy = "View";
|
||||
pageName = "UIxMailListView";
|
||||
actionName = "markMessageRead";
|
||||
};
|
||||
getMail = {
|
||||
protectedBy = "View";
|
||||
pageName = "UIxMailListView";
|
||||
@@ -235,6 +225,16 @@
|
||||
actionClass = "UIxMailActions";
|
||||
actionName = "forward";
|
||||
};
|
||||
markMessageUnread = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxMailActions";
|
||||
actionName = "markMessageUnread";
|
||||
};
|
||||
markMessageRead = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxMailActions";
|
||||
actionName = "markMessageRead";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
|
||||
auth = [[WOApplication application]
|
||||
authenticatorInContext: context];
|
||||
response = [context response];
|
||||
response = [self responseWith204];
|
||||
cookieString = [NSString stringWithFormat: @"%@:%@",
|
||||
[self queryParameterForKey: @"userName"],
|
||||
[self queryParameterForKey: @"password"]];
|
||||
@@ -78,7 +78,6 @@
|
||||
authCookie = [WOCookie cookieWithName: [auth cookieNameInContext: context]
|
||||
value: cookieValue];
|
||||
[authCookie setPath: @"/"];
|
||||
[response setStatus: 204];
|
||||
[response addCookie: authCookie];
|
||||
|
||||
return response;
|
||||
|
||||
@@ -68,25 +68,25 @@
|
||||
/* date selection */
|
||||
- (NSCalendarDate *) selectedDate;
|
||||
|
||||
- (NSString *)dateStringForDate:(NSCalendarDate *)_date;
|
||||
- (NSString *) dateStringForDate: (NSCalendarDate *)_date;
|
||||
|
||||
- (BOOL) hideFrame;
|
||||
|
||||
- (UIxComponent *) jsCloseWithRefreshMethod: (NSString *) methodName;
|
||||
|
||||
/* SoUser */
|
||||
- (NSString *)shortUserNameForDisplay;
|
||||
- (NSString *) shortUserNameForDisplay;
|
||||
|
||||
/* labels */
|
||||
- (NSString *)labelForKey:(NSString *)_key;
|
||||
- (NSString *) labelForKey:(NSString *)_key;
|
||||
|
||||
- (NSString *)localizedNameForDayOfWeek:(unsigned)_dayOfWeek;
|
||||
- (NSString *)localizedAbbreviatedNameForDayOfWeek:(unsigned)_dayOfWeek;
|
||||
- (NSString *)localizedNameForMonthOfYear:(unsigned)_monthOfYear;
|
||||
- (NSString *)localizedAbbreviatedNameForMonthOfYear:(unsigned)_monthOfYear;
|
||||
- (NSString *) localizedNameForDayOfWeek:(unsigned)_dayOfWeek;
|
||||
- (NSString *) localizedAbbreviatedNameForDayOfWeek:(unsigned)_dayOfWeek;
|
||||
- (NSString *) localizedNameForMonthOfYear:(unsigned)_monthOfYear;
|
||||
- (NSString *) localizedAbbreviatedNameForMonthOfYear:(unsigned)_monthOfYear;
|
||||
|
||||
/* HTTP method safety */
|
||||
- (BOOL)isInvokedBySafeMethod;
|
||||
- (BOOL) isInvokedBySafeMethod;
|
||||
|
||||
/* locale */
|
||||
- (NSDictionary *)locale;
|
||||
@@ -95,6 +95,8 @@
|
||||
- (WOResourceManager *) pageResourceManager;
|
||||
- (NSString *) urlForResourceFilename: (NSString *) filename;
|
||||
|
||||
- (WOResponse *) responseWith204;
|
||||
|
||||
/* Debugging */
|
||||
- (BOOL)isUIxDebugEnabled;
|
||||
|
||||
|
||||
@@ -400,7 +400,7 @@ static BOOL uixDebugEnabled = NO;
|
||||
userTimeZone = [[context activeUser] timeZone];
|
||||
[_date setTimeZone: userTimeZone];
|
||||
|
||||
return [_date descriptionWithCalendarFormat:@"%Y%m%d"];
|
||||
return [_date descriptionWithCalendarFormat: @"%Y%m%d"];
|
||||
}
|
||||
|
||||
- (BOOL) hideFrame
|
||||
@@ -569,6 +569,16 @@ static BOOL uixDebugEnabled = NO;
|
||||
return url;
|
||||
}
|
||||
|
||||
- (WOResponse *) responseWith204
|
||||
{
|
||||
WOResponse *response;
|
||||
|
||||
response = [context response];
|
||||
[response setStatus: 204];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/* debugging */
|
||||
|
||||
- (BOOL)isUIxDebugEnabled {
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
#import <SoObjects/SOGo/NSObject+Utilities.h>
|
||||
#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
|
||||
|
||||
#import <UI/Common/WODirectAction+SOGo.h>
|
||||
|
||||
#import "NSArray+Scheduler.h"
|
||||
|
||||
#import "UIxCalListingActions.h"
|
||||
@@ -289,10 +291,9 @@
|
||||
{
|
||||
WOResponse *response;
|
||||
|
||||
response = [context response];
|
||||
response = [self responseWithStatus: 200];
|
||||
[response setHeader: @"text/plain; charset=utf-8"
|
||||
forKey: @"content-type"];
|
||||
[response setStatus: 200];
|
||||
[response appendContentString: [data jsonRepresentation]];
|
||||
|
||||
return response;
|
||||
|
||||
@@ -63,7 +63,6 @@
|
||||
var:class="messageSubjectCellStyleClass"
|
||||
var:id="msgDivID"
|
||||
><var:string value="message.envelope.subject"
|
||||
formatter="context.mailSubjectFormatter"
|
||||
/></td
|
||||
|
||||
><td class="messageAddressColumn"
|
||||
|
||||
@@ -149,7 +149,7 @@ function openMessageWindowsForSelection(action, firstOnly) {
|
||||
|
||||
function mailListMarkMessage(event) {
|
||||
var http = createHTTPClient();
|
||||
var url = ApplicationBaseURL + currentMailbox + "/" + action + "?uid=" + msguid;
|
||||
var url = ApplicationBaseURL + currentMailbox + "/" + msguid + "/" + action;
|
||||
|
||||
if (http) {
|
||||
// TODO: add parameter to signal that we are only interested in OK
|
||||
|
||||
Reference in New Issue
Block a user