mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-07-08 09:55:09 +00:00
Added the SOGoUserManager class (not used right now) to cache user preferences. Fixed tons of bugs wrt invitations handling and more cleanup needs to be done.
Monotone-Parent: 56b6e4ca9c570a4e36d00e32127d539e82da7293 Monotone-Revision: db186d0ad7ef7cd1cab54a0ee31f87daa7c32085 Monotone-Author: ludovic@Sophos.ca Monotone-Date: 2008-11-05T21:04:16 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||
Copyright (C) 2007-2008 Inverse inc.
|
||||
|
||||
This file is part of OpenGroupware.org.
|
||||
|
||||
@@ -62,6 +63,7 @@
|
||||
#import <SOGo/NSDictionary+Utilities.h>
|
||||
#import <SOGo/SOGoPermissions.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/SOGoUserManager.h>
|
||||
#import <SOGo/SOGoUserFolder.h>
|
||||
#import <SOGo/SOGoWebDAVAclManager.h>
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#import <SoObjects/SOGo/SOGoObject.h>
|
||||
#import <SoObjects/SOGo/SOGoPermissions.h>
|
||||
#import <SoObjects/SOGo/SOGoUser.h>
|
||||
#import <SoObjects/SOGo/SOGoUserManager.h>
|
||||
#import <SoObjects/SOGo/SOGoWebDAVAclManager.h>
|
||||
#import <SoObjects/SOGo/SOGoWebDAVValue.h>
|
||||
#import <SoObjects/SOGo/WORequest+SOGo.h>
|
||||
@@ -169,7 +170,7 @@
|
||||
possibleName = [folder resourceNameForEventUID: eventUID];
|
||||
if (possibleName)
|
||||
{
|
||||
object = [folder lookupName: nameInContainer
|
||||
object = [folder lookupName: possibleName
|
||||
inContext: context acquire: NO];
|
||||
if ([object isKindOfClass: [NSException class]])
|
||||
object = nil;
|
||||
@@ -362,9 +363,11 @@
|
||||
}
|
||||
|
||||
- (NSException *) _updateAttendee: (iCalPerson *) attendee
|
||||
ownerUser: (SOGoUser *) theOwnerUser
|
||||
forEventUID: (NSString *) eventUID
|
||||
withSequence: (NSNumber *) sequence
|
||||
forUID: (NSString *) uid
|
||||
shouldAddSentBy: (BOOL) b
|
||||
{
|
||||
SOGoAppointmentObject *eventObject;
|
||||
iCalEvent *event;
|
||||
@@ -381,8 +384,23 @@
|
||||
if ([[event sequence] compare: sequence]
|
||||
== NSOrderedSame)
|
||||
{
|
||||
otherAttendee = [event findParticipant: [context activeUser]];
|
||||
SOGoUser *currentUser;
|
||||
|
||||
//otherAttendee = [event findParticipant: [context activeUser]];
|
||||
otherAttendee = [event findParticipant: theOwnerUser];
|
||||
[otherAttendee setPartStat: [attendee partStat]];
|
||||
|
||||
// If one has accepted / declined an invitation on behalf of
|
||||
// the attendee, we add the user to the SENT-BY attribute.
|
||||
currentUser = [context activeUser];
|
||||
if (b && ![[currentUser login] isEqualToString: [theOwnerUser login]])
|
||||
{
|
||||
NSString *currentEmail;
|
||||
currentEmail = [[currentUser allEmails] objectAtIndex: 0];
|
||||
[otherAttendee addAttribute: @"SENT-BY"
|
||||
value: [NSString stringWithFormat: @"\"MAILTO:%@\"", currentEmail]];
|
||||
}
|
||||
|
||||
iCalString = [[event parent] versitString];
|
||||
error = [eventObject saveContentString: iCalString];
|
||||
}
|
||||
@@ -392,10 +410,11 @@
|
||||
}
|
||||
|
||||
- (NSException *) _handleAttendee: (iCalPerson *) attendee
|
||||
ownerUser: (SOGoUser *) theOwnerUser
|
||||
statusChange: (NSString *) newStatus
|
||||
inEvent: (iCalEvent *) event
|
||||
{
|
||||
NSString *newContent, *currentStatus, *organizerUID;
|
||||
NSString *newContent, *currentStatus, *currentUser, *organizerUID;
|
||||
NSException *ex;
|
||||
SOGoUser *ownerUser;
|
||||
|
||||
@@ -406,20 +425,70 @@
|
||||
!= NSOrderedSame)
|
||||
{
|
||||
[attendee setPartStat: newStatus];
|
||||
|
||||
// If one has accepted / declined an invitation on behalf of
|
||||
// the attendee, we add the user to the SENT-BY attribute.
|
||||
currentUser = [context activeUser];
|
||||
if (![[currentUser login] isEqualToString: [theOwnerUser login]])
|
||||
{
|
||||
NSString *currentEmail;
|
||||
currentEmail = [[currentUser allEmails] objectAtIndex: 0];
|
||||
[attendee addAttribute: @"SENT-BY"
|
||||
value: [NSString stringWithFormat: @"\"MAILTO:%@\"", currentEmail]];
|
||||
}
|
||||
|
||||
// We generate the updated iCalendar file and we save it
|
||||
// in the database.
|
||||
newContent = [[event parent] versitString];
|
||||
ex = [self saveContentString: newContent];
|
||||
|
||||
|
||||
ownerUser = [SOGoUser userWithLogin: owner roles: nil];
|
||||
if (!(ex || [event userIsOrganizer: ownerUser]))
|
||||
{
|
||||
if ([[attendee rsvp] isEqualToString: @"true"]
|
||||
&& [event isStillRelevant])
|
||||
[self sendResponseToOrganizer: event];
|
||||
|
||||
organizerUID = [[event organizer] uid];
|
||||
if (organizerUID)
|
||||
ex = [self _updateAttendee: attendee
|
||||
ownerUser: theOwnerUser
|
||||
forEventUID: [event uid]
|
||||
withSequence: [event sequence]
|
||||
forUID: organizerUID];
|
||||
forUID: organizerUID
|
||||
shouldAddSentBy: YES];
|
||||
}
|
||||
|
||||
// We update the calendar of all participants that are
|
||||
// local to the system. This is useful in case user A accepts
|
||||
// invitation from organizer B and users C, D, E who are also
|
||||
// attendees need to verify if A has accepted.
|
||||
NSArray *attendees;
|
||||
iCalPerson *att;
|
||||
NSString *uid;
|
||||
int i;
|
||||
|
||||
attendees = [event attendees];
|
||||
|
||||
for (i = 0; i < [attendees count]; i++)
|
||||
{
|
||||
att = [attendees objectAtIndex: i];
|
||||
|
||||
if (att == attendee) continue;
|
||||
|
||||
uid = [[LDAPUserManager sharedUserManager]
|
||||
getUIDForEmail: [att rfc822Email]];
|
||||
|
||||
if (uid)
|
||||
{
|
||||
[self _updateAttendee: attendee
|
||||
ownerUser: theOwnerUser
|
||||
forEventUID: [event uid]
|
||||
withSequence: [event sequence]
|
||||
forUID: uid
|
||||
shouldAddSentBy: YES];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,6 +581,7 @@
|
||||
{
|
||||
iCalPerson *localAttendee;
|
||||
iCalEvent *event;
|
||||
SOGoUser *ownerUser;
|
||||
|
||||
event = [self component: NO secure: NO];
|
||||
localAttendee = [event findParticipantWithEmail: [attendee rfc822Email]];
|
||||
@@ -519,6 +589,46 @@
|
||||
{
|
||||
[localAttendee setPartStat: [attendee partStat]];
|
||||
[self saveComponent: event];
|
||||
|
||||
/// TEST ///
|
||||
NSArray *attendees;
|
||||
iCalPerson *att;
|
||||
NSString *uid;
|
||||
int i;
|
||||
|
||||
// We update for the organizer
|
||||
ownerUser = [context activeUser];
|
||||
|
||||
[self _updateAttendee: attendee
|
||||
ownerUser: ownerUser
|
||||
forEventUID: [event uid]
|
||||
withSequence: [event sequence]
|
||||
forUID: [[SOGoUser userWithLogin: owner roles: nil] login]
|
||||
shouldAddSentBy: NO];
|
||||
|
||||
attendees = [event attendees];
|
||||
|
||||
for (i = 0; i < [attendees count]; i++)
|
||||
{
|
||||
att = [attendees objectAtIndex: i];
|
||||
|
||||
if (att == attendee) continue;
|
||||
|
||||
uid = [[LDAPUserManager sharedUserManager]
|
||||
getUIDForEmail: [att rfc822Email]];
|
||||
|
||||
if (uid)
|
||||
{
|
||||
[self _updateAttendee: attendee
|
||||
ownerUser: ownerUser
|
||||
forEventUID: [event uid]
|
||||
withSequence: [event sequence]
|
||||
forUID: uid
|
||||
shouldAddSentBy: NO];
|
||||
}
|
||||
}
|
||||
|
||||
/// TEST ///
|
||||
}
|
||||
else
|
||||
[self errorWithFormat: @"attendee not found: '%@'", attendee];
|
||||
@@ -579,7 +689,9 @@
|
||||
ownerUser = [SOGoUser userWithLogin: owner roles: nil];
|
||||
attendee = [event findParticipant: ownerUser];
|
||||
if (attendee)
|
||||
ex = [self _handleAttendee: attendee statusChange: _status
|
||||
ex = [self _handleAttendee: attendee
|
||||
ownerUser: ownerUser
|
||||
statusChange: _status
|
||||
inEvent: event];
|
||||
else
|
||||
ex = [NSException exceptionWithHTTPStatus: 404 /* Not Found */
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
<#IsSubject>Event Cancelled: <#summary/></#IsSubject>
|
||||
<#IsBody><#organizer/> has cancelled this event: <#summary/>.</#IsBody>
|
||||
<#IsBody><#organizer/> <#HasSentBy>(sent by <#sentBy/>) </#HasSentBy>has cancelled this event: <#summary/>.</#IsBody>
|
||||
@@ -16,3 +16,12 @@ summary: WOString {
|
||||
value = summary;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
HasSentBy: WOConditional {
|
||||
condition = hasSentBy;
|
||||
}
|
||||
|
||||
sentBy: WOString {
|
||||
value = sentBy;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
<#IsSubject>Event Invitation Reply: <#summary/></#IsSubject>
|
||||
<#IsBody><#attendee/> has <#HasAccepted>accepted</#HasAccepted><#HasDeclined>declined</#HasDeclined><#HasNotAcceptedNotDeclined>not yet decided upon</#HasNotAcceptedNotDeclined> your event invitation.</#IsBody>
|
||||
<#IsBody><#attendee/> has <#HasSentBy>(sent by <#sentBy/>) </#HasSentBy><#HasAccepted>accepted</#HasAccepted><#HasDeclined>declined</#HasDeclined><#HasNotAcceptedNotDeclined>not yet decided upon</#HasNotAcceptedNotDeclined> your event invitation.</#IsBody>
|
||||
|
||||
@@ -28,3 +28,12 @@ HasDeclined: WOConditional {
|
||||
HasNotAcceptedNotDeclined: WOConditional {
|
||||
condition = hasNotAcceptedNotDeclined;
|
||||
}
|
||||
|
||||
HasSentBy: WOConditional {
|
||||
condition = hasSentBy;
|
||||
}
|
||||
|
||||
sentBy: WOString {
|
||||
value = sentBy;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
<#IsSubject>Event Invitation: <#summary/></#IsSubject>
|
||||
<#IsBody><#organizer/> has invited you to <#summary/>.</#IsBody>
|
||||
<#IsBody><#organizer/> <#HasSentBy>(sent by <#sentBy/>) </#HasSentBy>has invited you to <#summary/>.</#IsBody>
|
||||
|
||||
+9
@@ -16,3 +16,12 @@ summary: WOString {
|
||||
value = summary;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
HasSentBy: WOConditional {
|
||||
condition = hasSentBy;
|
||||
}
|
||||
|
||||
sentBy: WOString {
|
||||
value = sentBy;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
@@ -98,7 +98,24 @@ static NSCharacterSet *wsSet = nil;
|
||||
|
||||
- (NSString *) attendeeName
|
||||
{
|
||||
return [attendee cn];
|
||||
NSString *name;
|
||||
|
||||
name = [attendee cn];
|
||||
|
||||
if (name && [name length])
|
||||
return name;
|
||||
|
||||
return [attendee rfc822Email];
|
||||
}
|
||||
|
||||
- (BOOL) hasSentBy
|
||||
{
|
||||
return [attendee hasSentBy];
|
||||
}
|
||||
|
||||
- (NSString *) sentBy
|
||||
{
|
||||
return [attendee sentBy];
|
||||
}
|
||||
|
||||
- (BOOL) hasAccepted
|
||||
|
||||
@@ -108,6 +108,16 @@ static NSTimeZone *UTC = nil;
|
||||
return organizerName;
|
||||
}
|
||||
|
||||
- (BOOL) hasSentBy
|
||||
{
|
||||
return [[apt organizer] hasSentBy];
|
||||
}
|
||||
|
||||
- (NSString *) sentBy
|
||||
{
|
||||
return [[apt organizer] sentBy];
|
||||
}
|
||||
|
||||
/* Helpers */
|
||||
|
||||
/* Generate Response */
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#import <SoObjects/SOGo/SOGoMailer.h>
|
||||
#import <SoObjects/SOGo/SOGoPermissions.h>
|
||||
#import <SoObjects/SOGo/SOGoUser.h>
|
||||
#import <SoObjects/SOGo/SOGoUserManager.h>
|
||||
#import <SoObjects/SOGo/WORequest+SOGo.h>
|
||||
#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
|
||||
|
||||
@@ -451,20 +452,6 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID)
|
||||
return [[SOGoUser userWithLogin: uid roles: nil] timeZone];
|
||||
}
|
||||
|
||||
- (void) _setupSentByIfNeeded: (iCalPerson *) person
|
||||
{
|
||||
SOGoUser *currentUser;
|
||||
NSString *currentEmail;
|
||||
|
||||
currentUser = [context activeUser];
|
||||
if (![[currentUser login] isEqualToString: owner])
|
||||
{
|
||||
currentEmail = [[currentUser allEmails] objectAtIndex: 0];
|
||||
[person addAttribute: @"SENT-BY"
|
||||
value: [NSString stringWithFormat: @"MAILTO:%@", currentEmail]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) sendEMailUsingTemplateNamed: (NSString *) newPageName
|
||||
forObject: (iCalRepeatableEntityObject *) object
|
||||
toAttendees: (NSArray *) attendees
|
||||
@@ -491,11 +478,12 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID)
|
||||
{
|
||||
/* sender */
|
||||
ownerUser = [SOGoUser userWithLogin: owner roles: nil];
|
||||
currentUser = [context activeUser];
|
||||
shortSenderEmail = [[currentUser allEmails] objectAtIndex: 0];
|
||||
senderEmail = [NSString stringWithFormat: @"%@ <%@>",
|
||||
[ownerUser cn], shortSenderEmail];
|
||||
[self _setupSentByIfNeeded: [object organizer]];
|
||||
//currentUser = [context activeUser];
|
||||
//shortSenderEmail = [[currentUser allEmails] objectAtIndex: 0];
|
||||
// senderEmail = [NSString stringWithFormat: @"%@ <%@>",
|
||||
// [ownerUser cn], shortSenderEmail];
|
||||
shortSenderEmail = [[object organizer] rfc822Email];
|
||||
senderEmail = [[object organizer] mailAddress];
|
||||
// NSLog (@"sending '%@' from %@",
|
||||
// [(iCalCalendar *) [object parent] method], senderEmail);
|
||||
/* generate iCalString once */
|
||||
@@ -695,7 +683,6 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID)
|
||||
{
|
||||
organizer = [event organizer];
|
||||
attendee = [event findParticipant: ownerUser];
|
||||
[self _setupSentByIfNeeded: attendee];
|
||||
[event setAttendees: [NSArray arrayWithObject: attendee]];
|
||||
[self sendIMIPReplyForEvent: event to: organizer];
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#import <SaxObjC/XMLNamespaces.h>
|
||||
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/SOGoUserManager.h>
|
||||
#import <SOGo/NSObject+DAV.h>
|
||||
#import <SOGo/NSString+DAV.h>
|
||||
|
||||
|
||||
@@ -95,14 +95,22 @@ _computeAllDayOffset()
|
||||
return isParticipant;
|
||||
}
|
||||
|
||||
#warning user could be a delegate, we will need to handle that someday
|
||||
- (BOOL) userIsOrganizer: (SOGoUser *) user
|
||||
{
|
||||
NSString *orgMail;
|
||||
NSString *mail;
|
||||
BOOL b;
|
||||
|
||||
orgMail = [[self organizer] rfc822Email];
|
||||
mail = [[self organizer] rfc822Email];
|
||||
b = [user hasEmail: mail];
|
||||
if (b) return YES;
|
||||
|
||||
return [user hasEmail: orgMail];
|
||||
// We check for the SENT-BY
|
||||
mail = [[self organizer] sentBy];
|
||||
|
||||
if ([mail length])
|
||||
return [user hasEmail: mail];
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSArray *) attendeeUIDs
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* iCalPerson+SOGo.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007 Inverse inc.
|
||||
* Copyright (C) 2007-2008 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
- (NSString *) mailAddress;
|
||||
- (NSString *) uid;
|
||||
- (BOOL) hasSentBy;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* iCalPerson+SOGo.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007 Inverse inc.
|
||||
* Copyright (C) 2007-2008 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
@@ -50,4 +50,30 @@ static LDAPUserManager *um = nil;
|
||||
return [um getUIDForEmail: [self rfc822Email]];
|
||||
}
|
||||
|
||||
- (BOOL) hasSentBy
|
||||
{
|
||||
NSString *mail;
|
||||
|
||||
mail = [self value: 0 ofAttribute: @"SENT-BY"];
|
||||
|
||||
return ([mail length] > 7);
|
||||
}
|
||||
|
||||
- (NSString *) sentBy
|
||||
{
|
||||
NSString *mail;
|
||||
|
||||
mail = [self value: 0 ofAttribute: @"SENT-BY"];
|
||||
|
||||
if ([mail length] > 7)
|
||||
{
|
||||
if ([mail characterAtIndex: 0] && [mail hasSuffix: @"\""])
|
||||
mail = [mail substringWithRange: NSMakeRange(1, [mail length]-2)];
|
||||
|
||||
return [mail substringFromIndex: 7];
|
||||
}
|
||||
|
||||
return @"";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -53,6 +53,7 @@ SOGo_HEADER_FILES = \
|
||||
SOGoWebDAVValue.h \
|
||||
SOGoMailer.h \
|
||||
SOGoUser.h \
|
||||
SOGoUserManager.h \
|
||||
\
|
||||
NSDictionary+BSJSONAdditions.h \
|
||||
NSScanner+BSJSONAdditions.h \
|
||||
@@ -98,6 +99,7 @@ SOGo_OBJC_FILES = \
|
||||
SOGoWebDAVValue.m \
|
||||
SOGoMailer.m \
|
||||
SOGoUser.m \
|
||||
SOGoUserManager.m \
|
||||
\
|
||||
NSDictionary+BSJSONAdditions.m \
|
||||
NSScanner+BSJSONAdditions.m \
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#import "LDAPUserManager.h"
|
||||
#import "SOGoPermissions.h"
|
||||
#import "SOGoUser.h"
|
||||
#import "SOGoUserManager.h"
|
||||
|
||||
#import "SOGoDAVAuthenticator.h"
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
#import "SOGoParentFolder.h"
|
||||
#import "SOGoPermissions.h"
|
||||
#import "SOGoUser.h"
|
||||
#import "SOGoUserManager.h"
|
||||
#import "SOGoWebDAVAclManager.h"
|
||||
#import "WORequest+SOGo.h"
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#import "SOGoCache.h"
|
||||
#import "SOGoPermissions.h"
|
||||
#import "SOGoUser.h"
|
||||
#import "SOGoUserManager.h"
|
||||
#import "SOGoUserFolder.h"
|
||||
#import "SOGoWebDAVAclManager.h"
|
||||
#import "SOGoWebDAVValue.h"
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
@class SOGoAppointmentFolder;
|
||||
@class SOGoAppointmentFolders;
|
||||
@class SOGoDateFormatter;
|
||||
@class SOGoUserDefaults;
|
||||
@class SOGoUserFolder;
|
||||
|
||||
extern NSString *SOGoWeekStartJanuary1;
|
||||
@@ -62,8 +63,8 @@ extern NSString *SOGoWeekStartFirstFullWeek;
|
||||
|
||||
@interface SOGoUser : SoUser
|
||||
{
|
||||
NSUserDefaults *userDefaults;
|
||||
NSUserDefaults *userSettings;
|
||||
SOGoUserDefaults *userDefaults;
|
||||
SOGoUserDefaults *userSettings;
|
||||
NSArray *allEmails;
|
||||
NSString *language;
|
||||
NSString *currentPassword;
|
||||
@@ -111,7 +112,10 @@ extern NSString *SOGoWeekStartFirstFullWeek;
|
||||
|
||||
/* defaults */
|
||||
|
||||
- (void) setUserDefaultsFromDictionary: (NSDictionary *) theDictionary;
|
||||
- (NSUserDefaults *) userDefaults;
|
||||
|
||||
- (void) setUserSettingsFromDictionary: (NSDictionary *) theDictionary;
|
||||
- (NSUserDefaults *) userSettings;
|
||||
|
||||
- (NSString *) language;
|
||||
|
||||
@@ -470,6 +470,14 @@ _timeValue (NSString *key)
|
||||
}
|
||||
|
||||
/* defaults */
|
||||
- (void) setUserDefaultsFromDictionary: (NSDictionary *) theDictionary
|
||||
{
|
||||
if (!userDefaults)
|
||||
userDefaults = [[SOGoUserDefaults alloc] initWithTableURL: SOGoProfileURL
|
||||
uid: login
|
||||
fieldName: @"c_defaults"];
|
||||
[userDefaults setValues: theDictionary];
|
||||
}
|
||||
|
||||
- (NSUserDefaults *) userDefaults
|
||||
{
|
||||
@@ -493,6 +501,15 @@ _timeValue (NSString *key)
|
||||
return userDefaults;
|
||||
}
|
||||
|
||||
- (void) setUserSettingsFromDictionary: (NSDictionary *) theDictionary
|
||||
{
|
||||
if (!userSettings)
|
||||
userSettings = [[SOGoUserDefaults alloc] initWithTableURL: SOGoProfileURL
|
||||
uid: login
|
||||
fieldName: @"c_settings"];
|
||||
[userSettings setValues: theDictionary];
|
||||
}
|
||||
|
||||
- (NSUserDefaults *) userSettings
|
||||
{
|
||||
if (!userSettings)
|
||||
|
||||
@@ -36,12 +36,9 @@
|
||||
|
||||
@interface SOGoUserDefaults : NSObject
|
||||
{
|
||||
NSUserDefaults *parent;
|
||||
NSURL *url;
|
||||
NSString *uid;
|
||||
NSString *fieldName;
|
||||
|
||||
NSArray *fieldNames;
|
||||
NSMutableDictionary *values;
|
||||
NSCalendarDate *lastFetch;
|
||||
|
||||
@@ -58,6 +55,7 @@
|
||||
fieldName: (NSString *) fieldName;
|
||||
|
||||
/* value access */
|
||||
- (void) setValues: (NSDictionary *) theValues;
|
||||
|
||||
- (void) setObject: (id) value
|
||||
forKey: (NSString *) key;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSDistributedNotificationCenter.h>
|
||||
#import <Foundation/NSPropertyList.h>
|
||||
#import <Foundation/NSUserDefaults.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
@@ -50,7 +51,6 @@ static NSString *uidColumnName = @"c_uid";
|
||||
if (tableURL && [userID length] > 0
|
||||
&& [defaultsFieldName length] > 0)
|
||||
{
|
||||
parent = [[NSUserDefaults standardUserDefaults] retain];
|
||||
fieldName = [defaultsFieldName copy];
|
||||
url = [tableURL copy];
|
||||
uid = [userID copy];
|
||||
@@ -77,7 +77,6 @@ static NSString *uidColumnName = @"c_uid";
|
||||
{
|
||||
[values release];
|
||||
[lastFetch release];
|
||||
[parent release];
|
||||
[url release];
|
||||
[uid release];
|
||||
[fieldName release];
|
||||
@@ -101,11 +100,6 @@ static NSString *uidColumnName = @"c_uid";
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
- (NSUserDefaults *) parentDefaults
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
/* operation */
|
||||
|
||||
- (BOOL) primaryFetchProfile
|
||||
@@ -275,6 +269,18 @@ static NSString *uidColumnName = @"c_uid";
|
||||
[self errorWithFormat: @"could not run SQL '%@': %@", sql, ex];
|
||||
else
|
||||
{
|
||||
NSMutableDictionary *d;
|
||||
|
||||
d = [[NSMutableDictionary alloc] init];
|
||||
[d addEntriesFromDictionary: values];
|
||||
[d setObject: uid forKey: @"uid"];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
postNotificationName: ([fieldName isEqualToString: @"c_defaults"] ? @"SOGoUserDefaultsHaveChanged" : @"SOGoUserSettingsHaveChanged")
|
||||
object: nil
|
||||
userInfo: d];
|
||||
[d release];
|
||||
|
||||
if ([[channel adaptorContext] hasOpenTransaction])
|
||||
{
|
||||
ex = [channel evaluateExpressionX: @"COMMIT TRANSACTION"];
|
||||
@@ -315,6 +321,11 @@ static NSString *uidColumnName = @"c_uid";
|
||||
}
|
||||
|
||||
/* value access */
|
||||
- (void) setValues: (NSDictionary *) theValues
|
||||
{
|
||||
[values removeAllObjects];
|
||||
[values addEntriesFromDictionary: theValues];
|
||||
}
|
||||
|
||||
- (void) setObject: (id) value
|
||||
forKey: (NSString *) key
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#import "LDAPUserManager.h"
|
||||
#import "SOGoPermissions.h"
|
||||
#import "SOGoUser.h"
|
||||
#import "SOGoUserManager.h"
|
||||
|
||||
#import "SOGoUserFolder.h"
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/* SOGoUserManager.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2008 Inverse inc.
|
||||
*
|
||||
* Author: Ludovic Marcotte <lmarcotte@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 SOGOUSERMANAGER_H
|
||||
#define SOGOUSERMANAGER_H
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
|
||||
@class NSArray;
|
||||
@class NSMutableDictionary;
|
||||
@class NSString;
|
||||
@class NSTimer;
|
||||
@class SOGoUser;
|
||||
|
||||
@interface SOGoUserManager : NSObject
|
||||
{
|
||||
@private
|
||||
NSMutableDictionary *_cache;
|
||||
NSTimer *_cleanupTimer;
|
||||
}
|
||||
|
||||
+ (id) sharedManager;
|
||||
- (SOGoUser *) userWithLogin: (NSString *) theLogin
|
||||
roles: (NSArray *) theRoles;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,189 @@
|
||||
/* SOGoUserManager.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2008 Inverse inc.
|
||||
*
|
||||
* Author: Ludovic Marcotte <lmarcotte@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.
|
||||
*/
|
||||
|
||||
#include "SOGoUserManager.h"
|
||||
|
||||
#include <Foundation/NSDictionary.h>
|
||||
#include <Foundation/NSDistributedNotificationCenter.h>
|
||||
#include <Foundation/NSEnumerator.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSTimer.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#include "SOGoUser.h"
|
||||
|
||||
// We define the default value for cleaning up cached
|
||||
// users' preferences. This value should be relatively high
|
||||
// to avoid useless database calls.
|
||||
static NSTimeInterval cleanupInterval = 1800;
|
||||
|
||||
@implementation SOGoUserManager
|
||||
|
||||
- (id) init
|
||||
{
|
||||
NSString *cleanupSetting;
|
||||
|
||||
if ((self = [super init]))
|
||||
{
|
||||
_cache = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
|
||||
// We register ourself for notifications
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(_userDefaultsHaveChanged:)
|
||||
name: @"SOGoUserDefaultsHaveChanged"
|
||||
object: nil];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(_userSettingsHaveChanged:)
|
||||
name: @"SOGoUserSettingsHaveChanged"
|
||||
object: nil];
|
||||
|
||||
// We fire our timer that will cleanup cache entries
|
||||
cleanupSetting = [[NSUserDefaults standardUserDefaults]
|
||||
objectForKey: @"SOGoUserManagerCleanupInterval"];
|
||||
|
||||
if (cleanupSetting && [cleanupSetting doubleValue] > 0.0)
|
||||
cleanupInterval = [cleanupSetting doubleValue];
|
||||
|
||||
_cleanupTimer = [NSTimer scheduledTimerWithTimeInterval: cleanupInterval
|
||||
target: self
|
||||
selector: @selector(_cleanupSources)
|
||||
userInfo: nil
|
||||
repeats: YES];
|
||||
[self logWithFormat: @"cleanup interval set every %f seconds",
|
||||
cleanupInterval];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[_cache release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
+ (id) sharedManager
|
||||
{
|
||||
static id sharedManager = nil;
|
||||
|
||||
if (!sharedManager)
|
||||
sharedManager = [self new];
|
||||
|
||||
return sharedManager;
|
||||
}
|
||||
|
||||
- (SOGoUser *) userWithLogin: (NSString *) theLogin
|
||||
roles: (NSArray *) theRoles
|
||||
{
|
||||
NSDate *cleanupDate;
|
||||
SOGoUser *user;
|
||||
id entry;
|
||||
|
||||
cleanupDate = [[NSDate date] addTimeInterval: cleanupInterval];
|
||||
entry = [_cache objectForKey: theLogin];
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
user = [SOGoUser userWithLogin: theLogin roles: theRoles];
|
||||
|
||||
entry = [NSMutableDictionary dictionaryWithObjectsAndKeys: user, @"user", cleanupDate, @"cleanupDate", nil];
|
||||
[_cache setObject: entry forKey: theLogin];
|
||||
}
|
||||
else
|
||||
{
|
||||
[entry setObject: cleanupDate forKey: @"cleanupDate"];
|
||||
user = [entry objectForKey: @"user"];
|
||||
}
|
||||
|
||||
[user setPrimaryRoles: theRoles];
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
//
|
||||
// Private stuff
|
||||
//
|
||||
- (void) _userDefaultsHaveChanged: (NSNotification *) theNotification
|
||||
{
|
||||
NSMutableDictionary *d;
|
||||
SOGoUser *user;
|
||||
|
||||
d = [[NSMutableDictionary alloc] init];
|
||||
[d addEntriesFromDictionary: [theNotification userInfo]];
|
||||
|
||||
user = [self userWithLogin: [d objectForKey: @"uid"]
|
||||
roles: nil];
|
||||
|
||||
[d removeObjectForKey: @"uid"];
|
||||
[user setUserDefaultsFromDictionary: d];
|
||||
[d release];
|
||||
}
|
||||
|
||||
- (void) _userSettingsHaveChanged: (NSNotification *) theNotification
|
||||
{
|
||||
NSMutableDictionary *d;
|
||||
SOGoUser *user;
|
||||
|
||||
d = [[NSMutableDictionary alloc] init];
|
||||
[d addEntriesFromDictionary: [theNotification userInfo]];
|
||||
|
||||
user = [self userWithLogin: [d objectForKey: @"uid"]
|
||||
roles: nil];
|
||||
|
||||
[d removeObjectForKey: @"uid"];
|
||||
[user setUserSettingsFromDictionary: d];
|
||||
[d release];
|
||||
}
|
||||
|
||||
- (void) _cleanupSources
|
||||
{
|
||||
NSEnumerator *userIDs;
|
||||
NSString *currentID;
|
||||
NSDictionary *currentUser;
|
||||
NSDate *now;
|
||||
unsigned int count;
|
||||
|
||||
now = [NSDate date];
|
||||
count = 0;
|
||||
userIDs = [[_cache allKeys] objectEnumerator];
|
||||
|
||||
while ((currentID = [userIDs nextObject]))
|
||||
{
|
||||
currentUser = [_cache objectForKey: currentID];
|
||||
if ([now earlierDate:
|
||||
[currentUser objectForKey: @"cleanupDate"]] == now)
|
||||
{
|
||||
[_cache removeObjectForKey: currentID];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count)
|
||||
[self logWithFormat: @"cleaned %d users records from cache", count];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -40,6 +40,7 @@
|
||||
#import "LDAPUserManager.h"
|
||||
#import "SOGoPermissions.h"
|
||||
#import "SOGoUser.h"
|
||||
#import "SOGoUserManager.h"
|
||||
|
||||
#import "SOGoWebAuthenticator.h"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* UIxComponentEditor.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006 Inverse inc.
|
||||
* Copyright (C) 2006-2008 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
@@ -41,8 +41,8 @@
|
||||
|
||||
NSString *saveURL;
|
||||
NSMutableArray *calendarList;
|
||||
NSMutableArray *organizerList;
|
||||
NSDictionary *organizerIdentity;
|
||||
//NSMutableArray *organizerList;
|
||||
//NSDictionary *organizerIdentity;
|
||||
|
||||
/* individual values */
|
||||
NSCalendarDate *cycleUntilDate;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* UIxComponentEditor.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006 Inverse inc.
|
||||
* Copyright (C) 2006-2008 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
@@ -81,7 +81,7 @@ iRANGE(2);
|
||||
|
||||
#define REPEAT(X) \
|
||||
- (NSString *) repeat##X { return repeat##X; } \
|
||||
- (void) setRepeat##X: (NSString *) theValue { NSLog(@"setRepeat%d %@", X, theValue); ASSIGN(repeat##X, theValue); } \
|
||||
- (void) setRepeat##X: (NSString *) theValue { ASSIGN(repeat##X, theValue); } \
|
||||
|
||||
#define RANGE(X) \
|
||||
- (NSString *) range##X { return range##X; } \
|
||||
@@ -98,7 +98,7 @@ iRANGE(2);
|
||||
[self setIsCycleEndNever];
|
||||
componentOwner = @"";
|
||||
organizer = nil;
|
||||
organizerIdentity = nil;
|
||||
//organizerIdentity = nil;
|
||||
attendeesNames = nil;
|
||||
attendeesUIDs = nil;
|
||||
attendeesEmails = nil;
|
||||
@@ -128,7 +128,7 @@ iRANGE(2);
|
||||
[title release];
|
||||
[location release];
|
||||
[organizer release];
|
||||
[organizerIdentity release];
|
||||
//[organizerIdentity release];
|
||||
[comment release];
|
||||
[priority release];
|
||||
[categories release];
|
||||
@@ -460,75 +460,101 @@ iRANGE(2);
|
||||
return [organizer mailAddress];
|
||||
}
|
||||
|
||||
- (BOOL) canBeOrganizer
|
||||
{
|
||||
NSString *owner;
|
||||
SOGoObject <SOGoComponentOccurence> *co;
|
||||
SOGoUser *currentUser;
|
||||
BOOL hasOrganizer;
|
||||
SoSecurityManager *sm;
|
||||
// - (BOOL) canBeOrganizer
|
||||
// {
|
||||
// NSString *owner;
|
||||
// SOGoObject <SOGoComponentOccurence> *co;
|
||||
// SOGoUser *currentUser;
|
||||
// BOOL hasOrganizer;
|
||||
// SoSecurityManager *sm;
|
||||
|
||||
co = [self clientObject];
|
||||
owner = [co ownerInContext: context];
|
||||
currentUser = [context activeUser];
|
||||
// co = [self clientObject];
|
||||
// owner = [co ownerInContext: context];
|
||||
// currentUser = [context activeUser];
|
||||
|
||||
hasOrganizer = ([[organizer value: 0] length] > 0);
|
||||
// hasOrganizer = ([[organizer value: 0] length] > 0);
|
||||
|
||||
sm = [SoSecurityManager sharedSecurityManager];
|
||||
// sm = [SoSecurityManager sharedSecurityManager];
|
||||
|
||||
return ([co isNew]
|
||||
|| (([owner isEqualToString: [currentUser login]]
|
||||
|| ![sm validatePermission: SOGoCalendarPerm_ModifyComponent
|
||||
onObject: co
|
||||
inContext: context])
|
||||
&& (!hasOrganizer || [component userIsOrganizer: currentUser])));
|
||||
}
|
||||
// return ([co isNew]
|
||||
// || (([owner isEqualToString: [currentUser login]]
|
||||
// || ![sm validatePermission: SOGoCalendarPerm_ModifyComponent
|
||||
// onObject: co
|
||||
// inContext: context])
|
||||
// && (!hasOrganizer || [component userIsOrganizer: currentUser])));
|
||||
// }
|
||||
|
||||
- (BOOL) hasOrganizer
|
||||
{
|
||||
return ([[organizer value: 0] length] && ![self canBeOrganizer]);
|
||||
}
|
||||
// We check if there's an organizer and if it's not ourself
|
||||
NSString *value;
|
||||
|
||||
- (void) setOrganizerIdentity: (NSDictionary *) newOrganizerIdentity
|
||||
{
|
||||
ASSIGN (organizerIdentity, newOrganizerIdentity);
|
||||
}
|
||||
value = [organizer rfc822Email];
|
||||
|
||||
- (NSDictionary *) organizerIdentity
|
||||
{
|
||||
NSArray *allIdentities;
|
||||
NSEnumerator *identities;
|
||||
NSDictionary *currentIdentity;
|
||||
NSString *orgEmail;
|
||||
|
||||
orgEmail = [organizer rfc822Email];
|
||||
if (!organizerIdentity)
|
||||
if ([value length])
|
||||
{
|
||||
if ([orgEmail length])
|
||||
{
|
||||
allIdentities = [[context activeUser] allIdentities];
|
||||
identities = [allIdentities objectEnumerator];
|
||||
while (!organizerIdentity
|
||||
&& ((currentIdentity = [identities nextObject])))
|
||||
if ([[currentIdentity objectForKey: @"email"]
|
||||
caseInsensitiveCompare: orgEmail]
|
||||
== NSOrderedSame)
|
||||
ASSIGN (organizerIdentity, currentIdentity);
|
||||
}
|
||||
NSDictionary *currentIdentity;
|
||||
NSEnumerator *identities;
|
||||
NSArray *allIdentities;
|
||||
|
||||
allIdentities = [[context activeUser] allIdentities];
|
||||
identities = [allIdentities objectEnumerator];
|
||||
currentIdentity = nil;
|
||||
|
||||
while ((currentIdentity = [identities nextObject]))
|
||||
if ([[currentIdentity objectForKey: @"email"]
|
||||
caseInsensitiveCompare: value]
|
||||
== NSOrderedSame)
|
||||
return NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
return organizerIdentity;
|
||||
return NO;
|
||||
|
||||
//return ([[organizer value: 0] length] && ![self canBeOrganizer]);
|
||||
}
|
||||
|
||||
- (NSArray *) organizerList
|
||||
{
|
||||
return [[context activeUser] allIdentities];
|
||||
}
|
||||
//- (void) setOrganizerIdentity: (NSDictionary *) newOrganizerIdentity
|
||||
//{
|
||||
// ASSIGN (organizerIdentity, newOrganizerIdentity);
|
||||
//}
|
||||
|
||||
- (NSString *) itemOrganizerText
|
||||
{
|
||||
return [item keysWithFormat: @"%{fullName} <%{email}>"];
|
||||
}
|
||||
// - (NSDictionary *) organizerIdentity
|
||||
// {
|
||||
// NSArray *allIdentities;
|
||||
// NSEnumerator *identities;
|
||||
// NSDictionary *currentIdentity;
|
||||
// NSString *orgEmail;
|
||||
|
||||
// orgEmail = [organizer rfc822Email];
|
||||
// if (!organizerIdentity)
|
||||
// {
|
||||
// if ([orgEmail length])
|
||||
// {
|
||||
// allIdentities = [[context activeUser] allIdentities];
|
||||
// identities = [allIdentities objectEnumerator];
|
||||
// while (!organizerIdentity
|
||||
// && ((currentIdentity = [identities nextObject])))
|
||||
// if ([[currentIdentity objectForKey: @"email"]
|
||||
// caseInsensitiveCompare: orgEmail]
|
||||
// == NSOrderedSame)
|
||||
// ASSIGN (organizerIdentity, currentIdentity);
|
||||
// }
|
||||
// }
|
||||
|
||||
// return organizerIdentity;
|
||||
// }
|
||||
|
||||
//- (NSArray *) organizerList
|
||||
//{
|
||||
// return [[context activeUser] allIdentities];
|
||||
//}
|
||||
|
||||
//- (NSString *) itemOrganizerText
|
||||
//{
|
||||
// return [item keysWithFormat: @"%{fullName} <%{email}>"];
|
||||
//}
|
||||
|
||||
- (void) setAttendeesNames: (NSString *) newAttendeesNames
|
||||
{
|
||||
@@ -833,7 +859,7 @@ iRANGE(2);
|
||||
|
||||
- (void) setComponentCalendar: (SOGoAppointmentFolder *) _componentCalendar
|
||||
{
|
||||
ASSIGN (componentCalendar, _componentCalendar);
|
||||
ASSIGN(componentCalendar, _componentCalendar);
|
||||
}
|
||||
|
||||
/* priorities */
|
||||
@@ -1286,13 +1312,38 @@ RANGE(2);
|
||||
NSString *owner, *login;
|
||||
BOOL isOwner, hasOrganizer, hasAttendees;
|
||||
|
||||
owner = [[self clientObject] ownerInContext: context];
|
||||
//owner = [[self clientObject] ownerInContext: context];
|
||||
owner = [componentCalendar ownerInContext: context];
|
||||
login = [[context activeUser] login];
|
||||
isOwner = [owner isEqualToString: login];
|
||||
hasAttendees = ([[component attendees] count] > 0);
|
||||
organizerEmail = [[component organizer] email];
|
||||
hasOrganizer = ([organizerEmail length] > 0);
|
||||
|
||||
#if 1
|
||||
ASSIGN (organizer, [iCalPerson elementWithTag: @"organizer"]);
|
||||
[component setOrganizer: organizer];
|
||||
|
||||
if (hasAttendees)
|
||||
{
|
||||
SOGoUser *user;
|
||||
id identity;
|
||||
|
||||
user = [SOGoUser userWithLogin: owner roles: nil];
|
||||
identity = [user defaultIdentity];
|
||||
[organizer setCn: [identity objectForKey: @"fullName"]];
|
||||
[organizer setEmail: [identity objectForKey: @"email"]];
|
||||
|
||||
if (!isOwner)
|
||||
{
|
||||
NSString *currentEmail;
|
||||
|
||||
currentEmail = [[[context activeUser] allEmails] objectAtIndex: 0];
|
||||
[organizer addAttribute: @"SENT-BY"
|
||||
value: [NSString stringWithFormat: @"\"MAILTO:%@\"", currentEmail]];
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (hasOrganizer)
|
||||
{
|
||||
if (isOwner && !hasAttendees)
|
||||
@@ -1311,6 +1362,7 @@ RANGE(2);
|
||||
[component setOrganizer: organizer];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void) _handleCustomRRule: (iCalRecurrenceRule *) theRule
|
||||
|
||||
@@ -61,12 +61,12 @@
|
||||
/><span class="content"><var:string
|
||||
value="organizerName"/></span></label>
|
||||
</var:if>
|
||||
<var:if condition="canBeOrganizer"
|
||||
<!--<var:if condition="canBeOrganizer"
|
||||
><label id="organizerListLabel"><var:string label:value="Organizer:"
|
||||
/><span class="content"><var:popup list="organizerList"
|
||||
item="item" string="itemOrganizerText"
|
||||
var:selection="organizerIdentity"/>
|
||||
</span></label></var:if>
|
||||
</span></label></var:if>-->
|
||||
<label id="attendeesLabel"><var:string label:value="Attendees:"
|
||||
/><span class="content"
|
||||
><a href="#" id="attendeesHref"><!-- space --></a></span></label>
|
||||
|
||||
Reference in New Issue
Block a user